From cc584d67da824ead5410f8142ae1ad48620051d8 Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Tue, 15 Sep 2015 14:18:45 -0600 Subject: [PATCH] select_provisional_grade endpoint test plan: 1. have a moderated assignment and at least one student selected for moderation 2. as two different TAs, give provisional grades to a student 3. use the "list gradeable students" endpoint with include[]=provisional_grades to see the provisional_grade_ids for the two grades (see https://gerrit.instructure.com/#/c/63092/) 4. use the "select provisional grade" endpoint to select one of these provisional grades for publishing PUT /courses/X/assignments/Y/select_provisional_grade/Z where Z is a provisional_grade_id from step 3 5. the response from step 4 should be a simple json object repeating the course, assignment, and provisional grade ids 6. redo the endpoint from step 3 to confirm the provisional grade was actually selected (a selected_provisional_grade_id will be returned along with the student whose grade was selected) fixes CNVS-23132 Change-Id: Ic05bce9685f6b246ee8e484523d51a9a014fb517 Reviewed-on: https://gerrit.instructure.com/63356 QA-Review: Clare Strong Reviewed-by: Dan Minkevitch Tested-by: Jenkins Product-Review: Jeremy Stanley --- app/controllers/submissions_api_controller.rb | 24 ++++++++++ app/models/assignment.rb | 1 + config/routes.rb | 1 + spec/apis/v1/submissions_api_spec.rb | 45 +++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/app/controllers/submissions_api_controller.rb b/app/controllers/submissions_api_controller.rb index 41f014964de..5976989a310 100644 --- a/app/controllers/submissions_api_controller.rb +++ b/app/controllers/submissions_api_controller.rb @@ -755,6 +755,30 @@ class SubmissionsApiController < ApplicationController end end + # undocumented @API Select provisional grade + # + # Choose which provisional grade the student should receive for a submission. + # The caller must have :moderate_grades rights. + # + # @example_response + # { + # "assignment_id": 867, + # "student_id": 5309, + # "selected_provisional_grade_id": 53669 + # } + # + def select_provisional_grade + if authorized_action(@context, @current_user, :moderate_grades) + assignment = @context.assignments.active.find(params[:assignment_id]) + pg = assignment.provisional_grades.find(params[:provisional_grade_id]) + selection = assignment.moderated_grading_selections.where(student_id: pg.submission.user_id).first + return render :json => { :message => 'student not in moderation set' }, :status => :bad_request unless selection + selection.provisional_grade = pg + selection.save! + render :json => selection.as_json(:include_root => false, :only => %w(assignment_id student_id selected_provisional_grade_id)) + end + end + # @API Grade or comment on multiple submissions # # Update the grading and comments on multiple student's assignment diff --git a/app/models/assignment.rb b/app/models/assignment.rb index 3420c138e5b..ea199e5b599 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -65,6 +65,7 @@ class Assignment < ActiveRecord::Base attr_reader :assignment_changed has_many :submissions, :dependent => :destroy + has_many :provisional_grades, :through => :submissions has_many :attachments, :as => :context, :dependent => :destroy has_many :assignment_student_visibilities has_one :quiz, class_name: 'Quizzes::Quiz' diff --git a/config/routes.rb b/config/routes.rb index 72ee7332329..90e2adb0da8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -976,6 +976,7 @@ CanvasRails::Application.routes.draw do end get "courses/:course_id/assignments/:assignment_id/gradeable_students", action: :gradeable_students, as: "course_assignment_gradeable_students" post "courses/:course_id/assignments/:assignment_id/publish_provisional_grades", action: :publish_provisional_grades, as: 'publish_provisional_grades' + put "courses/:course_id/assignments/:assignment_id/select_provisional_grade/:provisional_grade_id", action: :select_provisional_grade end post '/courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/files', action: :create_file, controller: :submission_comments_api diff --git a/spec/apis/v1/submissions_api_spec.rb b/spec/apis/v1/submissions_api_spec.rb index 8e229d3fa6a..d8aeb359d49 100644 --- a/spec/apis/v1/submissions_api_spec.rb +++ b/spec/apis/v1/submissions_api_spec.rb @@ -3395,4 +3395,49 @@ describe 'Submissions API', type: :request do end end end + + describe "select_provisional_grade" do + before(:once) do + course_with_student :active_all => true + ta_in_course :active_all => true + @course.root_account.allow_feature! :moderated_grading + @course.enable_feature! :moderated_grading + @assignment = @course.assignments.build + @assignment.moderated_grading = true + @assignment.save! + subs = @assignment.grade_student @student, :grader => @ta, :score => 0, :provisional => true + @pg = subs.first.provisional_grade(@ta) + @path = "/api/v1/courses/#{@course.id}/assignments/#{@assignment.id}/select_provisional_grade/#{@pg.id}" + @params = { :controller => 'submissions_api', :action => 'select_provisional_grade', + :format => 'json', :course_id => @course.to_param, :assignment_id => @assignment.to_param, + :provisional_grade_id => @pg.to_param } + end + + it "should fail if the student isn't in the moderation set" do + json = api_call_as_user(@teacher, :put, @path, @params, {}, {}, { :expected_status => 400 }) + expect(json['message']).to eq 'student not in moderation set' + end + + context "with moderation set" do + before(:once) do + @selection = @assignment.moderated_grading_selections.build + @selection.student_id = @student.id + @selection.save! + end + + it "should require :moderate_grades" do + api_call_as_user(@ta, :put, @path, @params, {}, {}, { :expected_status => 401 }) + end + + it "should select a provisional grade" do + json = api_call_as_user(@teacher, :put, @path, @params) + expect(json).to eq({ + 'assignment_id' => @assignment.id, + 'student_id' => @student.id, + 'selected_provisional_grade_id' => @pg.id + }) + expect(@selection.reload.provisional_grade).to eq(@pg) + end + end + end end