stop deleting submissions upon deactivation

closes EVAL-1298
flag=visible_assignments_scope_change

Test Plan:
1. Enable the visible_assignments_scope_change site admin flag.
2. Create an assignment assigned to a section.
3. As a teacher, deactivate the enrollment of a student in that
   section.
4. Verify the submission for the deactivated student is NOT
   soft-deleted:

   Submission.find_by(assignment_id: <id>, user_id: <id>)
   	.workflow_state # should not be 'deleted'

5. As the student, verify you are not permitted to view the assignment
   page in the UI.
6. As the student, verify the assignments_api_controller#index API
   endpoint does not return the assignment.
7. Re-activate the students deactivated enrollment.
8. As the student, verify you are now permitted to view the assignment
   page in the UI.
9. As the student, verify the assignments_api_controller#index API
   endpoint now returns the assignment.

Change-Id: I300de4bd0999edf55fca5384bb1c56f73e1bec93
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/272227
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Kai Bjorkman <kbjorkman@instructure.com>
QA-Review: Spencer Olson <solson@instructure.com>
Product-Review: Spencer Olson <solson@instructure.com>
This commit is contained in:
Spencer Olson 2021-08-25 10:21:25 -05:00
parent 4da3b36ec1
commit 432f3cde03
7 changed files with 102 additions and 8 deletions

View File

@ -2852,9 +2852,13 @@ class Assignment < ActiveRecord::Base
scope :for_course, lambda { |course_id| where(:context_type => 'Course', :context_id => course_id) }
scope :for_group_category, lambda { |group_category_id| where(:group_category_id => group_category_id) }
scope :visible_to_students_in_course_with_da, lambda { |user_id, _|
joins(:submissions)
.where(submissions: { :user_id => user_id })
scope :visible_to_students_in_course_with_da, lambda { |user_id, course_id|
if Account.site_admin.feature_enabled?(:visible_assignments_scope_change)
joins(:assignment_student_visibilities)
.where(assignment_student_visibilities: { user_id: user_id, course_id: course_id })
else
joins(:submissions).where(submissions: { user_id: user_id })
end
}
# course_ids should be courses that restrict visibility based on overrides

View File

@ -108,3 +108,8 @@ gradebook_assignment_search_and_redesign:
display_name: Gradebook Assignment Search And Redesign
description: Search assignments in Gradebook and new design for assignment
and student search
visible_assignments_scope_change:
state: hidden
applies_to: SiteAdmin
display_name: Visible Assignments Scope Change
description: Reverts the visible assignments scope to its original form

View File

@ -150,6 +150,14 @@ class EffectiveDueDates
end
end
def filter_section_assigned_enrollments_sql
if Account.site_admin.feature_enabled?(:visible_assignments_scope_change)
"('rejected', 'deleted')"
else
"('rejected', 'deleted', 'inactive')"
end
end
# This beauty of a method brings together assignment overrides,
# due dates, grading periods, course/group enrollments, etc
# to calculate each student's effective due date and whether or
@ -273,7 +281,7 @@ class EffectiveDueDates
WHERE
o.set_type = 'CourseSection' AND
s.workflow_state <> 'deleted' AND
e.workflow_state NOT IN ('rejected', 'deleted', 'inactive') AND
e.workflow_state NOT IN #{filter_section_assigned_enrollments_sql} AND
e.type IN ('StudentEnrollment', 'StudentViewEnrollment')
#{filter_students_sql('e')}
),

View File

@ -923,7 +923,7 @@ describe AssignmentsApiController, type: :request do
expect(json).to eq []
end
it "does not show assignments assigned to the user has an inactive sectionenrollments for" do
it "does not show assignments assigned to the user's inactive section enrollment" do
inactive_enrollment = @course.enroll_student(@student2, :allow_multiple_enrollments => true,
:enrollment_state => 'inactive', :section => @section2)

View File

