canvas-lms/spec/lib/effective_due_dates_spec.rb

1630 lines
61 KiB
Ruby

#
# Copyright (C) 2016 - 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 File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
describe Course do
before(:once) do
@test_course = Course.create!
course_with_teacher(course: @test_course, active_all: true)
@teacher = @user
end
describe 'for_course' do
it 'raises error if context is not a course' do
expect { EffectiveDueDates.for_course({}) }.to raise_error('Context must be a course')
end
it 'raises error if context has no id' do
expect { EffectiveDueDates.for_course(Course.new) }.to raise_error('Context must have an id')
end
it 'saves context' do
edd = EffectiveDueDates.for_course(@test_course)
expect(edd.context).to eq(@test_course)
end
end
describe '#filter_students_to' do
let(:edd) { EffectiveDueDates.for_course(@test_course) }
it 'defaults to no filtered students' do
expect(edd.filtered_students).to be_nil
end
it 'saves an array of students' do
user1, user2 = User.create, User.create
edd.filter_students_to([user1, user2])
expect(edd.filtered_students).to eq [user1.id, user2.id]
end
it 'saves a list of students' do
user1, user2 = User.create, User.create
edd.filter_students_to(user1, user2)
expect(edd.filtered_students).to eq [user1.id, user2.id]
end
it 'saves a list of student ids' do
edd.filter_students_to(15, 20, 2)
expect(edd.filtered_students).to eq [15, 20, 2]
end
it 'does nothing if no students are passed' do
edd.filter_students_to
expect(edd.filtered_students).to be_nil
end
it 'allows chaining' do
expect(edd.filter_students_to(5)).to eq edd
end
end
describe '#to_hash' do
before(:once) do
@now = Time.zone.now.change(sec: 0)
@student1_enrollment = student_in_course(course: @test_course, active_all: true)
@student1 = @student1_enrollment.user
@student2 = student_in_course(course: @test_course, active_all: true).user
@student3 = student_in_course(course: @test_course, active_all: true).user
@other_course = Course.create!
@student_in_other_course = student_in_course(course: @other_course, active_all: true).user
@assignment1 = @test_course.assignments.create!(due_at: 2.weeks.from_now(@now))
@assignment2 = @test_course.assignments.create!
@assignment3 = @test_course.assignments.create!
@deleted_assignment = @test_course.assignments.create!
@deleted_assignment.destroy
@assignment_in_other_course = @other_course.assignments.create!
end
it 'properly converts timezones' do
Time.zone = 'Alaska'
default_due = DateTime.parse("01 Jan 2011 14:00 AKST")
@assignment4 = @test_course.assignments.create!(title: "some assignment", due_at: default_due, submission_types: ['online_text_entry'])
edd = EffectiveDueDates.for_course(@test_course, @assignment4)
result = edd.to_hash
expect(result[@assignment4.id][@student1.id][:due_at]).to eq default_due
end
it 'returns the effective due dates per assignment per student' do
edd = EffectiveDueDates.for_course(@test_course)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 2.weeks.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 2.weeks.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 2.weeks.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
},
@assignment2.id => {
@student1.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
},
@assignment3.id => {
@student1.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'returns the effective due dates per assignment for select students when filtered' do
edd = EffectiveDueDates.for_course(@test_course).filter_students_to(@student1, @student3)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 2.weeks.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 2.weeks.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
},
@assignment2.id => {
@student1.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
},
@assignment3.id => {
@student1.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'maps id if the assignments are already loaded' do
args = @test_course.active_assignments.to_a
expect(args[0]).to receive(:id).once
expect(args[1]).to receive(:id).once
expect(args[2]).to receive(:id).once
edd = EffectiveDueDates.for_course(@test_course, args)
edd.to_hash
end
it 'uses sql if the assignments are still a relation' do
args = @test_course.active_assignments
expect_any_instance_of(Assignment).to receive(:id).never
edd = EffectiveDueDates.for_course(@test_course, args)
edd.to_hash
end
it 'memoizes the result' do
args = @test_course.active_assignments.to_a
expect(args[0]).to receive(:id).once
expect(args[1]).to receive(:id).once
expect(args[2]).to receive(:id).once
edd = EffectiveDueDates.for_course(@test_course, args)
2.times { edd.to_hash }
end
it 'can be passed a list of keys to only return those attributes' do
due_dates = EffectiveDueDates.for_course(@test_course)
due_dates_hash = due_dates.to_hash([:due_at, :override_source])
attributes_returned = due_dates_hash[@assignment1.id][@student1.id].keys
expect(attributes_returned).to contain_exactly(:due_at, :override_source)
end
describe 'initializes with' do
it 'no arguments and defaults to all active course assignments' do
edd = EffectiveDueDates.for_course(@test_course)
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment1.id, @assignment2.id, @assignment3.id)
end
it 'a list of ActiveRecord Assignment models' do
edd = EffectiveDueDates.for_course(@test_course, @assignment1, @assignment3)
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment3.id, @assignment1.id)
end
it 'an array of ActiveRecord Assignment models' do
edd = EffectiveDueDates.for_course(@test_course, [@assignment1, @assignment3])
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment3.id, @assignment1.id)
end
it 'a list of ids' do
edd = EffectiveDueDates.for_course(@test_course, @assignment1.id, @assignment3.id)
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment3.id, @assignment1.id)
end
it 'an array of ids' do
edd = EffectiveDueDates.for_course(@test_course, [@assignment1.id, @assignment3.id])
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment3.id, @assignment1.id)
end
it 'a single ActiveRecord relation' do
edd = EffectiveDueDates.for_course(@test_course, @test_course.assignments)
result = edd.to_hash
expect(result.keys).to contain_exactly(@assignment3.id, @assignment2.id, @assignment1.id)
end
it 'nil' do
edd = EffectiveDueDates.for_course(@test_course, nil)
result = edd.to_hash
expect(result).to be_empty
end
it 'new Assignment objects that do not have an ID' do
new_assignment = @test_course.assignments.build
edd = EffectiveDueDates.for_course(@test_course, new_assignment)
result = edd.to_hash
expect(result).to be_empty
end
end
it 'ignores students who are not in the course' do
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
student_ids = result[@assignment1.id].keys
expect(student_ids).not_to include @student_in_other_course.id
end
it 'ignores assignments that are not in this course' do
edd = EffectiveDueDates.for_course(@test_course, @assignment_in_other_course)
result = edd.to_hash
expect(result).to be_empty
end
it 'ignores assignments that are soft-deleted' do
edd = EffectiveDueDates.for_course(@test_course, @deleted_assignment)
result = edd.to_hash
expect(result).to be_empty
end
it 'ignores enrollments that rejected the course invitation' do
@student1_enrollment.reject
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
student_ids = edd.to_hash[@assignment1.id].keys
expect(student_ids).not_to include @student1.id
end
it 'includes deactivated enrollments' do
@student1_enrollment.deactivate
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
student_ids = edd.to_hash[@assignment1.id].keys
expect(student_ids).to include @student1.id
end
it 'includes concluded enrollments' do
@student1_enrollment.conclude
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
student_ids = edd.to_hash[@assignment1.id].keys
expect(student_ids).to include @student1.id
end
it 'ignores enrollments that are not students' do
@student1_enrollment.type = 'TeacherEnrollment'
@student1_enrollment.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
student_ids = result[@assignment1.id].keys
expect(student_ids).not_to include @student1.id
end
it 'ignores soft deleted students' do
@student1_enrollment.destroy
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
student_ids = result[@assignment1.id].keys
expect(student_ids).not_to include @student1.id
end
context 'when only visible to overrides' do
before(:once) do
@assignment1.only_visible_to_overrides = true
@assignment1.save!
end
it 'ignores inactive overrides' do
override = @assignment1.assignment_overrides.create!(due_at: 5.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
override.destroy!
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'ignores noop overrides' do
@assignment1.assignment_overrides.create!(set_type: 'Noop')
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'includes overrides with null due dates' do
override = @assignment1.assignment_overrides.create!(due_at: nil, due_at_overridden: true)
override.assignment_override_students.create!(user: @student3)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student3.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'includes overrides without due_at_overridden, and uses the due_at from the assignment' do
override = @assignment1.assignment_overrides.create!(due_at: nil)
override.assignment_override_students.create!(user: @student3)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash[@assignment1.id][@student3.id][:due_at]).to eq(@assignment1.due_at)
end
it 'uses the due_at from the assignment when the assignment is only visible to overrides and no overrides for the student have due_at_overridden' do
@assignment1.update!(due_at: @now)
override = @assignment1.assignment_overrides.create!(due_at: 2.days.from_now(@now))
override.assignment_override_students.create!(user: @student3)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash[@assignment1.id][@student3.id][:due_at]).to eq(@now)
end
it 'uses the due_at from the assignment when the assignment is visible to everyone and no overrides for the student have due_at_overridden' do
@assignment1.update!(only_visible_to_overrides: false, due_at: @now)
override = @assignment1.assignment_overrides.create!(due_at: 2.days.from_now(@now))
override.assignment_override_students.create!(user: @student3)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash[@assignment1.id][@student3.id][:due_at]).to eq(@now)
end
it 'does not consider the due_at from overrides without due_at_overridden when the override due_at is nil' do
override = @assignment1.assignment_overrides.create!(due_at: nil)
override.assignment_override_students.create!(user: @student3)
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
student_in_section(section, user: @student3)
section_override = @assignment1.assignment_overrides.create!(
due_at: 1.day.from_now(@now),
due_at_overridden: true,
set: section
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash[@assignment1.id][@student3.id][:due_at]).to eq(1.day.from_now(@now))
end
it 'does not consider the due_at from overrides without due_at_overridden even if the due date is more lenient than other dates' do
override = @assignment1.assignment_overrides.create!(due_at: 2.days.from_now(@now))
override.assignment_override_students.create!(user: @student3)
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
student_in_section(section, user: @student3)
section_override = @assignment1.assignment_overrides.create!(
due_at: 1.day.from_now(@now),
due_at_overridden: true,
set: section
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash[@assignment1.id][@student3.id][:due_at]).to eq(1.day.from_now(@now))
end
it 'applies adhoc overrides' do
override = @assignment1.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 3.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'ignores soft-deleted adhoc overrides' do
override = @assignment1.assignment_overrides.create!(due_at: 7.days.from_now(@now), due_at_overridden: true)
override_student = override.assignment_override_students.create!(user: @student1)
override_student.update!(workflow_state: 'deleted')
override = @assignment1.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 3.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq(expected)
end
it 'correctly matches adhoc overrides for different assignments' do
@assignment2.only_visible_to_overrides = true
@assignment2.save!
override2 = @assignment2.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override2.assignment_override_students.create!(user: @student1)
override1 = @assignment1.assignment_overrides.create!(due_at: 7.days.from_now(@now), due_at_overridden: true)
override1.assignment_override_students.create!(user: @student1)
edd = EffectiveDueDates.for_course(@test_course, @assignment1, @assignment2)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 7.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override1.id,
override_source: 'ADHOC'
}
},
@assignment2.id => {
@student1.id => {
due_at: 3.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override2.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'correctly matches adhoc overrides for different students' do
override1 = @assignment1.assignment_overrides.create!(due_at: 7.days.from_now(@now), due_at_overridden: true)
override1.assignment_override_students.create!(user: @student1)
override2 = @assignment1.assignment_overrides.create!(due_at: 1.day.from_now(@now), due_at_overridden: true)
override2.assignment_override_students.create!(user: @student2)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 7.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override1.id,
override_source: 'ADHOC'
},
@student2.id => {
due_at: 1.day.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override2.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'applies group overrides' do
group_with_user(user: @student3, active_all: true)
@group.users << @student2
override = @assignment1.assignment_overrides.create!(
due_at: 4.days.from_now(@now),
due_at_overridden: true,
set: @group
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'Group'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'Group'
}
}
}
expect(result).to eq expected
end
it 'ignores overrides for soft-deleted groups' do
group_with_user(user: @student3, active_all: true)
@assignment1.assignment_overrides.create!(due_at: 4.days.from_now(@now), due_at_overridden: true, set: @group)
@group.destroy!
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'only applies group overrides to students that have accepted the group invitation' do
group
@group.add_user(@student1, 'rejected')
@assignment1.assignment_overrides.create!(due_at: 4.days.from_now(@now), due_at_overridden: true, set: @group)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'applies section overrides' do
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
student_in_section(section, user: @student2)
student_in_section(section, user: @student1)
override = @assignment1.assignment_overrides.create!(
due_at: 1.day.from_now(@now),
due_at_overridden: true,
set: section
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 1.day.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'CourseSection'
},
@student2.id => {
due_at: 1.day.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'CourseSection'
}
}
}
expect(result).to eq expected
end
it 'ignores section overrides for TAs' do
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
ta_in_section(section, user: @student2)
@assignment1.assignment_overrides.create!(due_at: 1.day.from_now(@now), due_at_overridden: true, set: section)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'ignores overrides for soft-deleted sections' do
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
student_in_section(section, user: @student2)
@assignment1.assignment_overrides.create!(due_at: 1.day.from_now(@now), due_at_overridden: true, set: section)
section.destroy!
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'ignores not-assigned students with existing graded submissions' do
@assignment1.grade_student(@student1, grade: 5, grader: @teacher)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expect(result).to be_empty
end
it 'uses assigned date instead of submission date even if submission was late' do
override = @assignment1.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
@assignment1.grade_student(@student1, grade: 5, grader: @teacher)
@assignment1.submissions.find_by!(user: @student1).update!(
submitted_at: 1.week.from_now(@now),
submission_type: 'online_text_entry'
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
result = edd.to_hash
expected = {
@assignment1.id => {
@student1.id => {
due_at: 3.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'prioritizes the override due date if it exists over the Everyone Else date' do
override = @assignment2.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 3.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
# this might look like a strange test to have, but it is a result of how we are joining different tables in sql.
it 'prioritizes the override due date even if it is earlier than the Everyone Else date and the student has a graded submission that does not qualify' do
override = @assignment2.assignment_overrides.create!(due_at: 3.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
@assignment2.grade_student(@student1, grade: 5, grader: @teacher)
@assignment2.submissions.find_by!(user: @student1).update!(
submitted_at: 1.week.from_now(@now),
submission_type: 'online_text_entry'
)
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 3.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'prioritizes the Everyone Else due date if it exists over the submission NULL date' do
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
@assignment2.grade_student(@student1, grade: 5, grader: @teacher)
@assignment2.submissions.find_by!(user: @student1).update!(
submitted_at: 1.week.from_now(@now),
submission_type: 'online_text_entry'
)
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'ignores not-assigned students with ungraded submissions' do
@assignment1.all_submissions.find_by!(user: @student1).update!(
submission_type: 'online_text_entry',
workflow_state: 'submitted'
)
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
end
it 'picks the due date that gives the student the most amount of time to submit' do
# adhoc
override = @assignment2.assignment_overrides.create!(due_at: 3.days.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
# group
group_with_user(user: @student1, active_all: true)
group_override = @assignment2.assignment_overrides.create!(
due_at: 6.days.from_now(@now),
due_at_overridden: true,
set: @group
)
# everyone else
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 6.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: group_override.id,
override_source: 'Group'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'treats null due dates as the most permissive due date for a student' do
# adhoc
override = @assignment2.assignment_overrides.create!(due_at: nil, due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
# group
group_with_user(user: @student1, active_all: true)
@assignment2.assignment_overrides.create!(due_at: 6.days.from_now(@now), due_at_overridden: true, set: @group)
# everyone else
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: nil,
grading_period_id: nil,
in_closed_grading_period: false,
override_id: override.id,
override_source: 'ADHOC'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'returns all students in the course if the assignment is assigned to everybody' do
@assignment2.due_at = 4.days.from_now(@now)
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 4.days.from_now(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
context 'with grading periods' do
before(:once) do
@gp_group = Factories::GradingPeriodGroupHelper.new.create_for_account(@test_course.account)
@gp_group.enrollment_terms << @test_course.enrollment_term
end
it 'uses account grading periods if no course grading periods exist' do
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'uses only course grading periods if any exist (legacy)' do
Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
legacy_group = Factories::GradingPeriodGroupHelper.new.legacy_create_for_course(@test_course)
gp = Factories::GradingPeriodHelper.new.create_for_group(legacy_group, {
start_date: 10.days.ago(@now),
end_date: 5.days.ago(@now),
close_date: 1.day.ago(@now)
})
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
override = @assignment2.assignment_overrides.create!(due_at: 7.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 7.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: override.id,
override_source: 'ADHOC'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'ignores account grading periods for unrelated enrollment terms' do
gp_group = Factories::GradingPeriodGroupHelper.new.create_for_account_with_term(@test_course.account, 'Term')
Factories::GradingPeriodHelper.new.create_for_group(gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'uses the effective due date to find a closed grading period' do
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = 1.day.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
override = @assignment2.assignment_overrides.create!(due_at: 19.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student3)
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 1.day.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 1.day.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 19.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: override.id,
override_source: 'ADHOC'
}
}
}
expect(result).to eq expected
end
it 'truncates seconds when comparing override due dates to grading period dates' do
end_date = 15.days.ago(@now)
grading_period = Factories::GradingPeriodHelper.new.create_for_group(
@gp_group,
start_date: 20.days.ago(@now),
end_date: end_date,
close_date: 10.days.ago(@now)
)
override = @assignment2.assignment_overrides.create!(
due_at: 59.seconds.from_now(end_date),
due_at_overridden: true
)
override.assignment_override_students.create!(user: @student3)
effective_due_dates = EffectiveDueDates.for_course(@test_course, @assignment2).to_hash
submission_grading_period_id = effective_due_dates[@assignment2.id][@student3.id][:grading_period_id]
expect(submission_grading_period_id).to eq grading_period.id
end
it 'ignores soft-deleted grading period groups' do
Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@gp_group.destroy!
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'ignores soft-deleted grading periods' do
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
gp.destroy!
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
describe 'in_closed_grading_period attribute' do
it 'is true if the associated grading period is closed' do
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'is false if the associated grading period is open' do
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 4.days.from_now(@now)
})
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 17.days.ago(@now),
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'is false if the due date does not fall in a grading period' do
Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = 12.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: 12.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: 12.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: 12.days.ago(@now),
grading_period_id: nil,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'is true if the due date is null and the last grading period is closed' do
Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 50.days.ago(@now),
end_date: 35.days.ago(@now),
close_date: 30.days.from_now(@now)
})
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
})
@assignment2.due_at = nil
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: true,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
it 'is false if the due date is null and the last grading period is open' do
Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 50.days.ago(@now),
end_date: 35.days.ago(@now),
close_date: 30.days.ago(@now)
})
gp = Factories::GradingPeriodHelper.new.create_for_group(@gp_group, {
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.from_now(@now)
})
@assignment2.due_at = nil
@assignment2.only_visible_to_overrides = false
@assignment2.save!
edd = EffectiveDueDates.for_course(@test_course, @assignment2)
result = edd.to_hash
expected = {
@assignment2.id => {
@student1.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student2.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
},
@student3.id => {
due_at: nil,
grading_period_id: gp.id,
in_closed_grading_period: false,
override_id: nil,
override_source: 'Everyone Else'
}
}
}
expect(result).to eq expected
end
end
end
end
end
context 'grading periods' do
before(:once) do
@now = Time.zone.now.change(sec: 0)
@test_course = Course.create!
@student1 = student_in_course(course: @test_course, active_all: true).user
@student2 = student_in_course(course: @test_course, active_all: true).user
@gp_group = Factories::GradingPeriodGroupHelper.new.create_for_account(@test_course.account)
@gp_group.enrollment_terms << @test_course.enrollment_term
@grading_period = Factories::GradingPeriodHelper.new.create_for_group(
@gp_group,
start_date: 20.days.ago(@now),
end_date: 15.days.ago(@now),
close_date: 10.days.ago(@now)
)
@assignment1 = @test_course.assignments.create!(due_at: 2.weeks.from_now(@now))
@assignment2 = @test_course.assignments.create!
end
describe '#any_in_closed_grading_period?' do
it 'returns false if there are no grading periods' do
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
expect(@test_course).to receive(:grading_periods?).and_return false
edd = EffectiveDueDates.for_course(@test_course)
expect(edd).to receive(:to_hash).never
expect(edd.any_in_closed_grading_period?).to eq(false)
end
context 'with grading periods' do
it 'returns true if any students in any assignments have a due date in a closed grading period' do
@assignment2.due_at = 1.day.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
override = @assignment2.assignment_overrides.create!(due_at: 19.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
edd = EffectiveDueDates.for_course(@test_course)
expect(edd.any_in_closed_grading_period?).to eq(true)
end
it 'returns false if no student in any assignments has a due date in a closed grading period' do
@assignment2.due_at = 1.day.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
override = @assignment2.assignment_overrides.create!(due_at: 2.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
edd = EffectiveDueDates.for_course(@test_course)
expect(edd.any_in_closed_grading_period?).to eq(false)
end
it 'memoizes the result' do
edd = EffectiveDueDates.for_course(@test_course)
expect(edd).to receive(:to_hash).once.and_return({})
2.times { edd.any_in_closed_grading_period? }
end
end
end
describe '#grading_period_id_for' do
it 'returns the grading_period_id for the given student and assignment' do
@assignment1.update!(due_at: 2.days.from_now(@grading_period.start_date))
effective_due_dates = EffectiveDueDates.new(@test_course, @assignment1.id)
grading_period_id = effective_due_dates.grading_period_id_for(
student_id: @student1.id,
assignment_id: @assignment1.id
)
expect(grading_period_id).to eq(@grading_period.id)
end
it 'returns nil if there if the given student and assignment do not fall in a grading period' do
effective_due_dates = EffectiveDueDates.new(@test_course, @assignment1.id)
grading_period_id = effective_due_dates.grading_period_id_for(
student_id: @student1.id,
assignment_id: @assignment1.id
)
expect(grading_period_id).to be_nil
end
it 'returns nil if the assignment is not assigned to the student' do
@assignment1.update!(
due_at: 2.days.from_now(@grading_period.start_date),
only_visible_to_overrides: true
)
effective_due_dates = EffectiveDueDates.new(@test_course, @assignment1.id)
grading_period_id = effective_due_dates.grading_period_id_for(
student_id: @student1.id,
assignment_id: @assignment1.id
)
expect(grading_period_id).to be_nil
end
end
describe '#in_closed_grading_period?' do
it 'returns false if there are no grading periods' do
@assignment2.due_at = 17.days.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
expect(@test_course).to receive(:grading_periods?).and_return false
edd = EffectiveDueDates.for_course(@test_course)
expect(edd).to receive(:to_hash).never
expect(edd.in_closed_grading_period?(@assignment2)).to eq(false)
end
it 'returns false if assignment id is nil' do
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd).to receive(:to_hash).never
expect(edd.in_closed_grading_period?(nil)).to eq(false)
end
context 'with grading periods' do
before do
@assignment2.due_at = 1.day.ago(@now)
@assignment2.only_visible_to_overrides = false
@assignment2.save!
override = @assignment2.assignment_overrides.create!(due_at: 19.days.ago(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
@edd = EffectiveDueDates.for_course(@test_course)
end
it 'returns true if any students in the given assignment have a due date in a closed grading period' do
expect(@edd.in_closed_grading_period?(@assignment2)).to eq(true)
end
it 'accepts assignment id as the argument' do
expect(@edd.in_closed_grading_period?(@assignment2.id)).to eq(true)
end
it 'returns false if no student in the given assignment has a due date in a closed grading period' do
expect(@edd.in_closed_grading_period?(@assignment1)).to eq(false)
end
it 'returns true if the specified student has a due date for this assignment' do
expect(@edd.in_closed_grading_period?(@assignment2, @student2)).to be true
expect(@edd.in_closed_grading_period?(@assignment2, @student2.id)).to be true
end
it 'raises error if the specified student was filtered out of the query' do
expect { @edd.filter_students_to(@student1).in_closed_grading_period?(@assignment2, @student2) }.
to raise_error("Student #{@student2.id} was not included in this query")
end
it 'returns true if the specified student was included in the query and has a due date for this assignment' do
expect(@edd.filter_students_to(@student2).in_closed_grading_period?(@assignment2, @student2)).to be true
end
it 'returns false if the specified student has a due date in an open grading period' do
override = @assignment2.assignment_overrides.create!(due_at: 1.day.from_now(@now), due_at_overridden: true)
override.assignment_override_students.create!(user: @student1)
expect(@edd.in_closed_grading_period?(@assignment2, @student1)).to be false
expect(@edd.in_closed_grading_period?(@assignment2, @student1.id)).to be false
end
it 'returns false if the specified student does not have a due date for this assignment' do
@other_course = Course.create!
@student_in_other_course = student_in_course(course: @other_course, active_all: true).user
expect(@edd.in_closed_grading_period?(@assignment2, @student_in_other_course)).to be false
expect(@edd.in_closed_grading_period?(@assignment2, @student_in_other_course.id)).to be false
end
end
end
end
end