canvas-lms/spec/models/split_users_spec.rb

651 lines
30 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__) + '/../sharding_spec_helper.rb')
describe SplitUsers do
describe 'user splitting' do
let!(:restored_user) { user_model } # user will be merged into source_user and then restored on split
let!(:source_user) { user_model } # always the destination user of merge
let(:user3) { user_model }
let(:course1) { course_factory(active_all: true) }
let(:course2) { course_factory(active_all: true) }
let(:course3) { course_factory(active_all: true) }
let(:account1) { Account.default }
let(:sub_account) { account1.sub_accounts.create! }
it 'should restore terms_of use one way' do
source_user.accept_terms
source_user.save!
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(restored_user)
expect(restored_user.reload.preferences[:accepted_terms]).to be_nil
expect(source_user.reload.preferences[:accepted_terms]).to_not be_nil
end
it 'should restore terms_of use other way' do
restored_user.accept_terms
restored_user.save!
UserMerge.from(restored_user).into(source_user)
expect(source_user.reload.preferences[:accepted_terms]).to_not be_nil
SplitUsers.split_db_users(source_user)
expect(restored_user.reload.preferences[:accepted_terms]).to_not be_nil
expect(source_user.reload.preferences[:accepted_terms]).to be_nil
end
it 'should restore terms_of use no way' do
UserMerge.from(restored_user).into(source_user)
source_user.accept_terms
source_user.save!
SplitUsers.split_db_users(source_user)
expect(source_user.reload.preferences[:accepted_terms]).to be_nil
expect(restored_user.reload.preferences[:accepted_terms]).to be_nil
end
it 'should restore terms_of use both ways' do
restored_user.accept_terms
restored_user.save!
source_user.accept_terms
source_user.save!
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(source_user.reload.preferences[:accepted_terms]).to_not be_nil
expect(restored_user.reload.preferences[:accepted_terms]).to_not be_nil
end
it 'should restore names' do
restored_user.name = "jimmy one"
restored_user.save!
source_user.name = "jenny one"
source_user.save!
UserMerge.from(restored_user).into(source_user)
source_user.name = "other name"
source_user.save!
SplitUsers.split_db_users(source_user)
expect(restored_user.reload.name).to eq "jimmy one"
expect(source_user.reload.name).to eq "jenny one"
end
it 'should restore pseudonyms to the original user' do
pseudonym1 = source_user.pseudonyms.create!(unique_id: 'sam1@example.com')
pseudonym2 = account1.pseudonyms.create!(user: restored_user, unique_id: 'sam2@example.com')
pseudonym3 = account1.pseudonyms.create!(user: restored_user, unique_id: 'sam3@example.com')
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
source_user.reload
restored_user.reload
expect(pseudonym1.user).to eq source_user
expect(pseudonym2.user).to eq restored_user
expect(pseudonym3.user).to eq restored_user
end
it 'should not split if the data is too old' do
pseudonym1 = source_user.pseudonyms.create!(unique_id: 'sam1@example.com')
pseudonym2 = account1.pseudonyms.create!(user: restored_user, unique_id: 'sam2@example.com')
Timecop.travel(183.days.ago) do
UserMerge.from(restored_user).into(source_user)
end
expect(SplitUsers.split_db_users(source_user)).to eq []
expect(restored_user.workflow_state).to eq 'deleted'
expect(pseudonym1.reload.user).to eq source_user
expect(pseudonym2.reload.user).to eq source_user
end
it 'should use the setting for split time.' do
pseudonym1 = source_user.pseudonyms.create!(unique_id: 'sam1@example.com')
pseudonym2 = account1.pseudonyms.create!(user: restored_user, unique_id: 'sam2@example.com')
Setting.set('user_merge_to_split_time', '12')
Timecop.travel(15.days.ago) do
UserMerge.from(restored_user).into(source_user)
end
expect(SplitUsers.split_db_users(source_user)).to eq []
Setting.set('user_merge_to_split_time', '30')
SplitUsers.split_db_users(source_user)
expect(pseudonym1.reload.user).to eq source_user
expect(pseudonym2.reload.user).to eq restored_user
end
describe 'with merge data' do
it "should move lti_id to the new user" do
course1.enroll_user(source_user)
course2.enroll_user(restored_user)
UserMerge.from(restored_user).into(source_user)
UserMerge.from(source_user).into(user3)
SplitUsers.split_db_users(user3)
expect(user3.reload.past_lti_ids.count).to eq 0
expect(source_user.reload.past_lti_ids.count).to eq 1
end
it 'should split multiple users if no merge_data is specified' do
enrollment1 = course1.enroll_student(restored_user, enrollment_state: 'active')
enrollment2 = course1.enroll_student(source_user, enrollment_state: 'active')
enrollment3 = course2.enroll_student(restored_user, enrollment_state: 'active')
enrollment4 = course3.enroll_teacher(restored_user)
enrollment5 = course1.enroll_teacher(user3)
UserMerge.from(restored_user).into(source_user)
UserMerge.from(user3).into(source_user)
SplitUsers.split_db_users(source_user)
restored_user.reload
source_user.reload
user3.reload
expect(restored_user).not_to be_deleted
expect(source_user).not_to be_deleted
expect(user3).not_to be_deleted
expect(enrollment1.reload.user).to eq restored_user
expect(enrollment1.workflow_state).to eq 'active'
expect(enrollment2.reload.user).to eq source_user
expect(enrollment3.reload.user).to eq restored_user
expect(enrollment4.reload.user).to eq restored_user
expect(enrollment5.reload.user).to eq user3
end
it 'should handle conflicting enrollments' do
enrollment1 = course1.enroll_student(restored_user, enrollment_state: 'active')
UserMerge.from(restored_user).into(source_user)
enrollment2 = course1.enroll_student(restored_user, enrollment_state: 'active')
SplitUsers.split_db_users(source_user)
restored_user.reload
source_user.reload
expect(restored_user).not_to be_deleted
expect(source_user).not_to be_deleted
expect(enrollment1.reload.user).to eq source_user
expect(enrollment2.reload.user).to eq restored_user
end
it 'should handle user_observers' do
observer1 = user_model
observer2 = user_model
add_linked_observer(restored_user, observer1)
add_linked_observer(source_user, observer2)
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(restored_user.linked_observers).to eq [observer1]
expect(source_user.linked_observers).to eq [observer2]
end
it 'should handle access tokens' do
at = AccessToken.create!(user: restored_user, :developer_key => DeveloperKey.default)
UserMerge.from(restored_user).into(source_user)
expect(at.reload.user_id).to eq source_user.id
SplitUsers.split_db_users(source_user)
expect(at.reload.user_id).to eq restored_user.id
end
it 'should handle polls' do
poll = Polling::Poll.create!(user: restored_user, question: 'A Test Poll', description: 'A test description.')
UserMerge.from(restored_user).into(source_user)
expect(poll.reload.user_id).to eq source_user.id
SplitUsers.split_db_users(source_user)
expect(poll.reload.user_id).to eq restored_user.id
end
it 'should handle favorites' do
course1.enroll_user(restored_user)
fav = Favorite.create!(user: restored_user, context: course1)
UserMerge.from(restored_user).into(source_user)
expect(source_user.favorites.take.context_id).to eq course1.id
SplitUsers.split_db_users(source_user)
expect(fav.reload.user_id).to eq restored_user.id
end
it 'should handle ignores' do
course1.enroll_user(restored_user)
assignment2 = assignment_model(course: course1)
ignore = Ignore.create!(asset: assignment2, user: restored_user, purpose: 'submitting')
UserMerge.from(restored_user).into(source_user)
expect(ignore.reload.user_id).to eq source_user.id
SplitUsers.split_db_users(source_user)
expect(ignore.reload.user_id).to eq restored_user.id
end
it 'should handle conversations' do
sender = restored_user
recipient = user3
convo = sender.initiate_conversation([recipient])
UserMerge.from(restored_user).into(source_user)
expect(convo.reload.user_id).to eq source_user.id
SplitUsers.split_db_users(source_user)
expect(convo.reload.user_id).to eq restored_user.id
end
it 'should handle attachments' do
attachment1 = Attachment.create!(user: restored_user,
context: restored_user,
filename: "test.txt",
uploaded_data: StringIO.new("first"))
attachment2 = Attachment.create!(user: source_user,
context: source_user,
filename: "test2.txt",
uploaded_data: StringIO.new("second"))
UserMerge.from(restored_user).into(source_user)
run_jobs
expect(attachment1.reload.context).to eq source_user
expect(restored_user.reload.attachments).to eq []
SplitUsers.split_db_users(source_user)
expect(restored_user.reload.attachments).to eq [attachment1]
expect(source_user.reload.attachments).to eq [attachment2]
end
it 'should handle when observing merged user' do
link = add_linked_observer(source_user, restored_user)
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(restored_user.reload.as_observer_observation_links.to_a).to eq [link]
expect(source_user.reload.as_student_observation_links.to_a).to eq [link]
end
it 'should handle as_observer_observation_links' do
observee1 = user_model
observee2 = user_model
add_linked_observer(observee1, restored_user)
add_linked_observer(observee2, source_user)
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(restored_user.as_observer_observation_links).to eq observee1.as_student_observation_links
expect(source_user.as_observer_observation_links).to eq observee2.as_student_observation_links
end
it 'should handle duplicate user_observers' do
observer1 = user_model
observee1 = user_model
add_linked_observer(observee1, restored_user)
add_linked_observer(observee1, source_user)
add_linked_observer(restored_user, observer1)
add_linked_observer(source_user, observer1)
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(restored_user.as_observer_observation_links.count).to eq 1
expect(source_user.as_observer_observation_links.count).to eq 1
expect(restored_user.linked_observers).to eq [observer1]
expect(source_user.linked_observers).to eq [observer1]
expect(restored_user.as_observer_observation_links.first.workflow_state).to eq 'active'
expect(source_user.as_observer_observation_links.first.workflow_state).to eq 'active'
expect(restored_user.as_student_observation_links.first.workflow_state).to eq 'active'
expect(source_user.as_student_observation_links.first.workflow_state).to eq 'active'
end
it 'should only split users from merge_data when specified' do
enrollment1 = course1.enroll_user(restored_user)
enrollment2 = course1.enroll_student(source_user, enrollment_state: 'active')
enrollment3 = course2.enroll_student(restored_user, enrollment_state: 'active')
enrollment4 = course3.enroll_teacher(restored_user)
enrollment5 = course1.enroll_teacher(user3)
UserMerge.from(restored_user).into(source_user)
UserMerge.from(user3).into(source_user)
merge_data = UserMergeData.where(user_id: source_user, from_user: restored_user).first
SplitUsers.split_db_users(source_user, merge_data)
restored_user.reload
source_user.reload
user3.reload
expect(restored_user).not_to be_deleted
expect(source_user).not_to be_deleted
expect(user3).to be_deleted
expect(enrollment1.reload.user).to eq restored_user
expect(enrollment2.reload.user).to eq source_user
expect(enrollment3.reload.user).to eq restored_user
expect(enrollment4.reload.user).to eq restored_user
expect(enrollment5.reload.user).to eq source_user
end
it "should move ccs to the new user (but only if they don't already exist)" do
notification = Notification.where(name: "Report Generated").first_or_create
# unconfirmed: active conflict
restored_user.communication_channels.create!(path: 'a@instructure.com')
source_user.communication_channels.create!(path: 'A@instructure.com') { |cc| cc.workflow_state = 'active' }
# active: unconfirmed conflict
restored_user.communication_channels.create!(path: 'b@instructure.com') { |cc| cc.workflow_state = 'active' }
cc1 = source_user.communication_channels.create!(path: 'B@instructure.com')
# active: active conflict + notification policy copy
np_cc = restored_user.communication_channels.create!(path: 'c@instructure.com') { |cc| cc.workflow_state = 'active' }
np_cc.notification_policies.create!(notification_id: notification.id, frequency: 'weekly')
needs_np = source_user.communication_channels.create!(path: 'C@instructure.com') { |cc| cc.workflow_state = 'active' }
# unconfirmed: unconfirmed conflict
restored_user.communication_channels.create!(path: 'd@instructure.com')
source_user.communication_channels.create!(path: 'D@instructure.com')
# retired: unconfirmed conflict
restored_user.communication_channels.create!(path: 'e@instructure.com') { |cc| cc.workflow_state = 'retired' }
source_user.communication_channels.create!(path: 'E@instructure.com')
# unconfirmed: retired conflict
restored_user.communication_channels.create!(path: 'f@instructure.com')
source_user.communication_channels.create!(path: 'F@instructure.com') { |cc| cc.workflow_state = 'retired' }
# retired: active conflict
restored_user.communication_channels.create!(path: 'g@instructure.com') { |cc| cc.workflow_state = 'retired' }
source_user.communication_channels.create!(path: 'G@instructure.com') { |cc| cc.workflow_state = 'active' }
# active: retired conflict
restored_user.communication_channels.create!(path: 'h@instructure.com') { |cc| cc.workflow_state = 'active' }
source_user.communication_channels.create!(path: 'H@instructure.com') { |cc| cc.workflow_state = 'retired' }
# retired: retired conflict
restored_user.communication_channels.create!(path: 'i@instructure.com') { |cc| cc.workflow_state = 'retired' }
source_user.communication_channels.create!(path: 'I@instructure.com') { |cc| cc.workflow_state = 'retired' }
# <nothing>: active
source_user.communication_channels.create!(path: 'J@instructure.com') { |cc| cc.workflow_state = 'active' }
# active: <nothing>
restored_user.communication_channels.create!(path: 'k@instructure.com') { |cc| cc.workflow_state = 'active' }
# <nothing>: unconfirmed
source_user.communication_channels.create!(path: 'L@instructure.com')
# unconfirmed: <nothing>
restored_user.communication_channels.create!(path: 'm@instructure.com')
# <nothing>: retired
source_user.communication_channels.create!(path: 'N@instructure.com') { |cc| cc.workflow_state = 'retired' }
# retired: <nothing>
restored_user.communication_channels.create!(path: 'o@instructure.com') { |cc| cc.workflow_state = 'retired' }
restored_user_ccs = restored_user.communication_channels.where.not(workflow_state: 'retired').
map { |cc| [cc.path, cc.workflow_state] }.sort
# cc will not be restored because it conflicted on merge and it was unconfirmed and it is frd deleted
source_user_ccs = source_user.communication_channels.where.not(id: cc1, workflow_state: 'retired').
map { |cc| [cc.path, cc.workflow_state] }.sort
UserMerge.from(restored_user).into(source_user)
expect(needs_np.notification_policies.take.frequency).to eq 'weekly'
SplitUsers.split_db_users(source_user)
restored_user.reload
source_user.reload
expect(restored_user.communication_channels.where.not(workflow_state: 'retired').
map { |cc| [cc.path, cc.workflow_state] }.sort).to eq restored_user_ccs
expect(source_user.communication_channels.where.not(workflow_state: 'retired').
map { |cc| [cc.path, cc.workflow_state] }.sort).to eq source_user_ccs
end
end
it 'should restore submissions' do
course1.enroll_student(restored_user, enrollment_state: 'active')
assignment = course1.assignments.new(title: "some assignment")
assignment.workflow_state = "published"
assignment.save
valid_attributes = {
grade: "1.5",
grader: @teacher,
url: "www.instructure.com"
}
submission = assignment.submissions.find_by!(user: restored_user)
submission.update!(valid_attributes)
UserMerge.from(restored_user).into(source_user)
expect(submission.reload.user).to eq source_user
SplitUsers.split_db_users(source_user)
expect(submission.reload.user).to eq restored_user
end
it 'should handle conflicting submissions' do
course1.enroll_student(restored_user, enrollment_state: 'active')
course1.enroll_student(source_user, enrollment_state: 'active')
assignment = course1.assignments.new(title: "some assignment")
assignment.workflow_state = "published"
assignment.save
valid_attributes = {
grade: "1.5",
grader: @teacher,
url: "www.instructure.com"
}
submission1 = assignment.submissions.find_by!(user: restored_user)
submission1.update!(valid_attributes)
submission2 = assignment.submissions.find_by!(user: source_user)
submission2.update!(valid_attributes)
UserMerge.from(restored_user).into(source_user)
expect(submission1.reload.user).to eq restored_user
expect(submission2.reload.user).to eq source_user
Submission.where(id: submission1).update_all(workflow_state: 'deleted')
SplitUsers.split_db_users(source_user)
expect(submission1.reload.user).to eq restored_user
expect(submission2.reload.user).to eq source_user
end
it 'should handle conflicting submissions other way too' do
course1.enroll_student(restored_user, enrollment_state: 'active')
course1.enroll_student(source_user, enrollment_state: 'active')
assignment = course1.assignments.new(title: "some assignment")
assignment.workflow_state = "published"
assignment.save
valid_attributes = {
grade: "1.5",
grader: @teacher,
url: "www.instructure.com"
}
submission1 = assignment.submissions.find_by!(user: restored_user)
submission1.update!(valid_attributes)
submission2 = assignment.submissions.find_by!(user: source_user)
UserMerge.from(restored_user).into(source_user)
expect(submission1.reload.user).to eq source_user
expect(submission2.reload.user).to eq restored_user
SplitUsers.split_db_users(source_user)
expect(submission1.reload.user).to eq restored_user
expect(submission2.reload.user).to eq source_user
end
it 'should not blow up on deleted courses' do
course1.enroll_student(restored_user, enrollment_state: 'active')
UserMerge.from(restored_user).into(source_user)
course1.destroy
expect { SplitUsers.split_db_users(source_user) }.not_to raise_error
end
it 'should restore admins to the original state' do
admin = account1.account_users.create(user: restored_user)
admin2 = sub_account.account_users.create(user: restored_user)
admin3 = sub_account.account_users.create(user: source_user)
UserMerge.from(restored_user).into(source_user)
admin.reload.destroy
SplitUsers.split_db_users(source_user)
expect(admin.reload.workflow_state).to eq 'active'
expect(admin.reload.user).to eq restored_user
expect(admin2.reload.user).to eq restored_user
expect(admin3.reload.user).to eq source_user
end
context 'sharding' do
specs_require_sharding
let!(:shard1_source_user) { @shard1.activate { user_model } }
let!(:shard1_account) { @shard1.activate { Account.create! } }
let!(:shard1_course) { shard1_account.courses.create! }
it 'should handle access tokens' do
at = AccessToken.create!(user: restored_user, :developer_key => DeveloperKey.default)
UserMerge.from(restored_user).into(shard1_source_user)
expect(at.reload.user_id).to eq shard1_source_user.id
SplitUsers.split_db_users(shard1_source_user)
expect(at.reload.user_id).to eq restored_user.id
end
it 'should move submissions from new courses post merge when appropriate' do
pseudonym1 = restored_user.pseudonyms.create!(unique_id: 'sam1@example.com')
UserMerge.from(restored_user).into(shard1_source_user)
e = course1.enroll_student(shard1_source_user, enrollment_state: 'active')
Enrollment.where(id: e).update_all(sis_pseudonym_id: pseudonym1.id)
assignment = course1.assignments.new(title: "some assignment")
assignment.workflow_state = "published"
assignment.save
valid_attributes = {
grade: "1.5",
grader: @teacher,
url: "www.instructure.com"
}
submission = assignment.submissions.find_by!(user: shard1_source_user)
submission.update!(valid_attributes)
SplitUsers.split_db_users(shard1_source_user)
expect(submission.reload.user).to eq restored_user
end
it 'should handle user_observers cross shard' do
observer1 = user_model
observer2 = user_model
add_linked_observer(restored_user, observer1)
add_linked_observer(shard1_source_user, observer2)
UserMerge.from(restored_user).into(shard1_source_user)
expect(restored_user.linked_observers).to eq []
expect(shard1_source_user.linked_observers.pluck(:id).sort).to eq [observer1.id, observer2.id].sort
SplitUsers.split_db_users(shard1_source_user)
expect(restored_user.reload.linked_observers).to eq [observer1]
expect(shard1_source_user.reload.linked_observers).to eq [observer2]
end
it 'should handle conflicting submissions for cross shard users' do
course1.enroll_student(restored_user, enrollment_state: 'active')
course1.enroll_student(shard1_source_user, enrollment_state: 'active')
assignment = course1.assignments.new(title: "some assignment")
assignment.workflow_state = "published"
assignment.save
valid_attributes = {
grade: "1.5",
grader: @teacher,
url: "www.instructure.com"
}
submission1 = assignment.submissions.find_by!(user: restored_user)
submission1.update!(valid_attributes)
submission2 = assignment.submissions.find_by!(user: shard1_source_user)
UserMerge.from(restored_user).into(shard1_source_user)
expect(submission1.reload.user).to eq shard1_source_user
expect(submission2.reload.user).to eq restored_user
SplitUsers.split_db_users(shard1_source_user)
expect(submission1.reload.user).to eq restored_user
expect(submission2.reload.user).to eq shard1_source_user
end
it 'should restore admins to the original state' do
admin = account1.account_users.create(user: restored_user)
shard1_source_user.associate_with_shard(sub_account.shard)
admin2 = sub_account.account_users.create(user: shard1_source_user)
UserMerge.from(restored_user).into(shard1_source_user)
admin.reload.destroy
SplitUsers.split_db_users(shard1_source_user)
expect(admin.reload.workflow_state).to eq 'active'
expect(admin.reload.user).to eq restored_user
expect(admin2.reload.user).to eq shard1_source_user
end
it 'should merge a user across shards' do
pseudonym1 = restored_user.pseudonyms.create!(unique_id: 'sam1@example.com')
@shard1.activate do
account = Account.create!
@pseudonym2 = shard1_source_user.pseudonyms.create!(account: account, unique_id: 'sam1@example.com')
UserMerge.from(restored_user).into(shard1_source_user)
SplitUsers.split_db_users(shard1_source_user)
end
restored_user.reload
shard1_source_user.reload
expect(restored_user).not_to be_deleted
expect(pseudonym1.reload.user).to eq restored_user
expect(shard1_source_user.all_pseudonyms).to eq [@pseudonym2]
end
it "should split a user across shards with ccs" do
restored_user.communication_channels.create!(:path => 'a@example.com') { |cc| cc.workflow_state = 'active' }
restored_user_ccs = restored_user.communication_channels.map { |cc| [cc.path, cc.workflow_state] }.sort
source_user_ccs = shard1_source_user.communication_channels.map { |cc| [cc.path, cc.workflow_state] }.sort
@shard1.activate do
UserMerge.from(restored_user).into(shard1_source_user)
cc = shard1_source_user.reload.communication_channels.where(path: 'a@example.com').take
n = Notification.create!(name: 'Assignment Createds', subject: 'Tests', category: 'TestNevers')
NotificationPolicy.create(notification: n, communication_channel: cc, frequency: 'immediately')
SplitUsers.split_db_users(shard1_source_user)
end
restored_user.reload
shard1_source_user.reload
expect(restored_user.communication_channels.map { |cc| [cc.path, cc.workflow_state] }.sort).to eq restored_user_ccs
expect(shard1_source_user.communication_channels.map { |cc| [cc.path, cc.workflow_state] }.sort).to eq source_user_ccs
end
it 'should handle enrollments across shards' do
e = course1.enroll_user(restored_user)
@shard1.activate do
@e = shard1_course.enroll_user(shard1_source_user)
UserMerge.from(restored_user).into(shard1_source_user)
end
SplitUsers.split_db_users(shard1_source_user)
expect(e.reload.user).to eq restored_user
expect(@e.reload.user).to eq shard1_source_user
end
it "should work with cross-shard submissions" do
shard1_course.enroll_student(restored_user, enrollment_state: 'active')
assignment = shard1_course.assignments.create!(title: "some assignment", workflow_state: 'published', submission_types: "online_text_entry")
submission = assignment.submit_homework(restored_user, submission_type: 'online_text_entry', body: 'fooey')
UserMerge.from(restored_user).into(source_user)
SplitUsers.split_db_users(source_user)
expect(submission.reload.user).to eq restored_user
end
it "should copy notification policies" do
og_cc = restored_user.communication_channels.create!(:path => 'a@example.com') { |cc| cc.workflow_state = 'active' }
n = Notification.create!(name: 'Assignment', subject: 'Tests', category: 'TestNevers')
NotificationPolicy.create!(notification: n, communication_channel: og_cc, frequency: 'immediately')
@shard1.activate do
UserMerge.from(restored_user).into(shard1_source_user)
cc = shard1_source_user.communication_channels.where(path: 'a@example.com').take!
expect(cc.notification_policies.count).to eq 1
end
SplitUsers.split_db_users(shard1_source_user)
expect(shard1_source_user.communication_channels.count).to eq 0
end
it "should copy notification policies on conflict" do
og_cc = restored_user.communication_channels.create!(:path => 'a@example.com') { |cc| cc.workflow_state = 'active' }
n = Notification.create!(name: 'Assignment', subject: 'Tests', category: 'TestNevers')
NotificationPolicy.create!(notification: n, communication_channel: og_cc, frequency: 'immediately')
# conflict_cc
cc = shard1_source_user.communication_channels.create!(:path => 'a@example.com') { |cc| cc.workflow_state = 'active' }
UserMerge.from(restored_user).into(shard1_source_user)
expect(cc.notification_policies.count).to eq 1
SplitUsers.split_db_users(shard1_source_user)
expect(shard1_source_user.communication_channels.count).to eq 1
end
end
end
end