remove lower bound override calculations

When an override score exists on an enrollment, the actual percentage
is now returned for students. Previously, if a grading standard
existed for the course, the override score shown to students would be
the lower bound of the grade range that the override score was in.

closes GRADE-2006

Test Plan

- Enable grading standards.
- As a teacher, open the gradebook.
- Assign an override score to the student, taking care to make the
  score _not_ at the boundary of a grade (low end or high end).
- As a student, open the grades summary page and verify that the
  override score is the exact percentage given by the teacher.
- As the teacher again, enter in a letter override grade.
- As the student, verify that the override score is the lower bound
  of the grade given.

Change-Id: I7066a8d652224db4036dcaf6c637057eefb8aa73
Reviewed-on: https://gerrit.instructure.com/182046
Tested-by: Jenkins
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Derek Bender <djbender@instructure.com>
QA-Review: Gary Mei <gmei@instructure.com>
Product-Review: Keith Garner <kgarner@instructure.com>
This commit is contained in:
Gary Mei 2019-02-19 13:19:43 -06:00
parent 7df1200f02
commit 4a998ecf12
11 changed files with 5 additions and 116 deletions

View File

@ -35,7 +35,7 @@ import round from 'compiled/util/round'
import numberHelper from '../shared/helpers/numberHelper'
import CourseGradeCalculator from '../gradebook/CourseGradeCalculator'
import {scopeToUser} from '../gradebook/EffectiveDueDates'
import {gradeToScoreLowerBound, scoreToGrade} from '../gradebook/GradingSchemeHelper'
import {scoreToGrade} from '../gradebook/GradingSchemeHelper'
import GradeFormatHelper from '../gradebook/shared/helpers/GradeFormatHelper'
import StatusPill from '../grading/StatusPill'
import SelectMenuGroup from '../grade_summary/SelectMenuGroup'
@ -361,7 +361,6 @@ function calculateTotals (calculatedGrades, currentOrFinal, groupWeightingScheme
const scoreAsPercent = calculateGrade(finalScore, finalPossible)
let finalGrade
let letterGrade
let teaserText
if (gradingSchemeEnabled()) {
@ -369,18 +368,13 @@ function calculateTotals (calculatedGrades, currentOrFinal, groupWeightingScheme
ENV.effective_final_score :
calculatePercentGrade(finalScore, finalPossible)
letterGrade = scoreToGrade(scoreToUse, ENV.grading_scheme)
const letterGrade = scoreToGrade(scoreToUse, ENV.grading_scheme)
$('.final_grade .letter_grade').text(letterGrade)
}
if (!gradeChanged && overrideScorePresent()) {
finalGrade = formatPercentGrade(ENV.effective_final_score)
teaserText = scoreAsPoints
if (gradingSchemeEnabled()) {
finalGrade = formatPercentGrade(gradeToScoreLowerBound(letterGrade, ENV.grading_scheme))
} else {
finalGrade = formatPercentGrade(ENV.effective_final_score)
}
} else if (showTotalGradeAsPoints && groupWeightingScheme !== 'percent') {
finalGrade = scoreAsPoints
teaserText = scoreAsPercent

View File

@ -1077,7 +1077,7 @@ class Enrollment < ActiveRecord::Base
score = find_score(id_opts)
if score&.overridden? && course.feature_enabled?(:final_grades_override)
score.effective_final_score_lower_bound
score.effective_final_score
else
computed_current_score(id_opts)
end
@ -1097,7 +1097,7 @@ class Enrollment < ActiveRecord::Base
score = find_score(id_opts)
if score&.overridden? && course.feature_enabled?(:final_grades_override)
score.effective_final_score_lower_bound
score.effective_final_score
else
computed_final_score(id_opts)
end

View File

@ -124,17 +124,6 @@ class GradingStandard < ActiveRecord::Base
ordered_scheme.max_by {|_, lower_bound| score >= lower_bound * 100 ? lower_bound : -lower_bound }[0]
end
def lower_bound(score)
best_index = 0
grading_standard_data = data.reverse
grading_standard_data.each_with_index do |grade_bracket, index|
best_index = index if score >= grade_bracket[1] * 100
end
grading_standard_data[best_index][1] * 100
end
def data=(new_val)
self.version = VERSION
# round values to the nearest 0.01 (0.0001 since e.g. 78 is stored as .78)

View File

@ -84,12 +84,6 @@ class Score < ActiveRecord::Base
override_score || final_score
end
def effective_final_score_lower_bound
score = effective_final_score
return score unless course.grading_standard_enabled?
course.grading_standard_or_default.lower_bound(score)
end
def effective_final_grade
score_to_grade(effective_final_score)
end

View File

@ -102,32 +102,20 @@ module Api
end
it "returns the override score in place of current score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@course_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:computed_current_score)).to be 99.0
end
it "returns the lower bound of override in place of current if present, feature enabled, and standards exist" do
@course_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:computed_current_score)).to be 94.0
end
it "returns the override grade in place of final grade if present and feature enabled" do
@course_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:computed_final_grade)).to eq "A"
end
it "returns the override score in place of final score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@course_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:computed_final_score)).to be 99.0
end
it "returns the lower bound of override in place of final if present, feature enabled, and standards exist" do
@course_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:computed_final_score)).to be 94.0
end
it "does not return an override_grade key" do
@course_score.update!(override_score: 99.0)
expect(json_enrollment.keys).not_to include :override_grade
@ -260,32 +248,20 @@ module Api
end
it "returns the override score in place of current score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:current_period_computed_current_score)).to be 99.0
end
it "returns the lower bound of override in place of current if present, feature enabled, and grading standards exist" do
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:current_period_computed_current_score)).to be 94.0
end
it "returns the override grade in place of final grade if present and feature enabled" do
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:current_period_computed_final_grade)).to eq "A"
end
it "returns the override score in place of final score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:current_period_computed_final_score)).to be 99.0
end
it "returns the lower bound of override in place of final if present, feature enabled, and grading standards exist" do
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.fetch(:current_period_computed_final_score)).to be 94.0
end
it "does not return an override_grade key" do
@gp_score.update!(override_score: 99.0)
expect(json_enrollment.keys).not_to include :override_grade

