Handle NaN in GradeCalculator

Fixes CNVS-32980

Test plan: smoke test grade calculator
* As a teacher, create an assignment
* As a student, submit something for that assignment
* As a teacher, grade the submission
* Make sure the grade saved properly and is viewable by teacher
  and student.

Change-Id: Ie789492c3966be660bb726079dc2191cc1cbf8fe
Reviewed-on: https://gerrit.instructure.com/99065
Reviewed-by: Jeremy Neander <jneander@instructure.com>
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
Tested-by: Jenkins
QA-Review: Anju Reddy <areddy@instructure.com>
Product-Review: Neil Gupta <ngupta@instructure.com>
This commit is contained in:
Neil Gupta 2017-01-06 17:10:49 -06:00
parent bf7456da8c
commit 993ff42ae3
2 changed files with 31 additions and 4 deletions

View File

@ -147,6 +147,13 @@ class GradeCalculator
end
end
def number_or_null(score)
# GradeCalculator sometimes divides by 0 somewhere,
# resulting in NaN. Treat that as null here
score = nil if score.try(:nan?)
score || 'NULL'
end
def save_scores
raise "Can't save scores when ignore_muted is false" unless @ignore_muted
@ -164,7 +171,7 @@ class GradeCalculator
current_score = CASE enrollment_id
#{@current_updates.map do |user_id, score|
enrollments_by_user[user_id].map do |enrollment|
"WHEN #{enrollment.id} THEN #{score || 'NULL'}"
"WHEN #{enrollment.id} THEN #{number_or_null(score)}"
end.join(' ')
end.join(' ')}
ELSE current_score
@ -172,7 +179,7 @@ class GradeCalculator
final_score = CASE enrollment_id
#{@final_updates.map do |user_id, score|
enrollments_by_user[user_id].map do |enrollment|
"WHEN #{enrollment.id} THEN #{score || 'NULL'}"
"WHEN #{enrollment.id} THEN #{number_or_null(score)}"
end.join(' ')
end.join(' ')}
ELSE final_score
@ -190,7 +197,7 @@ class GradeCalculator
CASE enrollments.id
#{@current_updates.map do |user_id, score|
enrollments_by_user[user_id].map do |enrollment|
"WHEN #{enrollment.id} THEN #{score || 'NULL'}"
"WHEN #{enrollment.id} THEN #{number_or_null(score)}"
end.join(' ')
end.join(' ')}
ELSE NULL
@ -198,7 +205,7 @@ class GradeCalculator
CASE enrollments.id
#{@final_updates.map do |user_id, score|
enrollments_by_user[user_id].map do |enrollment|
"WHEN #{enrollment.id} THEN #{score || 'NULL'}"
"WHEN #{enrollment.id} THEN #{number_or_null(score)}"
end.join(' ')
end.join(' ')}
ELSE NULL

View File

@ -456,6 +456,26 @@ describe GradeCalculator do
end
end
describe '#number_or_null' do
it "should return a valid score" do
calc = GradeCalculator.new [@user.id], @course.id
score = 23.4
expect(calc.send(:number_or_null, score)).to eql(score)
end
it "should convert NaN to NULL" do
calc = GradeCalculator.new [@user.id], @course.id
score = 0/0.0
expect(calc.send(:number_or_null, score)).to eql('NULL')
end
it "should convert nil to NULL" do
calc = GradeCalculator.new [@user.id], @course.id
score = nil
expect(calc.send(:number_or_null, score)).to eql('NULL')
end
end
describe '#compute_and_save_scores' do
before(:once) do
@first_period, @second_period = grading_periods(count: 2)