fix outcomes not updated on manually scored quizzes

fixes OUT-1832

test plan:
- create a learning outcome
- create a question bank and align the outcome
- add at least one text question to the bank, such as
  an essay question
- create a quiz that allow retakes for 'latest score'
- attach the questions from the bank to the newly created
  quiz
- as a student, take the quiz
- there should not be any learning outcome result yet,
  since the essay question needs grading
- as the teacher, grade the essay question
- there should now be a learning outcome result
- try giving the essay question a different score
  the outcome should update properly based on the given
  score
- change the quiz kept score on retakes to 'highest'
- take the quiz as a student
- as the teacher, give the quiz a higher score
- the outcome should update
- take the quiz as the student again
- as the teacher, give the quiz a lower score
- the outcome should not update, since the original
  higher score should still be the kept score

Change-Id: Icd2d0894ba3b9c956878e5691aae46f6f6c90b9a
Reviewed-on: https://gerrit.instructure.com/137946
Tested-by: Jenkins
Reviewed-by: Neil Gupta <ngupta@instructure.com>
Reviewed-by: Frank Murphy <fmurphy@instructure.com>
QA-Review: Andrew Porter <hporter-c@instructure.com>
Product-Review: Sidharth Oberoi <soberoi@instructure.com>
This commit is contained in:
Matthew Berns 2018-01-15 14:08:55 -06:00 committed by Matt Berns
parent 6d50f50707
commit 9b18df5c62
3 changed files with 43 additions and 5 deletions

View File

@ -636,6 +636,7 @@ class Quizzes::QuizSubmission < ActiveRecord::Base
end
def update_scores(params)
original_score = self.score
params = (params || {}).with_indifferent_access
self.manually_scored = false
self.grader_id = params[:grader_id]
@ -721,6 +722,10 @@ class Quizzes::QuizSubmission < ActiveRecord::Base
self.without_versioning(&:save)
end
self.reload
grader = Quizzes::SubmissionGrader.new(self)
if grader.outcomes_require_update(self, original_score)
grader.track_outcomes(version.model.attempt)
end
true
end

View File

@ -54,7 +54,7 @@ module Quizzes
@submission.with_versioning(true) do |s|
original_score = s.kept_score
if s.save
track_outcomes(s.attempt) if s.quiz.assignment? && kept_score_updating?(original_score)
track_outcomes(s.attempt) if outcomes_require_update(s, original_score)
end
end
@submission.context_module_action
@ -99,6 +99,10 @@ module Quizzes
return result
end
def outcomes_require_update(submission, original_score)
submission.quiz.assignment? && kept_score_updating?(original_score)
end
def track_outcomes(attempt)
return unless @submission.user_id
@ -129,8 +133,8 @@ module Quizzes
# we'll need this method to return true. if the method is highest,
# the kept score only updates if it's higher than the original score
quiz = @submission.quiz
return true if quiz.scoring_policy != 'keep_highest' || quiz.points_possible.to_i == 0
@submission.kept_score != original_score
return true if quiz.scoring_policy != 'keep_highest' || quiz.points_possible.to_i == 0 || original_score.nil?
@submission.kept_score && @submission.kept_score > original_score
end
def questions_and_alignments(question_ids)

View File

@ -253,13 +253,42 @@ describe Quizzes::QuizOutcomeResultBuilder do
answer_a_question(@q2, @sub, correct: false)
Quizzes::SubmissionGrader.new(@sub).grade_submission
@outcome.reload
@quiz_results = @outcome.learning_outcome_results.where(user_id: @user).to_a
end
it "does not create an outcome result" do
expect(@quiz_results).to be_empty
expect(@outcome.learning_outcome_results.where(user_id: @user).count).to equal 0
end
it "creates and updates an outcome result once fully manually graded" do
# update_scores is the method fired when manually grading a quiz in speedgrader.
@sub.update_scores({
'context_id' => @course.id,
'override_scores' => true,
'context_type' => 'Course',
'submission_version_number' => '1',
"question_score_#{@q1.id}" => "1",
})
expect(@outcome.learning_outcome_results.where(user_id: @user).count).to equal 0
@sub.update_scores({
'context_id' => @course.id,
'override_scores' => true,
'context_type' => 'Course',
'submission_version_number' => '1',
"question_score_#{@q2.id}" => "1"
})
results = @outcome.learning_outcome_results.where(user_id: @user)
expect(results.count).to equal 1
expect(results[0].score).to equal 2.0
@sub.update_scores({
'context_id' => @course.id,
'override_scores' => true,
'context_type' => 'Course',
'submission_version_number' => '1',
"question_score_#{@q1.id}" => "2"
})
results[0].reload
expect(results[0].score).to equal 3.0
end
end
describe "ungraded quizzes and surveys" do