def setUpTestData(cls): super(SearchTests, cls).setUpTestData() # create some students with mute_signals(post_save): cls.students = [(ProfileFactory.create(filled_out=True)).user for _ in range(30)] # create the programs cls.program1 = ProgramFactory.create(live=True) cls.program2 = ProgramFactory.create(live=True) cls.program3 = ProgramFactory.create(live=True) # enroll the users in the programs for num, student in enumerate(cls.students): if num % 3 == 0: program = cls.program1 elif num % 3 == 1: program = cls.program2 else: program = cls.program3 ProgramEnrollmentFactory.create( user=student, program=program ) # create an user with a role for one program cls.staff = UserFactory.create() Role.objects.create( user=cls.staff, program=cls.program1, role=Staff.ROLE_ID ) # search URL cls.search_url = reverse('search_api', kwargs={'elastic_url': ''})
def test_financial_aid_with_application_with_full_profile(self): """ Test that financialAid request serializer works when profile is filled out. """ with mute_signals(post_save): profile = ProfileFactory.create() ProgramEnrollmentFactory.create(user=profile.user, program=self.program) original_currency = 'USD' original_income = 1000.0 serializer = FinancialAidRequestSerializer( data={ 'program_id': self.program.id, 'tier_program': self.min_tier_program, 'date_documents_sent': None, 'original_currency': original_currency, 'original_income': original_income }, context={ 'request': MagicMock(user=profile.user) } ) serializer.is_valid(raise_exception=True) serializer.save() assert serializer.data == { 'original_currency': original_currency, 'original_income': original_income, 'program_id': self.program.id }
def setUpTestData(cls): super().setUpTestData() with mute_signals(post_save): staff_profile = ProfileFactory.create(user__email='*****@*****.**') recipient_profile = ProfileFactory.create( user__email='*****@*****.**', email_optin=True, ) cls.staff_user = staff_profile.user cls.recipient_user = recipient_profile.user cls.program = ProgramFactory.create(financial_aid_availability=False) ProgramEnrollmentFactory.create( user=cls.recipient_user, program=cls.program ) Role.objects.create( user=cls.staff_user, program=cls.program, role=Staff.ROLE_ID ) cls.url_name = 'learner_mail_api' cls.request_data = { 'email_subject': 'email subject', 'email_body': 'email body' }
def test_multiple_success(self): """test retire_users command success with more than one user""" user_names = ["foo", "bar", "baz"] for user_name in user_names: user = UserFactory.create(username=user_name, is_active=True) user.profile.email_optin = True user.profile.save() UserSocialAuthFactory.create(user=user, provider='not_edx') for _ in range(TOTAL_PROGRAMS): ProgramEnrollmentFactory.create(user=user) assert user.is_active is True assert user.profile.email_optin is True assert UserSocialAuth.objects.filter(user=user).count() == 1 assert ProgramEnrollment.objects.filter(user=user).count() == TOTAL_PROGRAMS self.command.handle("retire_users", users=user_names) for user_name in user_names: user = User.objects.get(username=user_name) assert user.is_active is False assert user.profile.email_optin is False assert UserSocialAuth.objects.filter(user=user).count() == 0 assert ProgramEnrollment.objects.filter(user=user).count() == 0
def test_financial_aid_with_application_with_full_profile(self): """ Test that financialAid request serializer works when profile is filled out. """ with mute_signals(post_save): profile = ProfileFactory.create() ProgramEnrollmentFactory.create(user=profile.user, program=self.program) original_currency = 'USD' original_income = 1000.0 serializer = FinancialAidRequestSerializer( data={ 'program_id': self.program.id, 'tier_program': self.min_tier_program, 'date_documents_sent': None, 'original_currency': original_currency, 'original_income': original_income }, context={'request': MagicMock(user=profile.user)}) serializer.is_valid(raise_exception=True) serializer.save() assert serializer.data == { 'original_currency': original_currency, 'original_income': original_income, 'program_id': self.program.id }
def test_learner_view_needs_paid_learner(self, mock_mailgun_client): """ Test that a learner attempting to email another learner will only succeed if the sender has paid for a course run in a program that the recipient is enrolled in """ mock_mailgun_client.send_individual_email.return_value = Mock( spec=Response, status_code=status.HTTP_200_OK, json=mocked_json() ) with mute_signals(post_save): learner_profile = ProfileFactory.create( user__email='*****@*****.**', email_optin=True, ) learner_user = learner_profile.user ProgramEnrollmentFactory.create(user=learner_user, program=self.program) CachedEnrollment.objects.filter(user=learner_user).delete() self.client.force_login(learner_user) url = reverse(self.url_name, kwargs={'student_id': self.recipient_user.profile.student_id}) resp_post = self.client.post(url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_403_FORBIDDEN CachedEnrollmentFactory.create(user=learner_user, course_run__course__program=self.program, verified=True) resp_post = self.client.post(url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_200_OK
def test_multiple_success(self): """test retire_users command success with more than one user""" user_names = ["foo", "bar", "baz"] for user_name in user_names: user = UserFactory.create(username=user_name, is_active=True) user.profile.email_optin = True user.profile.save() UserSocialAuthFactory.create(user=user, provider='not_edx') for _ in range(TOTAL_PROGRAMS): ProgramEnrollmentFactory.create(user=user) assert user.is_active is True assert user.profile.email_optin is True assert UserSocialAuth.objects.filter(user=user).count() == 1 assert ProgramEnrollment.objects.filter( user=user).count() == TOTAL_PROGRAMS self.command.handle("retire_users", users=user_names) for user_name in user_names: user = User.objects.get(username=user_name) assert user.is_active is False assert user.profile.email_optin is False assert UserSocialAuth.objects.filter(user=user).count() == 0 assert ProgramEnrollment.objects.filter(user=user).count() == 0
def test_learner_view_needs_paid_learner(self, mock_mailgun_client): """ Test that a learner attempting to email another learner will only succeed if the sender has paid for a course run in a program that the recipient is enrolled in """ mock_mailgun_client.send_individual_email.return_value = Mock( spec=Response, status_code=status.HTTP_200_OK, json=mocked_json()) with mute_signals(post_save): learner_profile = ProfileFactory.create( user__email='*****@*****.**', email_optin=True, ) learner_user = learner_profile.user ProgramEnrollmentFactory.create(user=learner_user, program=self.program) CachedEnrollment.objects.filter(user=learner_user).delete() self.client.force_login(learner_user) url = reverse( self.url_name, kwargs={'student_id': self.recipient_user.profile.student_id}) resp_post = self.client.post(url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_403_FORBIDDEN CachedEnrollmentFactory.create( user=learner_user, course_run__course__program=self.program, verified=True) resp_post = self.client.post(url, data=self.request_data, format='json') assert resp_post.status_code == status.HTTP_200_OK
def setUpTestData(cls): super().setUpTestData() cls.program_enrollment_unsent = ProgramEnrollmentFactory.create() cls.program_enrollment_sent = ProgramEnrollmentFactory.create() cls.automatic_email = AutomaticEmailFactory.create(enabled=True) cls.percolate_query = cls.automatic_email.query cls.other_query = PercolateQueryFactory.create( source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) cls.percolate_queries = [cls.percolate_query, cls.other_query] cls.automatic_email_disabled = AutomaticEmailFactory.create( enabled=False) cls.percolate_query_disabled = cls.automatic_email_disabled.query SentAutomaticEmail.objects.create( automatic_email=cls.automatic_email, user=cls.program_enrollment_sent.user, status=SentAutomaticEmail.SENT, ) # User was sent email connected to a different AutomaticEmail SentAutomaticEmail.objects.create( user=cls.program_enrollment_unsent.user, automatic_email=AutomaticEmailFactory.create(enabled=True), status=SentAutomaticEmail.SENT, ) with mute_signals(post_save): cls.staff_user = UserFactory.create()
def test_add_moderators_to_channel(mocker, patched_users_api): """add_moderators_to_channel should add staff or instructors as moderators and subscribers""" channel = ChannelFactory.create() mods = [] for _ in range(3): program = ChannelProgramFactory.create(channel=channel).program with mute_signals(post_save): mods += [ RoleFactory.create( program=program, user=ProfileFactory.create().user ).user for _ in range(5) ] for __ in range(5): # Add some users to the channel to show that being part of the channel is not enough to be added as a mod ProgramEnrollmentFactory.create(program=program) create_stub, _ = patched_users_api create_stub.reset_mock() add_subscriber_stub = mocker.patch('discussions.api.add_subscriber_to_channel', autospec=True) add_moderator_stub = mocker.patch('discussions.api.add_moderator_to_channel', autospec=True) api.add_moderators_to_channel(channel.name) for mod in mods: add_subscriber_stub.assert_any_call(channel.name, mod.discussion_user.username) add_moderator_stub.assert_any_call(channel.name, mod.discussion_user.username) create_stub.assert_any_call(mod.discussion_user) assert add_subscriber_stub.call_count == len(mods) assert add_moderator_stub.call_count == len(mods) assert create_stub.call_count == len(mods)
def create_learners_in_program(self, learners_count, privacy=Profile.PUBLIC): """helper function to create a list of learners in the program""" for _ in range(0, learners_count): user = create_learner_with_image(privacy) ProgramEnrollmentFactory.create( user=user, program=self.program, )
def test_course_team_email_unpaid(self): """ Test that an attempt to send an email to the course team of an unpaid course will fail """ self.client.force_login(self.staff_user) new_course = CourseFactory.create(contact_email='*****@*****.**') ProgramEnrollmentFactory.create(user=self.staff_user, program=new_course.program) url = reverse(self.url_name, kwargs={'course_id': new_course.id}) resp = self.client.post(url, data=self.request_data, format='json') assert resp.status_code == status.HTTP_403_FORBIDDEN
def test_program_enrollment_clear_upon_profile_deletion(self): """ Test that all ProgramEnrollments are cleared from the index after the User's Profile has been deleted """ with mute_signals(post_save): profile = ProfileFactory.create() ProgramEnrollmentFactory.create(user=profile.user) ProgramEnrollmentFactory.create(user=profile.user) assert es.search()['total'] == 2 profile.delete() assert es.search()['total'] == 0
def test_course_team_email_unpaid(self): """ Test that an attempt to send an email to the course team of an unpaid course will fail """ self.client.force_login(self.staff_user) new_course = CourseFactory.create(contact_email='*****@*****.**') ProgramEnrollmentFactory.create(user=self.staff_user, program=new_course.program) url = reverse(self.url_name, kwargs={'course_id': new_course.id}) resp = self.client.post(url, data=self.request_data, format='json') assert resp.status_code == status.HTTP_403_FORBIDDEN
def test_authorize_enrollment_for_exam_run(self, authorize_for_latest_passed_course_mock): """Test authorize_enrollment_for_exam_run()""" program, _ = create_program() course = program.course_set.first() enrollment_1 = ProgramEnrollmentFactory.create(program=program) enrollment_2 = ProgramEnrollmentFactory.create(program=program) exam_run = ExamRunFactory.create(course=course) authorize_enrollment_for_exam_run([enrollment_1.id, enrollment_2.id], exam_run.id) assert authorize_for_latest_passed_course_mock.call_count == 2 authorize_for_latest_passed_course_mock.assert_any_call(enrollment_1.user, exam_run) authorize_for_latest_passed_course_mock.assert_any_call(enrollment_2.user, exam_run)
def setUpTestData(cls): cls.user = UserFactory.create(username='******', email='*****@*****.**') cls.course_runs = { 'fa': CourseRunFactory.create( course__program__financial_aid_availability=True), 'non_fa': CourseRunFactory.create( course__program__financial_aid_availability=False) } for course_run in cls.course_runs.values(): ProgramEnrollmentFactory.create(user=cls.user, program=course_run.course.program)
def test_bulk_authorize_for_exam_run_multiple(self): """Test that we check all program enrollments""" ProgramEnrollmentFactory.create(program=self.program) exam_run = ExamRunFactory.create(course=self.course_run.course) assert ExamAuthorization.objects.filter( course=exam_run.course, ).count() == 0 bulk_authorize_for_exam_run(exam_run) assert ExamAuthorization.objects.filter( course=exam_run.course, user=self.user ).count() == 1
def test_program_enrollment_add(self): """ Test that a newly created ProgramEnrollment is indexed properly """ assert es.search()['total'] == 0 program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(), [program_enrollment])
def test_document_needs_update_missing(self): """ If a document doesn't exist on Elasticsearch, document_needs_update should return true """ with mute_signals(post_save): enrollment = ProgramEnrollmentFactory.create() assert document_needs_updating(enrollment) is True
def test_program_enrollment_add(self, index_type, mock_on_commit): """ Test that a newly created ProgramEnrollment is indexed properly """ assert es.search(index_type)['total'] == 0 program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_role_delete(self, role, index_type, mock_on_commit): """ Test that `is_learner` status is restore once role is removed for a user. """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT sources = get_sources(es.search(index_type)) # user is learner assert sources[0]['program']['is_learner'] is True Role.objects.create(user=program_enrollment.user, program=program_enrollment.program, role=role) assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT # user is not learner sources = get_sources(es.search(index_type)) assert sources[0]['program']['is_learner'] is False # when staff role is deleted Role.objects.filter(user=program_enrollment.user, program=program_enrollment.program, role=role).delete() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT sources = get_sources(es.search(index_type)) # user is learner assert sources[0]['program']['is_learner'] is True
def test_update_during_recreate_index(self): """ If an indexing action happens during a recreate_index it should update all active indices """ conn = get_conn(verify=False) recreate_index() temp_aliases = {} index_types = [PRIVATE_ENROLLMENT_INDEX_TYPE, PUBLIC_ENROLLMENT_INDEX_TYPE] for index_type in index_types: # create temporary index temp_index = make_backing_index_name() temp_alias = make_alias_name(index_type=index_type, is_reindexing=True) clear_and_create_index(temp_index, index_type=index_type) conn.indices.put_alias(index=temp_index, name=temp_alias) temp_aliases[index_type] = temp_alias with patch('search.signals.transaction.on_commit', side_effect=lambda callback: callback()): program_enrollment = ProgramEnrollmentFactory.create() for index_type in index_types: assert_search(es.search(index_type), [program_enrollment], index_type=index_type) # Temp alias should get updated temp_alias = temp_aliases[index_type] refresh_index(temp_alias) temp_hits = conn.search(index=temp_alias)['hits'] assert_search(temp_hits, [program_enrollment], index_type=index_type)
def test_role_delete(self, role, index_type, mock_on_commit): """ Test that `is_learner` status is restore once role is removed for a user. """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT sources = get_sources(es.search(index_type)) # user is learner assert sources[0]['program']['is_learner'] is True Role.objects.create( user=program_enrollment.user, program=program_enrollment.program, role=role ) assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT # user is not learner sources = get_sources(es.search(index_type)) assert sources[0]['program']['is_learner'] is False # when staff role is deleted Role.objects.filter( user=program_enrollment.user, program=program_enrollment.program, role=role ).delete() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT sources = get_sources(es.search(index_type)) # user is learner assert sources[0]['program']['is_learner'] is True
def test_update_percolate_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create( user=profile.user) membership = PercolateQueryMembershipFactory.create( user=profile.user, query=query, is_member=is_member, needs_update=False) with patch('search.api._search_percolate_queries', return_value=[query.id] if query_matches else []) as search_percolate_queries_mock: update_percolate_memberships(profile.user, source_type) search_percolate_queries_mock.assert_called_once_with( program_enrollment) membership.refresh_from_db() assert membership.needs_update is (is_member is not query_matches)
def setUpTestData(cls): cls.program, _ = create_program(past=True) cls.course_run = cls.program.course_set.first().courserun_set.first() cls.course = cls.course_run.course cls.program_enrollment = ProgramEnrollmentFactory.create( program=cls.program) cls.user = cls.program_enrollment.user with mute_signals(post_save): cls.final_grades = sorted( [ FinalGradeFactory.create(user=cls.user, course_run=cls.course_run, passed=False, status=FinalGradeStatus.PENDING), FinalGradeFactory.create(user=cls.user, course_run__course=cls.course, passed=True, status=FinalGradeStatus.COMPLETE), FinalGradeFactory.create(user=cls.user, course_run__course=cls.course, passed=True, status=FinalGradeStatus.COMPLETE), ], key=lambda final_grade: final_grade.course_run.end_date, reverse=True)
def setUpTestData(cls): cls.program, _ = create_program(past=True) cls.course_run = cls.program.course_set.first().courserun_set.first() cls.course = cls.course_run.course cls.program_enrollment = ProgramEnrollmentFactory.create(program=cls.program) cls.user = cls.program_enrollment.user with mute_signals(post_save): cls.final_grades = sorted([ FinalGradeFactory.create( user=cls.user, course_run=cls.course_run, passed=False, status=FinalGradeStatus.PENDING ), FinalGradeFactory.create( user=cls.user, course_run__course=cls.course, passed=True, status=FinalGradeStatus.COMPLETE ), FinalGradeFactory.create( user=cls.user, course_run__course=cls.course, passed=True, status=FinalGradeStatus.COMPLETE ), ], key=lambda final_grade: final_grade.course_run.end_date, reverse=True)
def test_update_percolate_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create(user=profile.user) membership = PercolateQueryMembershipFactory.create( user=profile.user, query=query, is_member=is_member, needs_update=False ) with patch( 'search.api._search_percolate_queries', return_value=[query.id] if query_matches else [] ) as search_percolate_queries_mock: update_percolate_memberships(profile.user, source_type) search_percolate_queries_mock.assert_called_once_with(program_enrollment) membership.refresh_from_db() assert membership.needs_update is (is_member is not query_matches)
def test_authorize_exam_runs(self, authorized, authorize_for_latest_passed_course_mock): """Test authorize_exam_runs()""" program, _ = create_program() course = program.course_set.first() enrollment = ProgramEnrollmentFactory.create(program=program) current_run = ExamRunFactory.create(course=course, authorized=authorized) past_run = ExamRunFactory.create(course=course, scheduling_future=True, authorized=authorized) future_run = ExamRunFactory.create(course=course, scheduling_past=True, authorized=authorized) authorize_exam_runs() if authorized: assert authorize_for_latest_passed_course_mock.call_count == 0 else: assert authorize_for_latest_passed_course_mock.call_count == 2 authorize_for_latest_passed_course_mock.assert_any_call( enrollment.user, current_run) authorize_for_latest_passed_course_mock.assert_any_call( enrollment.user, future_run) for exam_run in (current_run, future_run): exam_run.refresh_from_db() assert exam_run.authorized is True past_run.refresh_from_db() assert past_run.authorized is False
def test_populate_query_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profiles = [ ProfileFactory.create(filled_out=True) for _ in range(3) ] program_enrollments = [ ProgramEnrollmentFactory.create(user=profile.user) for profile in profiles ] with patch('search.api._search_percolate_queries', return_value=[query.id] if query_matches else []) as search_percolate_queries_mock: populate_query_memberships(query.id) assert search_percolate_queries_mock.call_count == len( program_enrollments) for program_enrollment in program_enrollments: search_percolate_queries_mock.assert_any_call(program_enrollment) for profile in profiles: membership = PercolateQueryMembership.objects.get( user=profile.user, query=query) assert membership.is_member is query_matches assert membership.needs_update is True
def test_update_during_recreate_index(self): """ If an indexing action happens during a recreate_index it should update all active indices """ conn = get_conn(verify=False) recreate_index() temp_aliases = {} index_types = [ PRIVATE_ENROLLMENT_INDEX_TYPE, PUBLIC_ENROLLMENT_INDEX_TYPE ] for index_type in index_types: # create temporary index temp_index = make_backing_index_name() temp_alias = make_alias_name(index_type=index_type, is_reindexing=True) clear_and_create_index(temp_index, index_type=index_type) conn.indices.put_alias(index=temp_index, name=temp_alias) temp_aliases[index_type] = temp_alias with patch('search.signals.transaction.on_commit', side_effect=lambda callback: callback()): program_enrollment = ProgramEnrollmentFactory.create() for index_type in index_types: assert_search(es.search(index_type), [program_enrollment], index_type=index_type) # Temp alias should get updated temp_alias = temp_aliases[index_type] refresh_index(temp_alias) temp_hits = conn.search(index=temp_alias)['hits'] assert_search(temp_hits, [program_enrollment], index_type=index_type)
def test_document_needs_update_missing(self): """ If a document doesn't exist on Elasticsearch, document_needs_update should return true """ with mute_signals(post_save): enrollment = ProgramEnrollmentFactory.create() assert document_needs_updating(enrollment) is True
def test_program_enrollment_delete(self, index_type, mock_on_commit): """ Test that ProgramEnrollment is removed from index after the user is removed """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT program_enrollment.user.delete() assert es.search(index_type)['total'] == 0
def test_program_enrollment_add(self, index_type, mock_on_commit): """ Test that a newly created ProgramEnrollment is indexed properly """ assert es.search(index_type)['total'] == 0 program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_employment_add(self): """ Test that Employment is indexed after being added """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search()['total'] == 1 EmploymentFactory.create(profile=program_enrollment.user.profile) assert_search(es.search(), [program_enrollment])
def setUpTestData(cls): super().setUpTestData() with mute_signals(post_save): staff_profile = ProfileFactory.create() cls.staff_user = staff_profile.user cls.course = CourseFactory.create( contact_email='*****@*****.**', program__financial_aid_availability=False ) course_run = CourseRunFactory.create(course=cls.course) ProgramEnrollmentFactory.create(user=cls.staff_user, program=cls.course.program) CachedEnrollmentFactory.create(user=cls.staff_user, course_run=course_run) cls.url_name = 'course_team_mail_api' cls.request_data = { 'email_subject': 'email subject', 'email_body': 'email body' }
def test_program_enrollment_delete(self): """ Test that ProgramEnrollment is removed from index after the user is removed """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search()['total'] == 1 program_enrollment.user.delete() assert es.search()['total'] == 0
def test_remove_program_enrolled_user(self): """ Test that remove_program_enrolled_user removes the user from the index for that program """ program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(), [program_enrollment]) remove_program_enrolled_user(program_enrollment) assert_search(es.search(), [])
def test_program_enrollment_delete(self, index_type, mock_on_commit): """ Test that ProgramEnrollment is removed from index after the user is removed """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT program_enrollment.user.delete() assert es.search(index_type)['total'] == 0
def test_program_record_with_random_user(client): """Test that a request for program record with random (non-owner) user results in 404""" user = UserFactory.create() client.force_login(user) enrollment = ProgramEnrollmentFactory.create() resp = client.get( reverse("grade_records", kwargs=dict(enrollment_id=enrollment.id))) assert resp.status_code == status.HTTP_404_NOT_FOUND
def test_index_users(self): """ When we run the index_users task we should index user's program enrollments and send them automatic emails """ enrollment1 = ProgramEnrollmentFactory.create() enrollment2 = ProgramEnrollmentFactory.create(user=enrollment1.user) index_users([enrollment1.user.id]) assert self.index_program_enrolled_users_mock.call_count == 1 assert sorted(self.index_program_enrolled_users_mock.call_args[0][0], key=lambda _enrollment: _enrollment.id) == sorted( [enrollment1, enrollment2], key=lambda _enrollment: _enrollment.id) for enrollment in [enrollment1, enrollment2]: self.send_automatic_emails_mock.assert_any_call(enrollment) self.update_percolate_memberships_mock.assert_any_call( enrollment.user, PercolateQuery.DISCUSSION_CHANNEL_TYPE) self.refresh_index_mock.assert_called_with()
def test_employment_add(self, index_type, mock_on_commit): """ Test that Employment is indexed after being added """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT EmploymentFactory.create(profile=program_enrollment.user.profile, end_date=None) assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_remove_program_enrolled_user(self, index_type, mock_on_commit): """ Test that remove_program_enrolled_user removes the user from the index for that program """ program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(index_type), [program_enrollment], index_type=index_type) remove_program_enrolled_user(program_enrollment.id) assert_search(es.search(index_type), [], index_type=index_type)
def test_education_add(self, index_type, mock_on_commit): """ Test that Education is indexed after being added """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT EducationFactory.create(profile=program_enrollment.user.profile) assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_not_percolated(self, mock_on_commit): """If there are no percolated queries we should return an empty queryset""" with mute_signals(post_save): profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create(user=profile.user) assert list( search_percolate_queries( program_enrollment.id, PercolateQuery.AUTOMATIC_EMAIL_TYPE)) == []
def test_populate_query_inactive_memberships(self, is_active, has_profile, mock_on_commit): """ Tests that memberships are handled correctly for users who are inactive or have no profiles """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) user = UserFactory.create(is_active=is_active) if has_profile: ProfileFactory.create(user=user, filled_out=True) ProgramEnrollmentFactory.create(user=user) with patch('search.api.get_conn') as es_mock: populate_query_memberships(query.id) assert es_mock.return_value.percolate.call_count == (1 if has_profile and is_active else 0) assert PercolateQueryMembership.objects.filter(user=user, query=query).count() == ( 1 if is_active else 0 )
def test_employment_delete(self, index_type, mock_on_commit): """ Test that Employment is removed from index after being deleted """ program_enrollment = ProgramEnrollmentFactory.create() employment = EmploymentFactory.create(profile=program_enrollment.user.profile, end_date=None) assert_search(es.search(index_type), [program_enrollment], index_type=index_type) employment.delete() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_education_delete(self, index_type, mock_on_commit): """ Test that Education is removed from index after being deleted """ program_enrollment = ProgramEnrollmentFactory.create() education = EducationFactory.create(profile=program_enrollment.user.profile) assert_search(es.search(index_type), [program_enrollment], index_type=index_type) education.delete() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_staff_and_instructor_in_other_program_no_results(self, role, is_enrolled): """A user with staff or instructor role in another program gets no results""" user = UserFactory.create() Role.objects.create( user=user, program=self.program2, role=role, ) if is_enrolled: ProgramEnrollmentFactory.create(user=user, program=self.program1) params = { "post_filter": { "term": {"program.id": self.program1.id} } } self.client.force_login(user) resp = self.assert_status_code(json=params) assert len(resp.data['hits']['hits']) == 0
def test_remove_program_enrolled_user(self, index_type, mock_on_commit): """ Test that remove_program_enrolled_user removes the user from the index for that program """ program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(index_type), [program_enrollment], index_type=index_type) remove_program_enrolled_user(program_enrollment.id) assert_search(es.search(index_type), [], index_type=index_type)
def test_education_update(self, index_type, mock_on_commit): """ Test that Education is reindexed after being updated """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT education = EducationFactory.create(profile=program_enrollment.user.profile) education.school_city = 'city' education.save() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_past_employment_add(self, index_type, mock_on_commit): """ Test that past work history is not indexed """ program_enrollment = ProgramEnrollmentFactory.create() EmploymentFactory.create(profile=program_enrollment.user.profile, end_date=None) EmploymentFactory.create(profile=program_enrollment.user.profile) search_result = es.search(index_type)['hits'][0]['_source']['profile']['work_history'] assert len(search_result) == 1 self.assertFalse(search_result[0]['end_date'])
def test_profile_update(self, index_type, mock_on_commit): """ Test that ProgramEnrollment is reindexed after the User's Profile has been updated """ program_enrollment = ProgramEnrollmentFactory.create() assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT profile = program_enrollment.user.profile profile.first_name = 'updated' profile.save() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_document_needs_update(self, mocked_on_commit): """ If a document on ES is out of date with the database, document_needs_update should return true """ enrollment = ProgramEnrollmentFactory.create() assert document_needs_updating(enrollment) is False with mute_signals(post_save): enrollment.user.profile.first_name = "Changed" enrollment.user.profile.save() assert document_needs_updating(enrollment) is True
def test_add_edx_record(self, index_type, mock_on_commit): """ Test that cached edX records are indexed after being added """ program_enrollment = ProgramEnrollmentFactory.create() for edx_cached_model_factory in [CachedCertificateFactory, CachedEnrollmentFactory, CachedCurrentGradeFactory]: assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT course = CourseFactory.create(program=program_enrollment.program) course_run = CourseRunFactory.create(course=course) edx_cached_model_factory.create(user=program_enrollment.user, course_run=course_run) index_program_enrolled_users([program_enrollment]) assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_percolate_failure_user_unenroll_program(self, mock_on_commit): """ If search_percolate fails we should raise an Exception with some useful information for Sentry Case when there is not program enrollment. """ with mute_signals(post_save): profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create(user=profile.user) program_enrollment_id = program_enrollment.id program_enrollment.delete() with self.assertRaises(ProgramEnrollment.DoesNotExist): search_percolate_queries(program_enrollment_id, "doesnt_matter")
def test_update_index(self, index_type): """ Test that recreate_index will clear old data and index all profiles """ with patch('search.signals.transaction.on_commit', side_effect=lambda callback: callback()): program_enrollment = ProgramEnrollmentFactory.create() assert_search(es.search(index_type), [program_enrollment], index_type=index_type) remove_program_enrolled_user(program_enrollment.id) assert_search(es.search(index_type), [], index_type=index_type) # recreate_index should index the program-enrolled user recreate_index() assert_search(es.search(index_type), [program_enrollment], index_type=index_type)
def test_delete_edx_record(self, index_type, mock_on_commit): """ Test that a cached edX record is removed from index after being deleted """ program_enrollment = ProgramEnrollmentFactory.create() for edx_cached_model_factory in [CachedCertificateFactory, CachedEnrollmentFactory, CachedCurrentGradeFactory]: course = CourseFactory.create(program=program_enrollment.program) course_run = CourseRunFactory.create(course=course) edx_record = edx_cached_model_factory.create(user=program_enrollment.user, course_run=course_run) index_program_enrolled_users([program_enrollment]) assert_search(es.search(index_type), [program_enrollment], index_type=index_type) edx_record.delete() index_program_enrolled_users([program_enrollment]) assert_search(es.search(index_type), [program_enrollment], index_type=index_type)