2020-10-27 00:51:19 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-04-28 12:12:06 +08:00
|
|
|
#
|
|
|
|
# Copyright (C) 2014 - 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/>.
|
|
|
|
|
2024-01-11 07:57:56 +08:00
|
|
|
require_relative "student_visibility/student_visibility_common"
|
2024-05-24 03:03:25 +08:00
|
|
|
require_relative "../helpers/selective_release_common"
|
2024-01-11 07:57:56 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
describe "differentiated_assignments" do
|
2024-01-11 07:57:56 +08:00
|
|
|
include StudentVisibilityCommon
|
2024-05-24 03:03:25 +08:00
|
|
|
include SelectiveReleaseCommon
|
2024-01-11 07:57:56 +08:00
|
|
|
|
2016-02-26 23:44:19 +08:00
|
|
|
def course_with_differentiated_assignments_enabled
|
2014-08-23 03:13:56 +08:00
|
|
|
@course = Course.create!
|
|
|
|
@user = user_model
|
|
|
|
@course.enroll_user(@user)
|
|
|
|
@course.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
def make_quiz(opts = {})
|
|
|
|
@quiz = Quizzes::Quiz.create!({
|
|
|
|
context: @course,
|
|
|
|
description: "descript foo",
|
|
|
|
only_visible_to_overrides: opts[:ovto],
|
|
|
|
points_possible: rand(1000),
|
|
|
|
title: "I am a quiz"
|
|
|
|
})
|
|
|
|
@quiz.publish
|
|
|
|
@quiz.save!
|
|
|
|
@assignment = @quiz.assignment
|
|
|
|
end
|
|
|
|
|
|
|
|
def quiz_with_true_only_visible_to_overrides
|
|
|
|
make_quiz({ date: nil, ovto: true })
|
|
|
|
end
|
|
|
|
|
|
|
|
def quiz_with_false_only_visible_to_overrides
|
|
|
|
make_quiz({ date: Time.now, ovto: false })
|
|
|
|
end
|
|
|
|
|
2015-02-07 01:32:18 +08:00
|
|
|
def student_in_course_with_adhoc_override(quiz, opts = {})
|
|
|
|
@user = opts[:user] || user_model
|
|
|
|
StudentEnrollment.create!(user: @user, course: @course)
|
|
|
|
ao = AssignmentOverride.new
|
|
|
|
ao.quiz = quiz
|
|
|
|
ao.title = "ADHOC OVERRIDE"
|
|
|
|
ao.workflow_state = "active"
|
|
|
|
ao.set_type = "ADHOC"
|
2023-11-17 05:45:43 +08:00
|
|
|
ao.unassign_item = opts[:unassign_item] || "false"
|
2015-02-07 01:32:18 +08:00
|
|
|
ao.save!
|
|
|
|
override_student = ao.assignment_override_students.build
|
|
|
|
override_student.user = @user
|
|
|
|
override_student.save!
|
2015-07-10 03:29:44 +08:00
|
|
|
quiz.reload
|
2015-02-07 01:32:18 +08:00
|
|
|
@user
|
|
|
|
end
|
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
def enroller_user_in_section(section, opts = {})
|
|
|
|
@user = opts[:user] || user_model
|
|
|
|
StudentEnrollment.create!(user: @user, course: @course, course_section: section)
|
|
|
|
end
|
|
|
|
|
|
|
|
def enroller_user_in_both_sections
|
|
|
|
@user = user_model
|
|
|
|
StudentEnrollment.create!(user: @user, course: @course, course_section: @section_foo)
|
|
|
|
StudentEnrollment.create!(user: @user, course: @course, course_section: @section_bar)
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_multiple_sections
|
|
|
|
@default_section = @course.default_section
|
|
|
|
@section_foo = @course.course_sections.create!(name: "foo")
|
|
|
|
@section_bar = @course.course_sections.create!(name: "bar")
|
|
|
|
end
|
|
|
|
|
2021-11-16 06:05:02 +08:00
|
|
|
def create_override_for_quiz(quiz)
|
2014-08-23 03:13:56 +08:00
|
|
|
ao = AssignmentOverride.new
|
|
|
|
ao.quiz = quiz
|
|
|
|
ao.title = "Lorem"
|
|
|
|
ao.workflow_state = "active"
|
2021-11-16 06:05:02 +08:00
|
|
|
yield(ao)
|
2014-08-23 03:13:56 +08:00
|
|
|
ao.save!
|
2015-07-10 03:29:44 +08:00
|
|
|
quiz.reload
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
|
2023-11-17 05:45:43 +08:00
|
|
|
def give_section_foo_due_date(quiz, opts = {})
|
2014-08-23 03:13:56 +08:00
|
|
|
create_override_for_quiz(quiz) do |ao|
|
|
|
|
ao.set = @section_foo
|
|
|
|
ao.due_at = 3.weeks.from_now
|
2023-11-17 05:45:43 +08:00
|
|
|
ao.unassign_item = opts[:unassign_item] || "false"
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-11-03 21:21:55 +08:00
|
|
|
def give_course_due_date(quiz)
|
|
|
|
create_override_for_quiz(quiz) do |ao|
|
|
|
|
ao.set = @course
|
|
|
|
ao.due_at = 3.weeks.from_now
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
def ensure_user_does_not_see_quiz
|
2015-07-10 01:15:52 +08:00
|
|
|
visible_quiz_ids = Quizzes::QuizStudentVisibility.where(user_id: @user.id, course_id: @course.id).pluck(:quiz_id)
|
|
|
|
expect(visible_quiz_ids.map(&:to_i).include?(@quiz.id)).to be_falsey
|
2014-10-21 22:05:41 +08:00
|
|
|
expect(Quizzes::QuizStudentVisibility.visible_quiz_ids_in_course_by_user(user_id: [@user.id], course_id: [@course.id])[@user.id]).not_to include(@quiz.id)
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def ensure_user_sees_quiz
|
2015-07-10 01:15:52 +08:00
|
|
|
visible_quiz_ids = Quizzes::QuizStudentVisibility.where(user_id: @user.id, course_id: @course.id).pluck(:quiz_id)
|
|
|
|
expect(visible_quiz_ids.map(&:to_i).include?(@quiz.id)).to be_truthy
|
2014-10-21 22:05:41 +08:00
|
|
|
expect(Quizzes::QuizStudentVisibility.visible_quiz_ids_in_course_by_user(user_id: [@user.id], course_id: [@course.id])[@user.id]).to include(@quiz.id)
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
context "table" do
|
|
|
|
before do
|
|
|
|
course_with_differentiated_assignments_enabled
|
|
|
|
add_multiple_sections
|
|
|
|
quiz_with_true_only_visible_to_overrides
|
|
|
|
give_section_foo_due_date(@quiz)
|
|
|
|
enroller_user_in_section(@section_foo)
|
|
|
|
end
|
|
|
|
|
2024-01-11 07:57:56 +08:00
|
|
|
let(:visibility_object) { Quizzes::QuizStudentVisibility.first }
|
2014-08-23 03:13:56 +08:00
|
|
|
|
2024-01-11 07:57:56 +08:00
|
|
|
it_behaves_like "student visibility models"
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
context "course_with_differentiated_assignments_enabled" do
|
|
|
|
before do
|
2024-05-24 03:03:25 +08:00
|
|
|
differentiated_modules_off
|
2014-08-23 03:13:56 +08:00
|
|
|
course_with_differentiated_assignments_enabled
|
|
|
|
add_multiple_sections
|
|
|
|
end
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2015-07-10 01:15:52 +08:00
|
|
|
context "quiz only visible to overrides" do
|
2014-08-23 03:13:56 +08:00
|
|
|
before do
|
|
|
|
quiz_with_true_only_visible_to_overrides
|
|
|
|
give_section_foo_due_date(@quiz)
|
|
|
|
end
|
|
|
|
|
2015-02-07 01:32:18 +08:00
|
|
|
context "ADHOC overrides" do
|
|
|
|
before { quiz_with_true_only_visible_to_overrides }
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "returns a visibility for a student with an ADHOC override" do
|
2015-02-07 01:32:18 +08:00
|
|
|
student_in_course_with_adhoc_override(@quiz)
|
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "works with course section and return a single visibility" do
|
2015-02-07 01:32:18 +08:00
|
|
|
student_in_course_with_adhoc_override(@quiz)
|
|
|
|
give_section_foo_due_date(@quiz)
|
|
|
|
enroller_user_in_section(@section_foo)
|
|
|
|
ensure_user_sees_quiz
|
|
|
|
expect(Quizzes::QuizStudentVisibility.where(user_id: @user.id, course_id: @course.id, quiz_id: @quiz.id).count).to eq 1
|
|
|
|
end
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "does not return a visibility for a student without an ADHOC override" do
|
2015-02-07 01:32:18 +08:00
|
|
|
@user = user_model
|
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "does not return a visibility if ADHOC override is deleted" do
|
2015-02-07 01:32:18 +08:00
|
|
|
student_in_course_with_adhoc_override(@quiz)
|
2015-07-25 00:01:44 +08:00
|
|
|
@quiz.assignment_overrides.to_a.each(&:destroy)
|
2015-02-07 01:32:18 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with override who then changes sections" do
|
2016-11-15 05:36:56 +08:00
|
|
|
before do
|
|
|
|
enroller_user_in_section(@section_foo)
|
|
|
|
@student = @user
|
|
|
|
teacher_in_course(course: @course)
|
|
|
|
end
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "does not keep the quiz visible even if there is a grade" do
|
2016-11-15 05:36:56 +08:00
|
|
|
@quiz.assignment.grade_student(@student, grade: 10, grader: @teacher)
|
2017-10-05 02:34:31 +08:00
|
|
|
Score.where(enrollment_id: @student.enrollments).each(&:destroy_permanently!)
|
2016-11-15 05:36:56 +08:00
|
|
|
@student.enrollments.each(&:destroy_permanently!)
|
|
|
|
enroller_user_in_section(@section_bar, { user: @student })
|
2017-08-15 06:35:38 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "does not keep the quiz visible if there is no score, even if it has a grade" do
|
2016-11-15 05:36:56 +08:00
|
|
|
@quiz.assignment.grade_student(@student, grade: 10, grader: @teacher)
|
2014-09-25 00:02:14 +08:00
|
|
|
@quiz.assignment.submissions.last.update_attribute("score", nil)
|
|
|
|
@quiz.assignment.submissions.last.update_attribute("grade", 10)
|
2017-10-05 02:34:31 +08:00
|
|
|
Score.where(enrollment_id: @student.enrollments).each(&:destroy_permanently!)
|
2016-11-15 05:36:56 +08:00
|
|
|
@student.enrollments.each(&:destroy_permanently!)
|
|
|
|
enroller_user_in_section(@section_bar, { user: @student })
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "does not keep the quiz visible even if the grade is zero" do
|
2016-11-15 05:36:56 +08:00
|
|
|
@quiz.assignment.grade_student(@student, grade: 0, grader: @teacher)
|
2017-10-05 02:34:31 +08:00
|
|
|
Score.where(enrollment_id: @student.enrollments).each(&:destroy_permanently!)
|
2016-11-15 05:36:56 +08:00
|
|
|
@student.enrollments.each(&:destroy_permanently!)
|
|
|
|
enroller_user_in_section(@section_bar, { user: @student })
|
2017-08-15 06:35:38 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
2014-08-23 03:13:56 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "user in default section" do
|
2021-09-23 22:17:23 +08:00
|
|
|
it "hides the quiz from the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with override" do
|
|
|
|
before { enroller_user_in_section(@section_foo) }
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
2021-11-10 06:40:34 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "updates when enrollments change" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
enrollments = StudentEnrollment.where(user_id: @user.id, course_id: @course.id, course_section_id: @section_foo.id)
|
2017-10-05 02:34:31 +08:00
|
|
|
Score.where(enrollment_id: enrollments).each(&:destroy_permanently!)
|
2016-01-06 02:31:25 +08:00
|
|
|
enrollments.each(&:destroy_permanently!)
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
2021-11-10 06:40:34 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "updates when the override is deleted" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
2017-08-15 06:35:38 +08:00
|
|
|
@quiz.assignment_overrides.to_a.each(&:destroy!)
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with no override" do
|
|
|
|
before { enroller_user_in_section(@section_bar) }
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "hides the quiz from the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_does_not_see_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with override and one without override" do
|
|
|
|
before do
|
|
|
|
enroller_user_in_both_sections
|
|
|
|
end
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "quiz with false only_visible_to_overrides" do
|
|
|
|
before do
|
|
|
|
quiz_with_false_only_visible_to_overrides
|
|
|
|
give_section_foo_due_date(@quiz)
|
|
|
|
end
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in default section" do
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with override" do
|
|
|
|
before { enroller_user_in_section(@section_foo) }
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with no override" do
|
|
|
|
before { enroller_user_in_section(@section_bar) }
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
end
|
2021-11-18 09:59:30 +08:00
|
|
|
|
2014-08-23 03:13:56 +08:00
|
|
|
context "user in section with override and one without override" do
|
|
|
|
before do
|
|
|
|
enroller_user_in_both_sections
|
|
|
|
end
|
2021-11-10 07:34:38 +08:00
|
|
|
|
2021-09-23 22:17:23 +08:00
|
|
|
it "shows the quiz to the user" do
|
2014-08-23 03:13:56 +08:00
|
|
|
ensure_user_sees_quiz
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2014-10-21 22:05:41 +08:00
|
|
|
end
|