@ -21,6 +21,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
describe Course do
before(:once) do
Account.site_admin.enable_feature!(:visible_assignments_scope_change)
@test_course = Course.create!
course_with_teacher(course: @test_course, active_all: true)
@teacher = @user
@ -868,14 +869,28 @@ describe Course do
expect(edd.to_hash).to eq({})
end
it 'unassigns students in the assigned section when they are deactivated' do
it 'does not unassign students in the assigned section when they are deactivated' do
section = CourseSection.create!(name: 'My Awesome Section', course: @test_course)
student_in_section(section, user: @student1)
@assignment1.assignment_overrides.create!(due_at: 1.day.from_now(@now), due_at_overridden: true, set: section)
override = @assignment1.assignment_overrides.create!(
due_at: 1.day.from_now(@now),
due_at_overridden: true,
set: section
)
@student1_enrollment.deactivate
edd = EffectiveDueDates.for_course(@test_course, @assignment1)
expect(edd.to_hash).to eq({})
expect(edd.to_hash).to eq({
@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'
}
}
})
end
it 'does not unassign students in the assigned section when they are concluded' do

View File

@ -81,6 +81,7 @@ describe GradebookExporter do
end
it "returns assignments ordered by assignment group position when feature is disabled" do
expect(Account.site_admin).to receive(:feature_enabled?).and_call_original
expect(Account.site_admin).to receive(:feature_enabled?).with(:gradebook_csv_export_order_matches_gradebook_grid).and_return(false)
actual_assignment_headers = headers[4, 3]
@ -125,6 +126,7 @@ describe GradebookExporter do
end
it "returns assignments ordered by assignment group position when feature is disabled" do
expect(Account.site_admin).to receive(:feature_enabled?).and_call_original
expect(Account.site_admin).to receive(:feature_enabled?).with(:gradebook_csv_export_order_matches_gradebook_grid).and_return(false)
actual_assignment_headers = headers[4, 3]

View File

@ -516,6 +516,66 @@ describe Assignment do
end
end
describe '#visible_to_students_in_course_with_da' do
before(:once) do
Account.site_admin.enable_feature!(:visible_assignments_scope_change)
end
let(:student_enrollment) { @course.enrollments.find_by(user: @student) }
let(:visible_assignments) do
Assignment.visible_to_students_in_course_with_da(@student.id, @course.id)
end
it 'excludes unpublished assignments' do
assignment = @course.assignments.create!(workflow_state: 'unpublished')
expect(visible_assignments).not_to include assignment
end
it 'excludes assignments not assigned to the given user' do
section = @course.course_sections.create!
assignment = @course.assignments.create!(only_visible_to_overrides: true)
create_section_override_for_assignment(assignment, course_section: section)
expect(visible_assignments).not_to include assignment
end
it 'excludes assignments assigned to a deactivated enrollment for the given user' do
assignment = @course.assignments.create!(only_visible_to_overrides: true)
create_section_override_for_assignment(assignment, course_section: student_enrollment.course_section)
student_enrollment.deactivate
expect(visible_assignments).not_to include assignment
end
it 'excludes assignments that were assigned to the given user and then unassigned' do
section = @course.course_sections.create!
assignment = @course.assignments.create! # initially assigned
assignment.update!(only_visible_to_overrides: true) # unassigned
create_section_override_for_assignment(assignment, course_section: section)
expect(visible_assignments).not_to include assignment
end
it 'excludes assignments for which the given user submitted something before being unassigned' do
section = @course.course_sections.create!
assignment = @course.assignments.create!(submission_types: ['online_text_entry']) # initially assigned
assignment.submit_homework(@student, submission_type: :online_text_entry, body: :foo)
assignment.update!(only_visible_to_overrides: true) # unassigned
create_section_override_for_assignment(assignment, course_section: section)
expect(visible_assignments).not_to include assignment
end
it 'includes assignments assigned to a concluded enrollment for the given user' do
assignment = @course.assignments.create!(only_visible_to_overrides: true)
create_section_override_for_assignment(assignment, course_section: student_enrollment.course_section)
student_enrollment.conclude
expect(visible_assignments).to include assignment
end
it 'includes assignments assigned to an active enrollment for the given user' do
assignment = @course.assignments.create!(only_visible_to_overrides: true)
create_section_override_for_assignment(assignment, course_section: student_enrollment.course_section)
expect(visible_assignments).to include assignment
end
end
describe '#annotated_document?' do
before(:once) do
@assignment = @course.assignments.build