220 lines
9.3 KiB
Ruby
220 lines
9.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2017 - 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/>.
|
|
|
|
describe GradebookGradingPeriodAssignments do
|
|
before(:once) do
|
|
@example_course = Course.create!
|
|
end
|
|
|
|
describe "#to_h" do
|
|
before(:once) do
|
|
@student1 = student_in_course(course: @example_course, active_all: true).user
|
|
@student2 = student_in_course(course: @example_course, active_all: true).user
|
|
@assignment1_in_gp1 = @example_course.assignments.create!(due_at: 3.months.ago)
|
|
@assignment2_in_gp2 = @example_course.assignments.create!(due_at: 1.day.from_now)
|
|
@assignment3_in_gp2 = @example_course.assignments.create!(due_at: 2.days.from_now)
|
|
@assignment_not_in_gp = @example_course.assignments.create!(due_at: 6.months.from_now)
|
|
end
|
|
|
|
let(:hash) { GradebookGradingPeriodAssignments.new(@example_course).to_h }
|
|
|
|
context "with grading periods" do
|
|
before(:once) do
|
|
@group = Factories::GradingPeriodGroupHelper.new.create_for_account(@example_course.account)
|
|
@group.enrollment_terms << @example_course.enrollment_term
|
|
@period1, @period2, @period3 = Factories::GradingPeriodHelper.new.create_presets_for_group(
|
|
@group, :past, :current, :future
|
|
)
|
|
[@assignment1_in_gp1, @assignment2_in_gp2, @assignment3_in_gp2, @assignment_not_in_gp].each do |assignment|
|
|
DueDateCacher.recompute(assignment)
|
|
end
|
|
end
|
|
|
|
it "includes the grading period ids as keys on the hash, and a 'none' key to indicate no grading period" do
|
|
@example_course.assignments.create!(due_at: 3.months.from_now)
|
|
expect(hash.keys).to match_array([@period1.id, @period2.id, @period3.id, :none])
|
|
end
|
|
|
|
it "lists the related assignment ids as strings for the grading periods" do
|
|
expect(hash[@period1.id]).to match_array([@assignment1_in_gp1.id.to_s])
|
|
end
|
|
|
|
it "includes all assignments due in a given grading period" do
|
|
expect(hash[@period2.id]).to include(@assignment2_in_gp2.id.to_s)
|
|
expect(hash[@period2.id]).to include(@assignment3_in_gp2.id.to_s)
|
|
end
|
|
|
|
it "includes all assignments due outside of any grading period" do
|
|
assignment = @example_course.assignments.create!(due_at: 9.months.from_now)
|
|
expect(hash[:none]).to include(@assignment_not_in_gp.id.to_s)
|
|
expect(hash[:none]).to include(assignment.id.to_s)
|
|
end
|
|
|
|
it "includes assignments with due dates in multiple grading periods" do
|
|
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 1.day.ago, due_at_overridden: true)
|
|
override.assignment_override_students.create!(user: @student2)
|
|
expect(hash[@period1.id]).to include(@assignment1_in_gp1.id.to_s)
|
|
expect(hash[@period2.id]).to include(@assignment1_in_gp1.id.to_s)
|
|
end
|
|
|
|
it "includes assignments with due dates in a grading period and outside of a grading period" do
|
|
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 9.months.from_now, due_at_overridden: true)
|
|
override.assignment_override_students.create!(user: @student2)
|
|
expect(hash[@period1.id]).to include(@assignment1_in_gp1.id.to_s)
|
|
expect(hash[:none]).to include(@assignment1_in_gp1.id.to_s)
|
|
end
|
|
|
|
it "optionally returns results for a specific student" do
|
|
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 1.day.ago, due_at_overridden: true)
|
|
override.assignment_override_students.create!(user: @student2)
|
|
hash = GradebookGradingPeriodAssignments.new(@example_course, student: @student2).to_h
|
|
expect(hash[@period1.id]).to be_nil
|
|
expect(hash[@period2.id]).to include(@assignment1_in_gp1.id.to_s)
|
|
end
|
|
|
|
it "excludes assignments due outside of any grading period" do
|
|
expect(hash[@period1.id]).not_to include(@assignment_not_in_gp.id.to_s)
|
|
expect(hash[@period2.id]).not_to include(@assignment_not_in_gp.id.to_s)
|
|
end
|
|
|
|
it "excludes grading periods without assignments" do
|
|
expect(hash.keys).not_to include(@period3.id)
|
|
end
|
|
|
|
it "excludes deleted submissions" do
|
|
assignment_in_gp2 = @example_course.assignments.create!(due_at: 1.day.from_now)
|
|
assignment_in_gp2.destroy
|
|
assignment_in_gp2.submissions.preload(:all_submission_comments, :lti_result, :versions, :submission_drafts).map(&:destroy)
|
|
expect(hash[@period2.id]).not_to include(assignment_in_gp2.id.to_s)
|
|
end
|
|
|
|
it "excludes submissions for deleted assignments" do
|
|
assignment_in_gp2 = @example_course.assignments.create!(due_at: 1.day.from_now)
|
|
assignment_in_gp2.destroy
|
|
expect(hash[@period2.id]).not_to include(assignment_in_gp2.id.to_s)
|
|
end
|
|
|
|
it "excludes assignments from other courses" do
|
|
course = Course.create!
|
|
student_in_course(course: course, active_all: true).user
|
|
@group.enrollment_terms << course.enrollment_term
|
|
assignment = course.assignments.create!(due_at: 1.day.from_now)
|
|
expect(hash[@period2.id]).not_to include(assignment.id.to_s)
|
|
end
|
|
|
|
context 'with students that are not active' do
|
|
before(:once) do
|
|
@course = Course.create!
|
|
@student_enrollment = student_in_course(course: @course, active_all: true)
|
|
@assignment = @course.assignments.create!(due_at: @period2.end_date)
|
|
@settings = {}
|
|
end
|
|
|
|
let(:hash) { GradebookGradingPeriodAssignments.new(@course, course_settings: @settings).to_h }
|
|
|
|
describe 'concluded students' do
|
|
before(:once) do
|
|
@student_enrollment.conclude
|
|
end
|
|
|
|
it 'does not include assignments assigned exclusively to concluded students' do
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores deleted enrollments' do
|
|
# update_columns in order to avoid callbacks that would soft-delete the submission
|
|
@student_enrollment.update_columns(workflow_state: :deleted)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores enrollments in other courses' do
|
|
new_course = Course.create!
|
|
new_course.enroll_student(@student_enrollment.user, active_all: true)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores non-student enrollments' do
|
|
@course.enroll_ta(@student_enrollment.user, active_all: true)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'optionally includes assignments assigned exclusively to concluded students' do
|
|
@settings = { 'show_concluded_enrollments' => 'true' }
|
|
expect(hash[@period2.id]).to include @assignment.id.to_s
|
|
end
|
|
|
|
it 'optionally excludes assignments assigned exclusively to concluded students' do
|
|
@settings = { 'show_concluded_enrollments' => 'false' }
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
end
|
|
|
|
describe 'deactivated students' do
|
|
before(:once) do
|
|
@student_enrollment.deactivate
|
|
end
|
|
|
|
it 'does not include assignments assigned exclusively to deactivated students' do
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores deleted enrollments' do
|
|
# update_columns in order to avoid callbacks that would soft-delete the submission
|
|
@student_enrollment.update_columns(workflow_state: :deleted)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores enrollments in other courses' do
|
|
new_course = Course.create!
|
|
new_course.enroll_student(@student_enrollment.user, active_all: true)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'ignores non-student enrollments' do
|
|
@course.enroll_ta(@student_enrollment.user, active_all: true)
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
|
|
it 'optionally includes assignments assigned exclusively to deactivated students' do
|
|
@settings = { 'show_inactive_enrollments' => 'true' }
|
|
expect(hash[@period2.id]).to include @assignment.id.to_s
|
|
end
|
|
|
|
it 'optionally excludes assignments assigned exclusively to deactivated students' do
|
|
@settings = { 'show_inactive_enrollments' => 'false' }
|
|
expect(hash[@period2.id]).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
it "returns an empty hash when grading periods are not in use" do
|
|
expect(hash).to eq({})
|
|
end
|
|
end
|
|
|
|
it "raises an exception if context is not a course" do
|
|
expect { GradebookGradingPeriodAssignments.new({}) }.to raise_error("Context must be a course")
|
|
end
|
|
|
|
it "raises an exception if context has no id" do
|
|
expect { GradebookGradingPeriodAssignments.new(Course.new) }.to raise_error("Context must have an id")
|
|
end
|
|
end
|