embed poll submissions into poll session
fixes CNVS-13275, CNVS-13297 This commit embeds all submissions when a particular poll session is requested by authorized users (the creator/teacher of the poll and relevant poll session.). It also deletes all submissions and sessions that belong to a poll when that poll is deleted. Test plan Submission embedding - Create a poll and related poll session - Create multiple submissions for the poll as students - As a teacher, you should be able to see the related submissions when requesting the poll session via the API Poll session/submission deletion - Create a poll and two poll sessions, with two submissions per session - Delete the poll via the api, it should be deleted successfully Change-Id: I335f92eb97be095a2ddf6bc730954ed8a14220ef Reviewed-on: https://gerrit.instructure.com/35456 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Derek DeVries <ddevries@instructure.com> QA-Review: Caleb Guanzon <cguanzon@instructure.com> Product-Review: Josh Simpson <jsimpson@instructure.com>
This commit is contained in:
parent
c1b4b889fa
commit
a3a1205e2d
|
@ -26,14 +26,25 @@ module Polling
|
||||||
# "required": ["id", "poll_choice"],
|
# "required": ["id", "poll_choice"],
|
||||||
# "properties": {
|
# "properties": {
|
||||||
# "id": {
|
# "id": {
|
||||||
# "description": "The unique identifier for the account role/user assignment.",
|
# "description": "The unique identifier for the poll submission.",
|
||||||
# "example": 1023,
|
# "example": 1023,
|
||||||
# "type": "integer"
|
# "type": "integer"
|
||||||
# },
|
# },
|
||||||
# "poll_choice_id": {
|
# "poll_choice_id": {
|
||||||
# "description": "The id of the chosen poll choice for this submission.",
|
# "description": "The unique identifier of the poll choice chosen for this submission.",
|
||||||
# "example": 55,
|
# "example": 155,
|
||||||
# "type": "integer"
|
# "type": "integer"
|
||||||
|
# },
|
||||||
|
# "user_id": {
|
||||||
|
# "description": "the unique identifier of the user who submitted this poll submission.",
|
||||||
|
# "example": 4555,
|
||||||
|
# "type": "integer"
|
||||||
|
# },
|
||||||
|
# "created_at": {
|
||||||
|
# "description": "The date and time the poll submission was submitted.",
|
||||||
|
# "example": "2013-11-07T13:16:18Z",
|
||||||
|
# "type": "string",
|
||||||
|
# "format": "date-time"
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
|
|
@ -22,8 +22,8 @@ module Polling
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :poll_choices, class_name: 'Polling::PollChoice', dependent: :destroy
|
has_many :poll_choices, class_name: 'Polling::PollChoice', dependent: :destroy
|
||||||
has_many :poll_submissions, class_name: 'Polling::PollSubmission'
|
has_many :poll_submissions, class_name: 'Polling::PollSubmission', dependent: :destroy
|
||||||
has_many :poll_sessions, class_name: 'Polling::PollSession'
|
has_many :poll_sessions, class_name: 'Polling::PollSession', dependent: :destroy
|
||||||
|
|
||||||
validates_presence_of :question, :user
|
validates_presence_of :question, :user
|
||||||
validates_length_of :question, maximum: 255, allow_nil: true
|
validates_length_of :question, maximum: 255, allow_nil: true
|
||||||
|
|
|
@ -21,6 +21,7 @@ module Polling
|
||||||
attr_accessible :text, :poll, :is_correct
|
attr_accessible :text, :poll, :is_correct
|
||||||
|
|
||||||
belongs_to :poll, class_name: 'Polling::Poll'
|
belongs_to :poll, class_name: 'Polling::Poll'
|
||||||
|
has_many :poll_submissions, class_name: 'Polling::PollSubmission', dependent: :destroy
|
||||||
|
|
||||||
validates_presence_of :poll, :text
|
validates_presence_of :poll, :text
|
||||||
validates_length_of :text, maximum: 255, allow_nil: true
|
validates_length_of :text, maximum: 255, allow_nil: true
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
module Polling
|
module Polling
|
||||||
class PollSessionSerializer < Canvas::APISerializer
|
class PollSessionSerializer < Canvas::APISerializer
|
||||||
root :poll_session
|
attributes :id, :is_published, :has_public_results, :results, :course_id, :course_section_id, :created_at, :poll_id, :poll_submissions
|
||||||
|
|
||||||
attributes :id, :is_published, :has_public_results, :results, :course_id, :course_section_id, :created_at
|
|
||||||
|
|
||||||
def_delegators :object, :results, :poll
|
def_delegators :object, :results, :poll
|
||||||
|
|
||||||
|
# has_many relationships with embedded objects doesn't work, so we override it this way
|
||||||
|
def poll_submissions
|
||||||
|
@poll_submissions ||= object.poll_submissions.map do |submission|
|
||||||
|
Polling::PollSubmissionSerializer.new(submission, controller: @controller, scope: @scope, root: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def filter(keys)
|
def filter(keys)
|
||||||
if poll.grants_right?(current_user, session, :update) || object.has_public_results?
|
if poll.grants_right?(current_user, session, :update) || object.has_public_results?
|
||||||
student_keys + teacher_keys
|
student_keys + teacher_keys
|
||||||
|
@ -17,11 +22,11 @@ module Polling
|
||||||
private
|
private
|
||||||
|
|
||||||
def teacher_keys
|
def teacher_keys
|
||||||
[:has_public_results, :results]
|
[:has_public_results, :results, :poll_submissions]
|
||||||
end
|
end
|
||||||
|
|
||||||
def student_keys
|
def student_keys
|
||||||
[:id, :is_published, :course_id, :course_section_id, :created_at]
|
[:id, :is_published, :course_id, :course_section_id, :created_at, :poll_id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
module Polling
|
module Polling
|
||||||
class PollSubmissionSerializer < Canvas::APISerializer
|
class PollSubmissionSerializer < Canvas::APISerializer
|
||||||
root :poll_submission
|
root :poll_submission
|
||||||
|
attributes :id, :poll_session_id, :poll_choice_id, :user_id, :created_at
|
||||||
attributes :id, :poll_choice_id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -95,12 +95,29 @@ describe Polling::PollSessionsController, type: :request do
|
||||||
context "as a teacher" do
|
context "as a teacher" do
|
||||||
it "retrieves the poll session specified even if closed" do
|
it "retrieves the poll session specified even if closed" do
|
||||||
@poll_session.close!
|
@poll_session.close!
|
||||||
|
|
||||||
|
@user = @teacher
|
||||||
json = get_show
|
json = get_show
|
||||||
poll_json = json['poll_sessions'].first
|
poll_json = json['poll_sessions'].first
|
||||||
poll_json['id'].should == @poll_session.id.to_s
|
poll_json['id'].should == @poll_session.id.to_s
|
||||||
poll_json['is_published'].should be_false
|
poll_json['is_published'].should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "embeds the associated poll submissions" do
|
||||||
|
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
||||||
|
choice2 = @poll.poll_choices.create!(text: 'Choice B', is_correct: false)
|
||||||
|
|
||||||
|
2.times { create_submission(choice1) }
|
||||||
|
1.times { create_submission(choice2) }
|
||||||
|
|
||||||
|
@user = @teacher
|
||||||
|
json = get_show
|
||||||
|
poll_session_json = json['poll_sessions'].first
|
||||||
|
|
||||||
|
poll_session_json.should have_key('poll_submissions')
|
||||||
|
poll_session_json['poll_submissions'].size.should == 3
|
||||||
|
end
|
||||||
|
|
||||||
it "shows the results of a current poll session" do
|
it "shows the results of a current poll session" do
|
||||||
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
||||||
choice2 = @poll.poll_choices.create!(text: 'Choice B', is_correct: false)
|
choice2 = @poll.poll_choices.create!(text: 'Choice B', is_correct: false)
|
||||||
|
@ -119,6 +136,21 @@ describe Polling::PollSessionsController, type: :request do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as a student" do
|
context "as a student" do
|
||||||
|
it "doesn't embed the associated poll submissions" do
|
||||||
|
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
||||||
|
choice2 = @poll.poll_choices.create!(text: 'Choice B', is_correct: false)
|
||||||
|
|
||||||
|
2.times { create_submission(choice1) }
|
||||||
|
1.times { create_submission(choice2) }
|
||||||
|
|
||||||
|
student = student_in_course(active_user:true).user
|
||||||
|
@user = student
|
||||||
|
|
||||||
|
json = get_show
|
||||||
|
|
||||||
|
json.should_not have_key('poll_submissions')
|
||||||
|
end
|
||||||
|
|
||||||
context "when has_public_results is false" do
|
context "when has_public_results is false" do
|
||||||
it "doesn't show the results of a current poll session" do
|
it "doesn't show the results of a current poll session" do
|
||||||
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
choice1 = @poll.poll_choices.create!(text: 'Choice A', is_correct: true)
|
||||||
|
@ -342,6 +374,4 @@ describe Polling::PollSessionsController, type: :request do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -170,6 +170,16 @@ describe Polling::PollsController, type: :request do
|
||||||
describe 'DELETE destroy' do
|
describe 'DELETE destroy' do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@poll = @teacher.polls.create!(question: 'An Old Title')
|
@poll = @teacher.polls.create!(question: 'An Old Title')
|
||||||
|
@choice = @poll.poll_choices.create!(text: 'Blah')
|
||||||
|
@session = @poll.poll_sessions.create!(course: @course)
|
||||||
|
@session.publish!
|
||||||
|
|
||||||
|
@student = student_in_course(active_user: true).user
|
||||||
|
@submission = @session.poll_submissions.create!(
|
||||||
|
user: @student,
|
||||||
|
poll: @poll,
|
||||||
|
poll_choice: @choice
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_destroy
|
def delete_destroy
|
||||||
|
@ -183,6 +193,7 @@ describe Polling::PollsController, type: :request do
|
||||||
|
|
||||||
context "as a teacher" do
|
context "as a teacher" do
|
||||||
it "deletes a poll successfully" do
|
it "deletes a poll successfully" do
|
||||||
|
@user = @teacher
|
||||||
delete_destroy
|
delete_destroy
|
||||||
|
|
||||||
response.code.should == '204'
|
response.code.should == '204'
|
||||||
|
@ -193,6 +204,7 @@ describe Polling::PollsController, type: :request do
|
||||||
choice_a = @poll.poll_choices.create!(text: 'choice a')
|
choice_a = @poll.poll_choices.create!(text: 'choice a')
|
||||||
choice_b = @poll.poll_choices.create!(text: 'choice b')
|
choice_b = @poll.poll_choices.create!(text: 'choice b')
|
||||||
|
|
||||||
|
@user = @teacher
|
||||||
delete_destroy
|
delete_destroy
|
||||||
response.code.should == '204'
|
response.code.should == '204'
|
||||||
Polling::PollChoice.find_by_id(choice_a.id).should be_nil
|
Polling::PollChoice.find_by_id(choice_a.id).should be_nil
|
||||||
|
|
Loading…
Reference in New Issue