def test_results_cache_after_user_merge(self): """Asserts that merge_users leaves the results cache in a consistent state. Regression test for #907""" contributor = baker.make(UserProfile) main_user = baker.make(UserProfile) student = baker.make(UserProfile) evaluation = baker.make(Evaluation, state=Evaluation.State.PUBLISHED, participants=[student]) questionnaire = baker.make(Questionnaire) baker.make(Question, questionnaire=questionnaire, type=Question.GRADE) baker.make(Contribution, contributor=contributor, evaluation=evaluation, questionnaires=[questionnaire]) cache_results(evaluation) merge_users(main_user, contributor) evaluation_results = get_results(evaluation) for contribution_result in evaluation_results.contribution_results: self.assertTrue( Contribution.objects.filter( evaluation=evaluation, contributor=contribution_result.contributor).exists())
def test_collect_results_after_user_merge(self): """ Asserts that merge_users leaves the results cache in a consistent state. Regression test for #907 """ contributor = mommy.make(UserProfile) main_user = mommy.make(UserProfile) student = mommy.make(UserProfile) course = mommy.make(Course, state='published', participants=[student]) questionnaire = mommy.make(Questionnaire) mommy.make(Question, questionnaire=questionnaire, type="G") mommy.make(Contribution, contributor=contributor, course=course, questionnaires=[questionnaire]) collect_results(course) merge_users(main_user, contributor) course_results = collect_results(course) for contribution_result in course_results.contribution_results: self.assertTrue( Contribution.objects.filter( course=course, contributor=contribution_result.contributor).exists())
def user_merge(request, main_user_id, other_user_id): main_user = get_object_or_404(UserProfile, id=main_user_id) other_user = get_object_or_404(UserProfile, id=other_user_id) if request.method == 'POST': merged_user, errors, warnings = merge_users(main_user, other_user) if not errors: messages.success(request, _("Successfully merged users.")) else: messages.error(request, _("Merging the users failed. No data was changed.")) return redirect('staff:user_index') else: merged_user, errors, warnings = merge_users(main_user, other_user, preview=True) return render(request, "staff_user_merge.html", dict(main_user=main_user, other_user=other_user, merged_user=merged_user, errors=errors, warnings=warnings))
def test_merge_users_changes_data_on_success(self): # Fix data so that the merge will not fail as in test_merge_users_does_not_change_data_on_fail self.evaluation1.participants.set([self.main_user]) self.contribution2.delete() __, errors, warnings = merge_users( self.main_user, self.other_user) # merge should succeed self.assertEqual(errors, []) self.assertEqual(warnings, ["rewards"]) # rewards warning is still there self.main_user.refresh_from_db() self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "User") self.assertEqual(self.main_user.email, "*****@*****.**") self.assertTrue(self.main_user.is_superuser) self.assertEqual(set(self.main_user.groups.all()), {self.group1, self.group2}) self.assertEqual(set(self.main_user.delegates.all()), {self.user1, self.user2, self.user3}) self.assertEqual(set(self.main_user.represented_users.all()), {self.user1, self.user3}) self.assertEqual(set(self.main_user.cc_users.all()), {self.user1}) self.assertEqual(set(self.main_user.ccing_users.all()), {self.user1, self.user2}) self.assertTrue( RewardPointGranting.objects.filter( user_profile=self.main_user).exists()) self.assertTrue( RewardPointRedemption.objects.filter( user_profile=self.main_user).exists()) self.assertEqual(set(self.course1.responsibles.all()), {self.main_user}) self.assertEqual(set(self.course2.responsibles.all()), {self.main_user}) self.assertEqual(set(self.course2.responsibles.all()), {self.main_user}) self.assertEqual(set(self.evaluation1.participants.all()), {self.main_user}) self.assertEqual(set(self.evaluation2.participants.all()), {self.main_user}) self.assertEqual(set(self.evaluation2.voters.all()), {self.main_user}) self.assertEqual(set(self.evaluation3.participants.all()), {self.main_user}) self.assertEqual(set(self.evaluation3.voters.all()), {self.main_user}) self.assertFalse( UserProfile.objects.filter( email="*****@*****.**").exists()) self.assertFalse( RewardPointGranting.objects.filter( user_profile=self.other_user).exists()) self.assertFalse( RewardPointRedemption.objects.filter( user_profile=self.other_user).exists())
def test_collect_results_after_user_merge(self): """ Asserts that merge_users leaves the results cache in a consistent state. Regression test for #907 """ contributor = mommy.make(UserProfile) main_user = mommy.make(UserProfile) student = mommy.make(UserProfile) evaluation = mommy.make(Evaluation, state='published', participants=[student]) questionnaire = mommy.make(Questionnaire) mommy.make(Question, questionnaire=questionnaire, type=Question.GRADE) mommy.make(Contribution, contributor=contributor, evaluation=evaluation, questionnaires=[questionnaire]) collect_results(evaluation) merge_users(main_user, contributor) evaluation_results = collect_results(evaluation) for contribution_result in evaluation_results.contribution_results: self.assertTrue(Contribution.objects.filter(evaluation=evaluation, contributor=contribution_result.contributor).exists())
def test_calculate_results_after_user_merge(self): """ Asserts that merge_users leaves the results cache in a consistent state. Regression test for #907 """ contributor = mommy.make(UserProfile) main_user = mommy.make(UserProfile) student = mommy.make(UserProfile) course = mommy.make(Course, state='published', participants=[student]) questionnaire = mommy.make(Questionnaire) mommy.make(Question, questionnaire=questionnaire, type="G") mommy.make(Contribution, contributor=contributor, course=course, questionnaires=[questionnaire]) calculate_results(course) merge_users(main_user, contributor) results = calculate_results(course) for section in results: self.assertTrue(Contribution.objects.filter(course=course, contributor=section.contributor).exists())
def test_merge_handles_all_attributes(self): user1 = mommy.make(UserProfile) user2 = mommy.make(UserProfile) all_attrs = list( field.name for field in UserProfile._meta.get_fields(include_hidden=True)) # these are relations to intermediate models generated by django for m2m relations. # we can safely ignore these since the "normal" fields of the m2m relations are present as well. all_attrs = list(attr for attr in all_attrs if not attr.startswith("UserProfile_")) # equally named fields are not supported, sorry self.assertEqual(len(all_attrs), len(set(all_attrs))) # some attributes we don't care about when merging ignored_attrs = { 'id', # nothing to merge here 'password', # not used in production 'last_login', # something to really not care about 'user_permissions', # we don't use permissions 'logentry', # wtf 'login_key', # we decided to discard other_user's login key 'login_key_valid_until', # not worth dealing with 'language', # Not worth dealing with 'Course_voters+', # some more intermediate models, for an explanation see above 'Course_participants+', # intermediate model } expected_attrs = set(all_attrs) - ignored_attrs # actual merge happens here merged_user, errors, warnings = merge_users(user1, user2) self.assertEqual(errors, []) self.assertEqual(warnings, []) handled_attrs = set(merged_user.keys()) # attributes that are handled in the merge method but that are not present in the merged_user dict # add attributes here only if you're actually dealing with them in merge_users(). additional_handled_attrs = { 'grades_last_modified_user+', 'course_last_modified_user+', } actual_attrs = handled_attrs | additional_handled_attrs self.assertEqual(expected_attrs, actual_attrs)
def test_merge_handles_all_attributes(self): user1 = mommy.make(UserProfile) user2 = mommy.make(UserProfile) all_attrs = list(field.name for field in UserProfile._meta.get_fields(include_hidden=True)) # these are relations to intermediate models generated by django for m2m relations. # we can safely ignore these since the "normal" fields of the m2m relations are present as well. all_attrs = list(attr for attr in all_attrs if not attr.startswith("UserProfile_")) # equally named fields are not supported, sorry self.assertEqual(len(all_attrs), len(set(all_attrs))) # some attributes we don't care about when merging ignored_attrs = { 'id', # nothing to merge here 'password', # not used in production 'last_login', # something to really not care about 'user_permissions', # we don't use permissions 'logentry', # wtf 'login_key', # we decided to discard other_user's login key 'login_key_valid_until', # not worth dealing with 'language', # Not worth dealing with 'Evaluation_voters+', # some more intermediate models, for an explanation see above 'Evaluation_participants+', # intermediate model } expected_attrs = set(all_attrs) - ignored_attrs # actual merge happens here merged_user, errors, warnings = merge_users(user1, user2) self.assertEqual(errors, []) self.assertEqual(warnings, []) handled_attrs = set(merged_user.keys()) # attributes that are handled in the merge method but that are not present in the merged_user dict # add attributes here only if you're actually dealing with them in merge_users(). additional_handled_attrs = { 'grades_last_modified_user+', 'courses_last_modified+', 'evaluations_last_modified+', 'Course_responsibles+' } actual_attrs = handled_attrs | additional_handled_attrs self.assertEqual(expected_attrs, actual_attrs)
def test_merge_users_does_not_change_data_on_fail(self): __, errors, warnings = merge_users(self.main_user, self.other_user) # merge should fail self.assertCountEqual(errors, ["contributions", "evaluations_participating_in"]) self.assertCountEqual(warnings, ["rewards"]) # assert that nothing has changed self.main_user.refresh_from_db() self.other_user.refresh_from_db() self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "") self.assertEqual(self.main_user.email, None) self.assertFalse(self.main_user.is_superuser) self.assertEqual(set(self.main_user.groups.all()), {self.group1}) self.assertEqual(set(self.main_user.delegates.all()), {self.user1, self.user2}) self.assertEqual(set(self.main_user.represented_users.all()), {self.user3}) self.assertEqual(set(self.main_user.cc_users.all()), {self.user1}) self.assertEqual(set(self.main_user.ccing_users.all()), set()) self.assertTrue(RewardPointGranting.objects.filter(user_profile=self.main_user).exists()) self.assertTrue(RewardPointRedemption.objects.filter(user_profile=self.main_user).exists()) self.assertEqual(self.other_user.title, "") self.assertEqual(self.other_user.first_name, "Other") self.assertEqual(self.other_user.last_name, "User") self.assertEqual(self.other_user.email, "*****@*****.**") self.assertEqual(set(self.other_user.groups.all()), {self.group2}) self.assertEqual(set(self.other_user.delegates.all()), {self.user3}) self.assertEqual(set(self.other_user.represented_users.all()), {self.user1}) self.assertEqual(set(self.other_user.cc_users.all()), set()) self.assertEqual(set(self.other_user.ccing_users.all()), {self.user1, self.user2}) self.assertTrue(RewardPointGranting.objects.filter(user_profile=self.other_user).exists()) self.assertTrue(RewardPointRedemption.objects.filter(user_profile=self.other_user).exists()) self.assertEqual(set(self.course1.responsibles.all()), {self.main_user}) self.assertEqual(set(self.course2.responsibles.all()), {self.main_user}) self.assertEqual(set(self.course3.responsibles.all()), {self.other_user}) self.assertEqual(set(self.evaluation1.participants.all()), {self.main_user, self.other_user}) self.assertEqual(set(self.evaluation1.participants.all()), {self.main_user, self.other_user}) self.assertEqual(set(self.evaluation2.participants.all()), {self.main_user}) self.assertEqual(set(self.evaluation2.voters.all()), {self.main_user}) self.assertEqual(set(self.evaluation3.participants.all()), {self.other_user}) self.assertEqual(set(self.evaluation3.voters.all()), {self.other_user})
def test_merge_users(self): __, errors, warnings = merge_users( self.main_user, self.other_user) # merge should fail self.assertSequenceEqual(errors, ['contributions', 'courses_participating_in']) self.assertSequenceEqual(warnings, ['rewards']) # assert that nothing has changed self.main_user.refresh_from_db() self.other_user.refresh_from_db() self.assertEqual(self.main_user.username, "main_user") self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "") self.assertEqual(self.main_user.email, "") self.assertSequenceEqual(self.main_user.groups.all(), [self.group1]) self.assertSequenceEqual(self.main_user.delegates.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.main_user.represented_users.all(), [self.user3]) self.assertSequenceEqual(self.main_user.cc_users.all(), [self.user1]) self.assertSequenceEqual(self.main_user.ccing_users.all(), []) self.assertFalse(self.main_user.is_superuser) self.assertTrue( RewardPointGranting.objects.filter( user_profile=self.main_user).exists()) self.assertTrue( RewardPointRedemption.objects.filter( user_profile=self.main_user).exists()) self.assertEqual(self.other_user.username, "other_user") self.assertEqual(self.other_user.title, "") self.assertEqual(self.other_user.first_name, "Other") self.assertEqual(self.other_user.last_name, "User") self.assertEqual(self.other_user.email, "*****@*****.**") self.assertSequenceEqual(self.other_user.groups.all(), [self.group2]) self.assertSequenceEqual(self.other_user.delegates.all(), [self.user3]) self.assertSequenceEqual(self.other_user.represented_users.all(), [self.user1]) self.assertSequenceEqual(self.other_user.cc_users.all(), []) self.assertSequenceEqual(self.other_user.ccing_users.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.course1.participants.all(), [self.main_user, self.other_user]) self.assertSequenceEqual(self.course2.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.voters.all(), [self.main_user]) self.assertSequenceEqual(self.course3.participants.all(), [self.other_user]) self.assertSequenceEqual(self.course3.voters.all(), [self.other_user]) self.assertTrue( RewardPointGranting.objects.filter( user_profile=self.other_user).exists()) self.assertTrue( RewardPointRedemption.objects.filter( user_profile=self.other_user).exists()) # fix data self.course1.participants.set([self.main_user]) self.contribution2.delete() __, errors, warnings = merge_users( self.main_user, self.other_user) # merge should succeed self.assertEqual(errors, []) self.assertSequenceEqual(warnings, ['rewards']) # rewards warning is still there self.main_user.refresh_from_db() self.assertEqual(self.main_user.username, "main_user") self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "User") self.assertEqual(self.main_user.email, "*****@*****.**") self.assertSequenceEqual(self.main_user.groups.all(), [self.group1, self.group2]) self.assertSequenceEqual(self.main_user.delegates.all(), [self.user1, self.user2, self.user3]) self.assertSequenceEqual(self.main_user.represented_users.all(), [self.user1, self.user3]) self.assertSequenceEqual(self.main_user.cc_users.all(), [self.user1]) self.assertSequenceEqual(self.main_user.ccing_users.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.course1.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.voters.all(), [self.main_user]) self.assertSequenceEqual(self.course3.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course3.voters.all(), [self.main_user]) self.assertTrue(self.main_user.is_superuser) self.assertTrue( RewardPointGranting.objects.filter( user_profile=self.main_user).exists()) self.assertTrue( RewardPointRedemption.objects.filter( user_profile=self.main_user).exists()) self.assertFalse( RewardPointGranting.objects.filter( user_profile=self.other_user).exists()) self.assertFalse( RewardPointRedemption.objects.filter( user_profile=self.other_user).exists())
def test_merge_users(self): __, errors, warnings = merge_users(self.main_user, self.other_user) # merge should fail self.assertSequenceEqual(errors, ['contributions', 'courses_participating_in']) self.assertSequenceEqual(warnings, ['rewards']) # assert that nothing has changed self.main_user.refresh_from_db() self.other_user.refresh_from_db() self.assertEqual(self.main_user.username, "main_user") self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "") self.assertEqual(self.main_user.email, "") self.assertSequenceEqual(self.main_user.groups.all(), [self.group1]) self.assertSequenceEqual(self.main_user.delegates.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.main_user.represented_users.all(), [self.user3]) self.assertSequenceEqual(self.main_user.cc_users.all(), [self.user1]) self.assertSequenceEqual(self.main_user.ccing_users.all(), []) self.assertFalse(self.main_user.is_superuser) self.assertTrue(RewardPointGranting.objects.filter(user_profile=self.main_user).exists()) self.assertTrue(RewardPointRedemption.objects.filter(user_profile=self.main_user).exists()) self.assertEqual(self.other_user.username, "other_user") self.assertEqual(self.other_user.title, "") self.assertEqual(self.other_user.first_name, "Other") self.assertEqual(self.other_user.last_name, "User") self.assertEqual(self.other_user.email, "*****@*****.**") self.assertSequenceEqual(self.other_user.groups.all(), [self.group2]) self.assertSequenceEqual(self.other_user.delegates.all(), [self.user3]) self.assertSequenceEqual(self.other_user.represented_users.all(), [self.user1]) self.assertSequenceEqual(self.other_user.cc_users.all(), []) self.assertSequenceEqual(self.other_user.ccing_users.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.course1.participants.all(), [self.main_user, self.other_user]) self.assertSequenceEqual(self.course2.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.voters.all(), [self.main_user]) self.assertSequenceEqual(self.course3.participants.all(), [self.other_user]) self.assertSequenceEqual(self.course3.voters.all(), [self.other_user]) self.assertTrue(RewardPointGranting.objects.filter(user_profile=self.other_user).exists()) self.assertTrue(RewardPointRedemption.objects.filter(user_profile=self.other_user).exists()) # fix data self.course1.participants.set([self.main_user]) self.contribution2.delete() __, errors, warnings = merge_users(self.main_user, self.other_user) # merge should succeed self.assertEqual(errors, []) self.assertSequenceEqual(warnings, ['rewards']) # rewards warning is still there self.main_user.refresh_from_db() self.assertEqual(self.main_user.username, "main_user") self.assertEqual(self.main_user.title, "Dr.") self.assertEqual(self.main_user.first_name, "Main") self.assertEqual(self.main_user.last_name, "User") self.assertEqual(self.main_user.email, "*****@*****.**") self.assertSequenceEqual(self.main_user.groups.all(), [self.group1, self.group2]) self.assertSequenceEqual(self.main_user.delegates.all(), [self.user1, self.user2, self.user3]) self.assertSequenceEqual(self.main_user.represented_users.all(), [self.user1, self.user3]) self.assertSequenceEqual(self.main_user.cc_users.all(), [self.user1]) self.assertSequenceEqual(self.main_user.ccing_users.all(), [self.user1, self.user2]) self.assertSequenceEqual(self.course1.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course2.voters.all(), [self.main_user]) self.assertSequenceEqual(self.course3.participants.all(), [self.main_user]) self.assertSequenceEqual(self.course3.voters.all(), [self.main_user]) self.assertTrue(self.main_user.is_superuser) self.assertTrue(RewardPointGranting.objects.filter(user_profile=self.main_user).exists()) self.assertTrue(RewardPointRedemption.objects.filter(user_profile=self.main_user).exists()) self.assertFalse(RewardPointGranting.objects.filter(user_profile=self.other_user).exists()) self.assertFalse(RewardPointRedemption.objects.filter(user_profile=self.other_user).exists())