View File

@ -1898,28 +1898,16 @@ describe CoursesController, type: :request do
end
it "returns the override score instead of the current score" do
@course2.update!(grading_standard_enabled: false)
json_response = courses_api_index_call
expect(enrollment(json_response).fetch("computed_current_score")).to be 89.0
end
it "returns the lower bound of override score instead of the current score" do
json_response = courses_api_index_call
expect(enrollment(json_response).fetch("computed_current_score")).to be 87.0
end
it "returns the override grade instead of the current grade" do
json_response = courses_api_index_call
expect(enrollment(json_response).fetch("computed_current_grade")).to eq "B+"
end
it "returns the lower bound of override score instead of the current final score" do
json_response = courses_api_index_call
expect(enrollment(json_response).fetch("computed_final_score")).to be 87.0
end
it "returns the override score instead of the current final score" do
@course2.update!(grading_standard_enabled: false)
json_response = courses_api_index_call
expect(enrollment(json_response).fetch("computed_final_score")).to be 89.0
end

View File

@ -402,32 +402,20 @@ describe Api::V1::User do
end
it "returns the override score in place of current score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@course_score.update!(override_score: 99.0)
expect(grades.fetch("current_score")).to be 99.0
end
it "returns the lower bound of override in place of current if present, feature enabled, and standards exist" do
@course_score.update!(override_score: 99.0)
expect(grades.fetch("current_score")).to be 94.0
end
it "returns the override grade in place of final grade if present and feature enabled" do
@course_score.update!(override_score: 99.0)
expect(grades.fetch("final_grade")).to eq "A"
end
it "returns the override score in place of final score if present and feature enabled" do
course.update!(grading_standard_enabled: false)
@course_score.update!(override_score: 99.0)
expect(grades.fetch("final_score")).to be 99.0
end
it "returns the lower bound of override in place of final if present, feature enabled, and standards exist" do
@course_score.update!(override_score: 99.0)
expect(grades.fetch("final_score")).to be 94.0
end
it "does not return an override_grade key" do
@course_score.update!(override_score: 99.0)
expect(grades.keys).not_to include :override_grade

View File

@ -351,13 +351,6 @@ QUnit.module('GradeSummary.calculateTotals', (suiteHooks) => {
ENV.grading_scheme = [['A', 0.90], ['B', 0.80], ['C', 0.70], ['D', 0.60], ['F', 0]]
})
test('sets the percent grade to the corresponding lower bound of the effective grade', () => {
ENV.effective_final_score = 72
GradeSummary.calculateTotals(exampleGrades, 'current', 'percent')
const $grade = $fixtures.find('.final_grade .grade').first()
strictEqual($grade.text(), '70%')
})
test('sets the letter grade to the effective grade', () => {
ENV.effective_final_score = 72
GradeSummary.calculateTotals(exampleGrades, 'current', 'percent')

View File

@ -391,12 +391,6 @@ describe Enrollment do
expect(@enrollment.effective_current_score).to eq 97.0
end
it "returns the lower bound of an override score, if a grading standard is enabled" do
allow(@course).to receive(:grading_standard_enabled?).and_return(true)
@enrollment.scores.create!(current_score: 79.0, override_score: 97.0)
expect(@enrollment.effective_current_score).to eq 94.0
end
it "does not return the override score if the feature is not enabled" do
@course.disable_feature!(:final_grades_override)
@enrollment.scores.create!(current_score: 79.0, override_score: 97.0)
@ -480,12 +474,6 @@ describe Enrollment do
expect(@enrollment.effective_current_score).to eq 97.0
end
it "returns the lower bound override score, if a grading standard is enabled" do
allow(@course).to receive(:grading_standard_enabled?).and_return true
@enrollment.scores.find_by(course_score: true).update!(override_score: 97.0)
expect(@enrollment.effective_final_score).to be 94.0
end
it "does not return the override score if the feature is not enabled" do
@course.disable_feature!(:final_grades_override)
@enrollment.scores.find_by(course_score: true).update!(override_score: 97.0)

View File

@ -118,13 +118,6 @@ describe GradingStandard do
end
end
describe "#lower_bound" do
it "returns the lower bound of a score" do
standard = GradingStandard.new(data: @default_standard_v1)
expect(standard.lower_bound(82)).to eq 79
end
end
context "#for" do
it "should return standards that match the context" do
grading_standard_for @course

View File

@ -283,20 +283,6 @@ describe Score do
end
end
describe "#effective_final_score_lower_bound" do
it "returns the lowest possible score in the matching grading scheme, if grading schemes enabled" do
score.update!(override_score: 89)
allow(score.course).to receive(:grading_standard_enabled?).and_return(true)
expect(score.effective_final_score_lower_bound).to eq 87
end
it "returns the effective final score if grading schemes are not enabled" do
score.update!(override_score: 89)
allow(score.course).to receive(:grading_standard_enabled?).and_return(false)
expect(score.effective_final_score_lower_bound).to eq 89
end
end
describe "#effective_final_grade" do
it "returns a grade commensurate with the override score when one is present" do
score.update!(override_score: 88)