329 lines
11 KiB
Ruby
329 lines
11 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2011 - present Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
# Software Foundation, version 3 of the License.
|
|
#
|
|
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
require "nokogiri"
|
|
|
|
describe GradebooksHelper do
|
|
include TextHelper
|
|
|
|
before do
|
|
stub_const("FakeAssignment",
|
|
Struct.new(:grading_type,
|
|
:quiz,
|
|
:points_possible,
|
|
:anonymous_grading) do
|
|
def anonymous_grading?
|
|
anonymous_grading
|
|
end
|
|
end)
|
|
|
|
stub_const("FakeSubmission",
|
|
Struct.new(:assignment,
|
|
:score,
|
|
:grade,
|
|
:submission_type,
|
|
:workflow_state,
|
|
:excused?))
|
|
|
|
stub_const("FakeQuiz",
|
|
Struct.new(:survey, :anonymous_submissions) do
|
|
def survey?
|
|
survey
|
|
end
|
|
|
|
def anonymous_survey?
|
|
survey? && anonymous_submissions
|
|
end
|
|
end)
|
|
end
|
|
|
|
let(:assignment) { FakeAssignment.new }
|
|
let(:submission) { FakeSubmission.new(assignment) }
|
|
let(:quiz) { assignment.quiz = FakeQuiz.new }
|
|
let(:anonymous_survey) { assignment.quiz = FakeQuiz.new(true, true) }
|
|
|
|
describe "#anonymous_survey?" do
|
|
it "requires a quiz" do
|
|
expect(helper.anonymous_survey?(assignment)).to eq false
|
|
end
|
|
|
|
it "is falsy with just a survey" do
|
|
quiz.survey = true
|
|
expect(helper.anonymous_survey?(assignment)).to eq false
|
|
end
|
|
|
|
it "is falsy with just anonymous_submissions" do
|
|
quiz.anonymous_submissions = true
|
|
expect(helper.anonymous_survey?(assignment)).to eq false
|
|
end
|
|
|
|
it "is truthy with an anonymous survey" do
|
|
anonymous_survey
|
|
expect(helper.anonymous_survey?(assignment)).to eq true
|
|
end
|
|
end
|
|
|
|
describe "#force_anonymous_grading?" do
|
|
it "returns false by default" do
|
|
expect(helper.force_anonymous_grading?(assignment_model)).to eq false
|
|
end
|
|
|
|
it "returns true if anonymous quiz" do
|
|
anonymous_survey
|
|
expect(helper.force_anonymous_grading?(assignment)).to eq true
|
|
end
|
|
|
|
it "returns true for an anonymously-graded assignment" do
|
|
assignment = assignment_model
|
|
allow(assignment).to receive(:anonymize_students?).and_return(true)
|
|
expect(helper.force_anonymous_grading?(assignment)).to be true
|
|
end
|
|
|
|
it "returns false for a non-anonymously-graded assignment" do
|
|
assignment = assignment_model
|
|
allow(assignment).to receive(:anonymize_students?).and_return(false)
|
|
expect(helper.force_anonymous_grading?(assignment)).to eq false
|
|
end
|
|
end
|
|
|
|
describe "#force_anonymous_grading_reason" do
|
|
it "returns nothing if anonymous grading is not forced" do
|
|
expect(helper.force_anonymous_grading_reason(assignment_model)).to eq ""
|
|
end
|
|
|
|
it "returns anonymous survey reason" do
|
|
anonymous_survey
|
|
expect(helper.force_anonymous_grading_reason(assignment)).to match(/anonymous survey/)
|
|
end
|
|
|
|
it "returns anonymous grading" do
|
|
assignment = assignment_model
|
|
allow(assignment).to receive(:anonymize_students?).and_return(true)
|
|
expect(helper.force_anonymous_grading_reason(assignment)).to match(/anonymous grading/)
|
|
end
|
|
end
|
|
|
|
describe "#student_score_display_for(submission, can_manage_grades)" do
|
|
let(:score_display) { helper.student_score_display_for(submission) }
|
|
let(:parsed_display) { Nokogiri::HTML5(score_display) }
|
|
let(:score_icon) { parsed_display.at_css("i") }
|
|
let(:score_screenreader_text) { parsed_display.at_css(".screenreader-only").text }
|
|
|
|
context "when the supplied submission is nil" do
|
|
it "must return a dash" do
|
|
score = helper.student_score_display_for(nil)
|
|
expect(score).to eq "-"
|
|
end
|
|
end
|
|
|
|
context "when the submission has been graded" do
|
|
before do
|
|
submission.score = 1
|
|
submission.grade = 1
|
|
end
|
|
|
|
context "and the assignment is graded pass-fail" do
|
|
before do
|
|
assignment.grading_type = "pass_fail"
|
|
end
|
|
|
|
context "with a passing grade" do
|
|
before do
|
|
submission.score = 1
|
|
end
|
|
|
|
it "must give us a check icon" do
|
|
expect(score_icon["class"]).to include "icon-check"
|
|
end
|
|
|
|
it "must indicate the assignment is complete via alt text" do
|
|
expect(score_screenreader_text).to include "Complete"
|
|
end
|
|
end
|
|
|
|
context "with a faililng grade" do
|
|
before do
|
|
submission.grade = "incomplete"
|
|
submission.score = nil
|
|
end
|
|
|
|
it "must give us a check icon" do
|
|
expect(score_icon["class"]).to include "icon-x"
|
|
end
|
|
|
|
it "must indicate the assignment is complete via alt text" do
|
|
expect(score_screenreader_text).to include "Incomplete"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "and the assignment is a percentage grade" do
|
|
it "must output the percentage" do
|
|
assignment.grading_type = "percent"
|
|
submission.grade = "42.5"
|
|
expect(score_display).to eq "42.5%"
|
|
end
|
|
end
|
|
|
|
context "and the assignment is a point grade" do
|
|
it "must output the grade rounded to two decimal points" do
|
|
assignment.grading_type = "points"
|
|
submission.grade = "42.3542"
|
|
submission.score = 42.3542
|
|
expect(score_display).to eq "42.35"
|
|
end
|
|
end
|
|
|
|
context "and the assignment is a letter grade" do
|
|
# clearly this code needs to change; just look at this nonsensical expectation:
|
|
it "has no score_display" do
|
|
assignment.grading_type = "letter_grade"
|
|
submission.grade = "B"
|
|
submission.score = 83
|
|
expect(score_display).to be_nil
|
|
end
|
|
end
|
|
|
|
context "and the assignment is a gpa scaled grade" do
|
|
# clearly this code needs to change; just look at this nonsensical expectation:
|
|
it "has no score_display" do
|
|
assignment.grading_type = "gpa_scale"
|
|
submission.grade = "B"
|
|
submission.score = 83
|
|
expect(score_display).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the submission is ungraded" do
|
|
before do
|
|
submission.score = nil
|
|
submission.grade = nil
|
|
end
|
|
|
|
context "and the submission is an online submission type" do
|
|
it "must output an appropriate icon" do
|
|
submission.submission_type = "online_quiz"
|
|
expect(score_icon["class"]).to include "submission_icon"
|
|
end
|
|
end
|
|
|
|
context "and the submission is some unknown type" do
|
|
it "must output a dash" do
|
|
submission.submission_type = "bogus_type"
|
|
expect(score_display).to eq "-"
|
|
end
|
|
end
|
|
|
|
it "shows an 'annotate' icon when the submission is a student annotation" do
|
|
submission.submission_type = "student_annotation"
|
|
expect(score_icon["class"]).to include "icon-annotate"
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#graded_by_title" do
|
|
it "returns an I18n translated string" do
|
|
expect(I18n).to receive(:t).with(
|
|
"%{graded_date} by %{grader}",
|
|
graded_date: "the_date",
|
|
grader: "the_grader"
|
|
).and_return("the return value")
|
|
expect(TextHelper).to receive(:date_string).with("the_date").and_return("the_date")
|
|
helper.graded_by_title("the_date", "the_grader")
|
|
end
|
|
end
|
|
|
|
describe "#history_submission_class" do
|
|
it "returns a class based on given submission" do
|
|
submission = OpenStruct.new(assignment_id: "assignment_id", user_id: "user_id")
|
|
expect(
|
|
helper.history_submission_class(submission)
|
|
).to eq "assignment_assignment_id_user_user_id_current_grade"
|
|
end
|
|
end
|
|
|
|
describe "translated_due_date_for_speedgrader" do
|
|
before do
|
|
@current_user = user_factory
|
|
@course = Account.default.courses.create!(name: "My Course")
|
|
@course.enroll_teacher(@current_user, enrollment_state: "active")
|
|
@student1 = student_in_course(course: @course, active_all: true).user
|
|
@student2 = student_in_course(course: @course, active_all: true).user
|
|
end
|
|
|
|
it "produces a translated due date if multiple dates" do
|
|
assignment = @course.assignments.create!(
|
|
title: "My Multiple Due Date Assignment",
|
|
due_at: "2021-04-15T22:00:24Z"
|
|
)
|
|
section1 = CourseSection.create!(name: "Section 1", course: @course)
|
|
section2 = CourseSection.create!(name: "Section 2", course: @course)
|
|
student_in_section(section1, user: @student1)
|
|
student_in_section(section2, user: @student2)
|
|
assignment.assignment_overrides.create!(
|
|
due_at: "2021-04-15T22:00:24Z",
|
|
due_at_overridden: true,
|
|
set: section1
|
|
)
|
|
assignment.assignment_overrides.create!(
|
|
due_at: "2021-04-22T22:00:24Z",
|
|
due_at_overridden: true,
|
|
set: section2
|
|
)
|
|
expect(translated_due_date_for_speedgrader(assignment)).to eq "Due: Multiple Due Dates"
|
|
end
|
|
|
|
it "produces a translated due date based on due date" do
|
|
assignment = @course.assignments.create!(
|
|
title: "My Due Date Assignment",
|
|
due_at: "2021-04-15T22:00:24Z"
|
|
)
|
|
expect(translated_due_date_for_speedgrader(assignment)).to eq "Due: Apr 15, 2021 at 10pm"
|
|
end
|
|
|
|
it "produces No due date message if no due date" do
|
|
assignment = @course.assignments.create!(
|
|
title: "My Assignment with no due date",
|
|
due_at: nil
|
|
)
|
|
expect(translated_due_date_for_speedgrader(assignment)).to eq "Due: No Due Date"
|
|
end
|
|
|
|
it "produces a translated due date based on single section overriden due date" do
|
|
assignment = @course.assignments.create!(
|
|
title: "My Single Section Overridden Due Date Assignment",
|
|
only_visible_to_overrides: true,
|
|
workflow_state: "published"
|
|
)
|
|
single_section = CourseSection.create!(name: "Single Section", course: @course)
|
|
student_in_section(single_section, user: @student1)
|
|
assignment.assignment_overrides.create!(
|
|
due_at: "2021-04-15T22:00:24Z",
|
|
due_at_overridden: true,
|
|
set: single_section,
|
|
workflow_state: "active"
|
|
)
|
|
assignment.reload
|
|
expect(translated_due_date_for_speedgrader(assignment)).to eq "Due: Apr 15, 2021 at 10pm"
|
|
end
|
|
end
|
|
end
|