add jsonapi pagination to polling and missing documentation
fixes CNVS-13534 This commit adds 2 things. One is that, when it's requested via the 'Accept' request header with a value of 'application/vnd.api+json', it will return jsonapi standard pagination. The other is the addition of of documentation for the 'results' attribute on poll sessions, and the 'total_results' attribute on polls. Test plan 1. jsonapi pagination - As a teacher, and using a header of Accept: application/vnd.api+json Test the following endpoints: - The polls index endpoint - The poll_choices index endpoint - The poll_sessions index endpoint - The poll_sessions opened endpoint - The poll_sessions closed endpoint - Each of these endpoints should return the same JSON response, but with the addition of a 'meta' attribute that has a 'pagination' key, with pagination information. 2. documentation - The documentation for polls should now include a 'total_results' attribute, and the documentation for poll_sessions should include a 'results' attribute. Change-Id: I2a16b4d32b3b2a4f2023628b24f9accaecbffcc1 Reviewed-on: https://gerrit.instructure.com/36216 Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Caleb Guanzon <cguanzon@instructure.com> Reviewed-by: Derek DeVries <ddevries@instructure.com> Product-Review: Josh Simpson <jsimpson@instructure.com>
This commit is contained in:
parent
7434644311
commit
2f594ea5e3
|
@ -72,9 +72,9 @@ module Polling
|
|||
def index
|
||||
if authorized_action(@poll, @current_user, :read)
|
||||
@poll_choices = @poll.poll_choices
|
||||
@poll_choices = Api.paginate(@poll_choices, self, api_v1_poll_choices_url(@poll))
|
||||
json, meta = paginate_for(@poll_choices)
|
||||
|
||||
render json: serialize_jsonapi(@poll_choices)
|
||||
render json: serialize_jsonapi(json, meta)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -178,18 +178,30 @@ module Polling
|
|||
end
|
||||
|
||||
protected
|
||||
def serialize_jsonapi(poll_choices)
|
||||
def paginate_for(poll_choices)
|
||||
meta = {}
|
||||
json = if accepts_jsonapi?
|
||||
poll_choices, meta = Api.jsonapi_paginate(poll_choices, self, api_v1_poll_choices_url(@poll))
|
||||
meta[:primaryCollection] = 'poll_choices'
|
||||
poll_choices
|
||||
else
|
||||
Api.paginate(poll_choices, self, api_v1_poll_choices_url(@poll))
|
||||
end
|
||||
|
||||
return json, meta
|
||||
end
|
||||
|
||||
def serialize_jsonapi(poll_choices, meta = {})
|
||||
poll_choices = Array.wrap(poll_choices)
|
||||
|
||||
serialized_set = Canvas::APIArraySerializer.new(poll_choices, {
|
||||
Canvas::APIArraySerializer.new(poll_choices, {
|
||||
each_serializer: Polling::PollChoiceSerializer,
|
||||
controller: self,
|
||||
root: false,
|
||||
root: :poll_choices,
|
||||
meta: meta,
|
||||
scope: @current_user,
|
||||
include_root: false
|
||||
}).as_json
|
||||
|
||||
{ poll_choices: serialized_set }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -60,6 +60,11 @@ module Polling
|
|||
# "example": "2014-01-07T15:16:18Z",
|
||||
# "type": "string",
|
||||
# "format": "date-time"
|
||||
# },
|
||||
# "results": {
|
||||
# "description": "The results of the submissions of the poll. Each key is the poll choice id, and the value is the count of submissions.",
|
||||
# "example": { "144": 10, "145": 3, "146": 27, "147": 8 },
|
||||
# "type": "object"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
@ -83,9 +88,9 @@ module Polling
|
|||
def index
|
||||
if authorized_action(@poll, @current_user, :update)
|
||||
@poll_sessions = @poll.poll_sessions
|
||||
@poll_sessions = Api.paginate(@poll_sessions, self, api_v1_poll_sessions_url(@poll))
|
||||
json, meta = paginate_for(@poll_sessions, api_v1_poll_sessions_url(@poll))
|
||||
|
||||
render json: serialize_jsonapi(@poll_sessions)
|
||||
render json: serialize_jsonapi(json, meta)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -243,7 +248,8 @@ module Polling
|
|||
#
|
||||
def opened
|
||||
@poll_sessions = Polling::PollSession.available_for(@current_user).where(is_published: true)
|
||||
render json: serialize_jsonapi(@poll_sessions)
|
||||
json, meta = paginate_for(@poll_sessions, api_v1_poll_sessions_opened_url)
|
||||
render json: serialize_jsonapi(json, meta)
|
||||
end
|
||||
|
||||
# @API List closed poll sessions
|
||||
|
@ -258,22 +264,36 @@ module Polling
|
|||
#
|
||||
def closed
|
||||
@poll_sessions = Polling::PollSession.available_for(@current_user).where(is_published: false)
|
||||
render json: serialize_jsonapi(@poll_sessions)
|
||||
json, meta = paginate_for(@poll_sessions, api_v1_poll_sessions_closed_url)
|
||||
render json: serialize_jsonapi(json, meta)
|
||||
end
|
||||
|
||||
protected
|
||||
def serialize_jsonapi(poll_sessions)
|
||||
def paginate_for(poll_sessions, api_url="")
|
||||
meta = {}
|
||||
json = if accepts_jsonapi?
|
||||
poll_sessions, meta = Api.jsonapi_paginate(poll_sessions, self, api_url)
|
||||
meta[:primaryCollection] = 'poll_sessions'
|
||||
poll_sessions
|
||||
else
|
||||
Api.paginate(poll_sessions, self, api_url)
|
||||
end
|
||||
|
||||
return json, meta
|
||||
end
|
||||
|
||||
|
||||
def serialize_jsonapi(poll_sessions, meta = {})
|
||||
poll_sessions = Array.wrap(poll_sessions)
|
||||
|
||||
serialized_set = Canvas::APIArraySerializer.new(poll_sessions, {
|
||||
Canvas::APIArraySerializer.new(poll_sessions, {
|
||||
each_serializer: Polling::PollSessionSerializer,
|
||||
controller: self,
|
||||
root: false,
|
||||
root: :poll_sessions,
|
||||
meta: meta,
|
||||
scope: @current_user,
|
||||
include_root: false
|
||||
}).as_json
|
||||
|
||||
{ poll_sessions: serialized_set }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -108,15 +108,14 @@ module Polling
|
|||
def serialize_jsonapi(poll_submissions)
|
||||
poll_submissions = Array.wrap(poll_submissions)
|
||||
|
||||
serialized_set = Canvas::APIArraySerializer.new(poll_submissions, {
|
||||
Canvas::APIArraySerializer.new(poll_submissions, {
|
||||
each_serializer: Polling::PollSubmissionSerializer,
|
||||
controller: self,
|
||||
root: false,
|
||||
root: :poll_submissions,
|
||||
meta: {},
|
||||
scope: @current_user,
|
||||
include_root: false
|
||||
}).as_json
|
||||
|
||||
{ poll_submissions: serialized_set }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -50,6 +50,11 @@ module Polling
|
|||
# "description": "The unique identifier for the user that created the poll.",
|
||||
# "example": 105,
|
||||
# "type": "integer"
|
||||
# },
|
||||
# "total_results": {
|
||||
# "description": "An aggregate of the results of all associated poll sessions, with the poll choice id as the key, and the aggregated submission count as the value.",
|
||||
# "example": { "543": 20, "544": 5, "545": 17 },
|
||||
# "type": "object"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
@ -71,9 +76,9 @@ module Polling
|
|||
#
|
||||
def index
|
||||
@polls = @current_user.polls.order('created_at DESC')
|
||||
@polls = Api.paginate(@polls, self, api_v1_polls_url)
|
||||
json, meta = paginate_for(@polls)
|
||||
|
||||
render json: serialize_jsonapi(@polls)
|
||||
render json: serialize_jsonapi(json, meta)
|
||||
end
|
||||
|
||||
# @API Get a single poll
|
||||
|
@ -166,18 +171,30 @@ module Polling
|
|||
end
|
||||
|
||||
protected
|
||||
def serialize_jsonapi(polls)
|
||||
def paginate_for(polls)
|
||||
meta = {}
|
||||
json = if accepts_jsonapi?
|
||||
polls, meta = Api.jsonapi_paginate(polls, self, api_v1_polls_url)
|
||||
meta[:primaryCollection] = 'polls'
|
||||
polls
|
||||
else
|
||||
Api.paginate(polls, self, api_v1_polls_url)
|
||||
end
|
||||
|
||||
return json, meta
|
||||
end
|
||||
|
||||
def serialize_jsonapi(polls, meta = {})
|
||||
polls = Array.wrap(polls)
|
||||
|
||||
serialized_set = Canvas::APIArraySerializer.new(polls, {
|
||||
Canvas::APIArraySerializer.new(polls, {
|
||||
each_serializer: Polling::PollSerializer,
|
||||
controller: self,
|
||||
root: false,
|
||||
root: :polls,
|
||||
meta: meta,
|
||||
scope: @current_user,
|
||||
include_root: false
|
||||
}).as_json
|
||||
|
||||
{ polls: serialized_set }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -33,13 +33,13 @@ describe Polling::PollChoicesController, type: :request do
|
|||
@poll.poll_choices.create!(text: "Poll Choice 5", is_correct:false, position: 5)
|
||||
end
|
||||
|
||||
def get_index(raw = false, data = {})
|
||||
def get_index(raw = false, data = {}, headers = {})
|
||||
helper = method(raw ? :raw_api_call : :api_call)
|
||||
helper.call(:get,
|
||||
"/api/v1/polls/#{@poll.id}/poll_choices",
|
||||
{ controller: 'polling/poll_choices', action: 'index', format: 'json',
|
||||
poll_id: @poll.id.to_s
|
||||
}, data)
|
||||
}, data, headers)
|
||||
end
|
||||
|
||||
it "returns all existing poll choices" do
|
||||
|
@ -62,6 +62,20 @@ describe Polling::PollChoicesController, type: :request do
|
|||
end
|
||||
|
||||
|
||||
it "paginates to the jsonapi standard if requested" do
|
||||
json = get_index(false, {}, 'Accept' => 'application/vnd.api+json')
|
||||
poll_choices_json = json['poll_choices']
|
||||
poll_choices_json.size.should == 5
|
||||
|
||||
poll_choices_json.each_with_index do |pc, i|
|
||||
pc['text'].should == "Poll Choice #{5-i}"
|
||||
end
|
||||
|
||||
json.should have_key('meta')
|
||||
json['meta'].should have_key('pagination')
|
||||
json['meta']['primaryCollection'].should == 'poll_choices'
|
||||
end
|
||||
|
||||
context "as a student" do
|
||||
before(:each) do
|
||||
student_in_course(:active_all => true, :course => @course)
|
||||
|
|
|
@ -32,19 +32,19 @@ describe Polling::PollSessionsController, type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
def get_index(raw = false, data = {})
|
||||
def get_index(raw = false, data = {}, header = {})
|
||||
helper = method(raw ? :raw_api_call : :api_call)
|
||||
helper.call(:get,
|
||||
"/api/v1/polls/#{@poll.id}/poll_sessions",
|
||||
{ controller: 'polling/poll_sessions', action: 'index', format: 'json',
|
||||
poll_id: @poll.id.to_s
|
||||
}, data)
|
||||
}, data, header)
|
||||
end
|
||||
|
||||
it "returns all existing poll sessions" do
|
||||
json = get_index
|
||||
poll_sessions_json = json['poll_sessions']
|
||||
session_ids = @poll.poll_sessions.map(&:id)
|
||||
session_ids = @poll.poll_sessions.pluck(:id)
|
||||
poll_sessions_json.size.should == 3
|
||||
|
||||
poll_sessions_json.each_with_index do |session, i|
|
||||
|
@ -52,6 +52,23 @@ describe Polling::PollSessionsController, type: :request do
|
|||
session['is_published'].should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "paginates to the jsonapi standard if requested" do
|
||||
json = get_index(false, {}, 'Accept' => 'application/vnd.api+json')
|
||||
poll_sessions_json = json['poll_sessions']
|
||||
session_ids = @poll.poll_sessions.pluck(:id)
|
||||
|
||||
poll_sessions_json.size.should == 3
|
||||
|
||||
poll_sessions_json.each_with_index do |session, i|
|
||||
session_ids.should include(session['id'].to_i)
|
||||
session['is_published'].should be_false
|
||||
end
|
||||
|
||||
json.should have_key('meta')
|
||||
json['meta'].should have_key('pagination')
|
||||
json['meta']['primaryCollection'].should == 'poll_sessions'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET show' do
|
||||
|
@ -437,11 +454,11 @@ describe Polling::PollSessionsController, type: :request do
|
|||
@poll2 = Polling::Poll.create!(user: @teacher2, question: 'Another Test Poll')
|
||||
end
|
||||
|
||||
def get_opened
|
||||
def get_opened(headers = {})
|
||||
api_call(:get,
|
||||
"/api/v1/poll_sessions/opened",
|
||||
{ controller: 'polling/poll_sessions', action: 'opened', format: 'json' },
|
||||
{}, {}, {})
|
||||
{}, headers)
|
||||
end
|
||||
|
||||
it "returns all poll sessions available to the current user that are published" do
|
||||
|
@ -475,6 +492,27 @@ describe Polling::PollSessionsController, type: :request do
|
|||
session_ids.should include(@published.id)
|
||||
session_ids.should_not include(@wrong_course_section.id)
|
||||
end
|
||||
|
||||
it "paginates to the jsonapi standard if requested" do
|
||||
@published = @poll1.poll_sessions.create!(course: @course1)
|
||||
@published.publish!
|
||||
@unenrolled = @poll2.poll_sessions.create!(course: @course2)
|
||||
@unenrolled.publish!
|
||||
@not_published = @poll1.poll_sessions.create!(course: @course1)
|
||||
|
||||
student_in_course(active_all: true, course: @course1)
|
||||
json = get_opened('Accept' => 'application/vnd.api+json')
|
||||
sessions = json['poll_sessions']
|
||||
session_ids = sessions.map { |session| session["id"].to_i }
|
||||
|
||||
session_ids.should include(@published.id)
|
||||
session_ids.should_not include(@unenrolled.id)
|
||||
session_ids.should_not include(@not_published.id)
|
||||
|
||||
json.should have_key('meta')
|
||||
json['meta'].should have_key('pagination')
|
||||
json['meta']['primaryCollection'].should == 'poll_sessions'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET closed' do
|
||||
|
@ -487,11 +525,11 @@ describe Polling::PollSessionsController, type: :request do
|
|||
@poll2 = Polling::Poll.create!(user: @teacher2, question: 'Another Test Poll')
|
||||
end
|
||||
|
||||
def get_closed
|
||||
def get_closed(headers = {})
|
||||
api_call(:get,
|
||||
"/api/v1/poll_sessions/closed",
|
||||
{ controller: 'polling/poll_sessions', action: 'closed', format: 'json' },
|
||||
{}, {}, {})
|
||||
{}, headers)
|
||||
end
|
||||
|
||||
it "returns all poll sessions available to the current user that are closed" do
|
||||
|
@ -526,6 +564,28 @@ describe Polling::PollSessionsController, type: :request do
|
|||
session_ids.should include(@not_published.id)
|
||||
session_ids.should_not include(@wrong_course_section.id)
|
||||
end
|
||||
end
|
||||
|
||||
it "paginates to the jsonapi standard if requested" do
|
||||
@published = @poll1.poll_sessions.create!(course: @course1)
|
||||
@published.publish!
|
||||
@unenrolled = @poll2.poll_sessions.create!(course: @course2)
|
||||
@unenrolled.close!
|
||||
@not_published = @poll1.poll_sessions.create!(course: @course1)
|
||||
@not_published.close!
|
||||
|
||||
student_in_course(active_all: true, course: @course1)
|
||||
json = get_closed('Accept' => 'application/vnd.api+json')
|
||||
|
||||
sessions = json['poll_sessions']
|
||||
session_ids = sessions.map { |session| session["id"].to_i }
|
||||
|
||||
session_ids.should include(@not_published.id)
|
||||
session_ids.should_not include(@unenrolled.id)
|
||||
session_ids.should_not include(@published.id)
|
||||
|
||||
json.should have_key('meta')
|
||||
json['meta'].should have_key('pagination')
|
||||
json['meta']['primaryCollection'].should == 'poll_sessions'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,12 +30,13 @@ describe Polling::PollsController, type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
def get_index(raw = false, data = {})
|
||||
def get_index(raw = false, data = {}, headers = {})
|
||||
helper = method(raw ? :raw_api_call : :api_call)
|
||||
helper.call(:get,
|
||||
"/api/v1/polls",
|
||||
{ controller: 'polling/polls', action: 'index', format: 'json' },
|
||||
data)
|
||||
data,
|
||||
headers)
|
||||
end
|
||||
|
||||
it "returns all existing polls" do
|
||||
|
@ -48,6 +49,20 @@ describe Polling::PollsController, type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
it "paginates to the jsonapi standard if requested" do
|
||||
json = get_index(false, {}, 'Accept' => 'application/vnd.api+json')
|
||||
poll_json = json['polls']
|
||||
poll_json.size.should == 5
|
||||
|
||||
poll_json.each_with_index do |poll, i|
|
||||
poll['question'].should == "Example Poll #{5-i}"
|
||||
end
|
||||
|
||||
json.should have_key('meta')
|
||||
json['meta'].should have_key('pagination')
|
||||
json['meta']['primaryCollection'].should == 'polls'
|
||||
end
|
||||
|
||||
context "as a site admin" do
|
||||
it "you can view polls you have created" do
|
||||
Account.site_admin.add_user(@teacher)
|
||||
|
@ -251,7 +266,5 @@ describe Polling::PollsController, type: :request do
|
|||
Polling::Poll.find_by_id(@poll.id).should == @poll
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue