add user_summary to submission_json

- new submission_json API include key 'user_summary' for provisional
  grades front-end
- extracted ModeratedGrading::NullProvisionalGrade to its own file.
- added the scored_by scope to ProvisionalGrade
- minor refactors to user_display_json
- minor refactors to submission_json & submission_provisional_grades_json

test plan:
- hit the submissions_api index action and include[]=user_summary
- ensure users are listed with their submissions

closes: CNVS-22974

Change-Id: Ia1248859bb0d34aab1940a4b38a034bbf3f244ae
Reviewed-on: https://gerrit.instructure.com/62210
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
Tested-by: Jenkins
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Derek Bender <djbender@instructure.com>
This commit is contained in:
Derek Bender 2015-08-31 15:23:46 -06:00
parent 3822474b96
commit 70a179ab0c
5 changed files with 93 additions and 52 deletions

View File

@ -0,0 +1,20 @@
class ModeratedGrading::NullProvisionalGrade
def initialize(scorer_id)
@scorer_id = scorer_id
end
def grade_attributes
{
'provisional_grade_id' => nil,
'grade' => nil,
'score' => nil,
'graded_at' => nil,
'scorer_id' => @scorer_id,
'grade_matches_current_submission' => true
}
end
def submission_comments
SubmissionComment.none
end
end

View File

@ -12,6 +12,8 @@ class ModeratedGrading::ProvisionalGrade < ActiveRecord::Base
validates :scorer, presence: true
validates :submission, presence: true
scope :scored_by, ->(scorer) { where(scorer_id: scorer) }
def valid?(*)
infer_grade
set_graded_at if @force_save || grade_changed? || score_changed?
@ -94,24 +96,3 @@ class ModeratedGrading::ProvisionalGrade < ActiveRecord::Base
self.graded_at = Time.zone.now
end
end
class ModeratedGrading::NullProvisionalGrade
def initialize(scorer_id)
@scorer_id = scorer_id
end
def grade_attributes
{
'provisional_grade_id' => nil,
'grade' => nil,
'score' => nil,
'graded_at' => nil,
'scorer_id' => @scorer_id,
'grade_matches_current_submission' => true
}
end
def submission_comments
SubmissionComment.none
end
end

View File

@ -25,40 +25,39 @@ module Api::V1::Submission
include Api::V1::User
include Api::V1::SubmissionComment
def submission_json(submission, assignment, user, session, context = nil, includes = [])
def submission_json(submission, assignment, current_user, session, context = nil, includes = [])
context ||= assignment.context
hash = submission_attempt_json(submission, assignment, user, session, context)
hash = submission_attempt_json(submission, assignment, current_user, session, context)
if includes.include?("submission_history")
hash['submission_history'] = []
submission.submission_history.each do |ver|
ver.without_versioned_attachments do
hash['submission_history'] << submission_attempt_json(ver, assignment, user, session, context)
hash['submission_history'] << submission_attempt_json(ver, assignment, current_user, session, context)
end
end
end
if user && includes.include?('provisional_grades') &&
assignment && assignment.context.is_a?(Course) && assignment.moderated_grading?
hash['provisional_grades'] = submission_provisional_grades_json(submission, assignment, user)
if current_user && assignment && includes.include?('provisional_grades') && assignment.moderated_grading?
hash['provisional_grades'] = submission_provisional_grades_json(submission, assignment, current_user)
end
if includes.include?("submission_comments")
hash['submission_comments'] = submission_comments_json(submission.comments_for(@current_user), user)
hash['submission_comments'] = submission_comments_json(submission.comments_for(@current_user), current_user)
end
if includes.include?("rubric_assessment") && submission.rubric_assessment && submission.user_can_read_grade?(user)
if includes.include?("rubric_assessment") && submission.rubric_assessment && submission.user_can_read_grade?(current_user)
ra = submission.rubric_assessment.data
hash['rubric_assessment'] = {}
ra.each { |rating| hash['rubric_assessment'][rating[:criterion_id]] = rating.slice(:points, :comments) }
end
if includes.include?("assignment")
hash['assignment'] = assignment_json(assignment, user, session)
hash['assignment'] = assignment_json(assignment, current_user, session)
end
if includes.include?("course")
hash['course'] = course_json(submission.context, user, session, ['html_url'], nil)
hash['course'] = course_json(submission.context, current_user, session, ['html_url'], nil)
end
if includes.include?("html_url")
@ -69,6 +68,10 @@ module Api::V1::Submission
hash['user'] = user_json(submission.user, user, session, ['avatar_url'], submission.context, nil)
end
if assignment && includes.include?('user_summary')
hash['user'] = user_display_json(submission.user, assignment.context)
end
if includes.include?("visibility")
hash['assignment_visible'] = submission.assignment_visible_to_user?(submission.user)
end
@ -204,19 +207,28 @@ module Api::V1::Submission
attachment
end
private
def submission_provisional_grades_json(submission, assignment, current_user)
provisional_grades = submission.provisional_grades
unless assignment.context.grants_right?(current_user, :moderate_grades)
provisional_grades = provisional_grades.where(scorer_id: current_user)
provisional_grades = provisional_grades.scored_by(current_user)
end
provisional_grades.map do |pg|
pg.grade_attributes.merge({
speedgrader_url: speed_grader_course_gradebook_url(
provisional_grades.map do |provisional_grade|
speed_grader_url = speed_grader_url(submission, assignment, provisional_grade)
provisional_grade.grade_attributes.merge(speedgrader_url: speed_grader_url)
end
end
def speed_grader_url(submission, assignment, provisional_grade)
speed_grader_course_gradebook_url(
:course_id => assignment.context.id,
:assignment_id => assignment.id,
:anchor => { student_id: submission.user_id, provisional_grade_id: pg.id }.to_json
:anchor => {
student_id: submission.user_id,
provisional_grade_id: provisional_grade.id
}.to_json
)
})
end
end
end

View File

@ -135,7 +135,12 @@ module Api::V1::User
else
polymorphic_url([parent_context, user])
end
{ :id => user.id, :display_name => user.short_name, :avatar_image_url => avatar_url_for_user(user, blank_fallback), :html_url => participant_url }
return {
id: user.id,
display_name: user.short_name,
avatar_image_url: avatar_url_for_user(user, blank_fallback),
html_url: participant_url
}
end
# optimization hint, currently user only needs to pull pseudonyms from the db

View File

@ -1269,10 +1269,33 @@ describe 'Submissions API', type: :request do
speedgrader_url = URI.parse(json.first['provisional_grades'].first['speedgrader_url'])
expect(speedgrader_url.path).to eq "/courses/#{@course.id}/gradebook/speed_grader"
expect(speedgrader_url.query).to eq "assignment_id=#{@assignment.id}"
expect(JSON.parse(URI.decode(speedgrader_url.fragment))).to eq({
expect(JSON.parse(URI.decode(speedgrader_url.fragment))).to eq(
{
"student_id" => @student.id,
"provisional_grade_id" => @provisional_grade.id
})
}
)
end
it "can include users" do
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignments/#{@assignment.id}/submissions.json",
{
controller: 'submissions_api',
action: 'index',
format: 'json',
course_id: @course.id,
assignment_id: @assignment.id,
},
{
include: ['user_summary']
}
)
user = json.first['user']
expect(user['display_name']).to eql @student.name
expect(user['avatar_image_url']).to eql "https://localhost/images/messages/avatar-50.png"
expect(user['html_url']).to eql polymorphic_url([@course, @student])
end
end