コード例 #1
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
 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'
     }
コード例 #2
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
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)
コード例 #3
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
    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': ''})
コード例 #4
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
    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
コード例 #5
0
    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
コード例 #6
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
        }
コード例 #7
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
 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
コード例 #8
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    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
コード例 #9
0
    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
コード例 #10
0
    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)
コード例 #11
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)
コード例 #12
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
 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)
コード例 #13
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    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)
コード例 #14
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
 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
コード例 #15
0
 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
コード例 #16
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
 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'
     }
コード例 #17
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)
コード例 #18
0
 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)
コード例 #19
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    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
        )
コード例 #20
0
 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)
コード例 #21
0
ファイル: views_test.py プロジェクト: mitodl/micromasters
 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
コード例 #22
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)
コード例 #23
0
 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'])
コード例 #24
0
 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)
コード例 #25
0
 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)
コード例 #26
0
 def test_education_update(self):
     """
     Test that Education is reindexed after being updated
     """
     program_enrollment = ProgramEnrollmentFactory.create()
     assert es.search()['total'] == 1
     education = EducationFactory.create(
         profile=program_enrollment.user.profile)
     education.school_city = 'city'
     education.save()
     assert_search(es.search(), [program_enrollment])
コード例 #27
0
 def test_employment_update(self):
     """
     Test that Employment is reindexed after being updated
     """
     program_enrollment = ProgramEnrollmentFactory.create()
     assert es.search()['total'] == 1
     employment = EmploymentFactory.create(
         profile=program_enrollment.user.profile)
     employment.city = 'city'
     employment.save()
     assert_search(es.search(), [program_enrollment])
コード例 #28
0
    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)
コード例 #29
0
 def test_update_index(self):  # pylint: disable=no-self-use
     """
     Test that recreate_index will clear old data and index all profiles
     """
     recreate_index()
     program_enrollment = ProgramEnrollmentFactory.create()
     assert_search(es.search(), [program_enrollment])
     remove_program_enrolled_user(program_enrollment)
     assert_search(es.search(), [])
     # recreate_index should index the program-enrolled user
     recreate_index()
     assert_search(es.search(), [program_enrollment])
コード例 #30
0
    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
コード例 #31
0
 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'])
コード例 #32
0
 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)
コード例 #33
0
 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)
コード例 #34
0
 def test_employment_update(self, index_type, mock_on_commit):
     """
     Test that Employment is reindexed after being updated
     """
     program_enrollment = ProgramEnrollmentFactory.create()
     assert es.search(index_type)['total'] == DOC_TYPES_PER_ENROLLMENT
     employment = EmploymentFactory.create(
         profile=program_enrollment.user.profile, end_date=None)
     employment.city = 'city'
     employment.save()
     assert_search(es.search(index_type), [program_enrollment],
                   index_type=index_type)
コード例 #35
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)
コード例 #36
0
 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)
コード例 #37
0
 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)
コード例 #38
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    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
コード例 #39
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
 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")
コード例 #40
0
 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")
コード例 #41
0
    def test_index_users_check_if_changed(self, enrollment1_needs_update,
                                          enrollment2_needs_update):
        """
        If check_if_changed is true we should only update documents which need updating
        """
        enrollment1 = ProgramEnrollmentFactory.create()
        enrollment2 = ProgramEnrollmentFactory.create()

        needs_update_list = []
        if enrollment1_needs_update:
            needs_update_list.append(enrollment1)
        if enrollment2_needs_update:
            needs_update_list.append(enrollment2)

        def fake_needs_updating(_enrollment):
            """Fake document_needs_update to conform to test data"""
            return _enrollment in needs_update_list

        self.document_needs_updating_mock.side_effect = fake_needs_updating
        index_users([enrollment1.user.id, enrollment2.user.id],
                    check_if_changed=True)

        expected_enrollments = []
        if enrollment1_needs_update:
            expected_enrollments.append(enrollment1)
        if enrollment2_needs_update:
            expected_enrollments.append(enrollment2)

        self.document_needs_updating_mock.assert_any_call(enrollment1)
        self.document_needs_updating_mock.assert_any_call(enrollment2)
        if len(needs_update_list) > 0:
            self.index_program_enrolled_users_mock.assert_called_once_with(
                needs_update_list)
            for enrollment in needs_update_list:
                self.send_automatic_emails_mock.assert_any_call(enrollment)
                self.update_percolate_memberships_mock.assert_any_call(
                    enrollment.user, PercolateQuery.DISCUSSION_CHANNEL_TYPE)
        else:
            assert self.index_program_enrolled_users_mock.called is False
            assert self.send_automatic_emails_mock.called is False
コード例 #42
0
 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'
     }
コード例 #43
0
    def test_not_analyzed(self):
        """
        At the moment no string fields in the mapping should be 'analyzed' since there's no field
        supporting full text search.
        """
        program_enrollment = ProgramEnrollmentFactory.create()
        EducationFactory.create(profile=program_enrollment.user.profile)
        EmploymentFactory.create(profile=program_enrollment.user.profile)

        mapping = es.get_mappings()
        nodes = list(traverse_mapping(mapping))
        for node in nodes:
            if node.get('type') == 'string':
                assert node['index'] == 'not_analyzed'
コード例 #44
0
    def test_financial_aid_with_application_with_no_residence(self):
        """
        Test that financialAid request serializer throws exception when profile is not filled out.
        """
        user = UserFactory.create()
        assert user.profile.filled_out is False
        ProgramEnrollmentFactory.create(user=user, program=self.program)
        serializer = FinancialAidRequestSerializer(
            data={
                'program_id': self.program.id,
                'tier_program': self.min_tier_program,
                'date_documents_sent': None,
                'original_currency': 'USD',
                'original_income': 1000
            },
            context={'request': MagicMock(user=user)})
        with self.assertRaises(ValidationError) as ex:
            serializer.is_valid(raise_exception=True)
            serializer.save()

        assert ex.exception.detail == {
            'non_field_errors': ['Profile is not complete']
        }
コード例 #45
0
    def test_single_success_user_with_email(self):
        """test retire_users command with email success"""
        user = UserFactory.create(email='*****@*****.**', 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.refresh_from_db()
        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
コード例 #46
0
 def test_add_edx_record(self):
     """
     Test that cached edX records are indexed after being added
     """
     program_enrollment = ProgramEnrollmentFactory.create()
     for edx_cached_model_factory in [
             CachedCertificateFactory, CachedEnrollmentFactory
     ]:
         assert es.search()['total'] == 1
         course_run = CourseRunFactory.create(
             program=program_enrollment.program)
         edx_cached_model_factory.create(user=program_enrollment.user,
                                         course_run=course_run)
         assert_search(es.search(), [program_enrollment])
コード例 #47
0
 def setUpTestData(cls):
     cls.program, _ = create_program(past=True)
     cls.course_run = cls.program.course_set.first().courserun_set.first()
     cls.program_enrollment = ProgramEnrollmentFactory.create(program=cls.program)
     cls.user = cls.program_enrollment.user
     create_order(cls.user, cls.course_run)
     with mute_signals(post_save):
         CachedEnrollmentFactory.create(user=cls.user, course_run=cls.course_run)
         cls.final_grade = FinalGradeFactory.create(
             user=cls.user,
             course_run=cls.course_run,
             passed=True,
             course_run_paid_on_edx=False,
         )
コード例 #48
0
 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)
コード例 #49
0
    def test_filled_out(self):
        """
        Search results should only include profiles which are filled out
        """
        program = self.program1
        filled_out_ids = list(ProgramEnrollment.objects.filter(program=program).values_list('user_id', flat=True))
        enrollment_not_filled_out = ProgramEnrollmentFactory.create(
            user__profile__filled_out=False,
            program=program,
        )

        resp = self.assert_status_code()
        user_ids_in_hits = self.get_user_ids_in_hits(resp.data['hits']['hits'])
        assert sorted(user_ids_in_hits) == sorted(filled_out_ids)
        assert enrollment_not_filled_out.user.id not in user_ids_in_hits
コード例 #50
0
 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)
コード例 #51
0
 def test_delete_edx_record(self):
     """
     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
     ]:
         course_run = CourseRunFactory.create(
             program=program_enrollment.program)
         edx_record = edx_cached_model_factory.create(
             user=program_enrollment.user, course_run=course_run)
         assert_search(es.search(), [program_enrollment])
         edx_record.delete()
         assert_search(es.search(), [program_enrollment])
コード例 #52
0
    def test_index_program_enrolled_users(self):
        """
        When we run the index_program_enrolled_users task we should index them and send them automatic emails
        """
        enrollments = [ProgramEnrollmentFactory.create() for _ in range(2)]
        enrollment_ids = [enrollment.id for enrollment in enrollments]

        index_program_enrolled_users(enrollment_ids)
        assert list(
            self.index_program_enrolled_users_mock.call_args[0][0].values_list(
                'id', flat=True)) == enrollment_ids
        for enrollment in enrollments:
            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()
コード例 #53
0
 def test_update_edx_record(self):
     """
     Test that a cached edX record is reindexed after being updated
     """
     program_enrollment = ProgramEnrollmentFactory.create()
     for edx_cached_model_factory in [
             CachedCertificateFactory, CachedEnrollmentFactory
     ]:
         assert es.search()['total'] == 1
         course_run = CourseRunFactory.create(
             program=program_enrollment.program)
         edx_record = edx_cached_model_factory.create(
             user=program_enrollment.user, course_run=course_run)
         edx_record.data.update({'new': 'data'})
         edx_record.save()
         assert_search(es.search(), [program_enrollment])
コード例 #54
0
def test_program_record(client):
    """Test that a request for program record results in 200"""
    enrollment = ProgramEnrollmentFactory.create()
    resp = client.get(
        reverse("grade_records", kwargs=dict(record_hash=enrollment.hash)))
    assert resp.status_code == status.HTTP_200_OK
    assert is_subset_dict(
        {
            'record_hash': enrollment.hash,
            'program_title': enrollment.program.title,
            'program_status': 'partially',
            'profile': {
                'username': enrollment.user.username
            },
            'last_updated': ''
        }, resp.context_data)
コード例 #55
0
    def test_analyzed(self, mock_on_commit):
        """
        Most string fields in the mapping should be 'analyzed' since we don't want to
        tokenize strings arbitrarily when filtering on fields.
        """
        program_enrollment = ProgramEnrollmentFactory.create()
        EducationFactory.create(profile=program_enrollment.user.profile)
        EmploymentFactory.create(profile=program_enrollment.user.profile)

        for index_type in ALL_INDEX_TYPES:
            mapping = es.get_mappings(index_type)
            nodes = list(traverse_mapping(mapping, ""))
            for key, node in nodes:
                if key == "folded":
                    assert node['analyzer'] == "folding"
                elif node.get('type') == 'string':
                    assert node['index'] == 'not_analyzed'
コード例 #56
0
 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)
コード例 #57
0
    def test_role_add(self, role, index_type, mock_on_commit):
        """
        Test that `is_learner` status is change when role is save
        """
        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
コード例 #58
0
def test_program_record(client):
    """Test that a request for program record results in 200"""
    user = UserFactory.create()
    enrollment = ProgramEnrollmentFactory.create(user=user)
    client.force_login(user)
    resp = client.get(
        reverse("grade_records", kwargs=dict(enrollment_id=enrollment.id)))
    assert resp.status_code == status.HTTP_200_OK
    assert is_subset_dict(
        {
            'is_public': False,
            'is_owner': True,
            'program_title': enrollment.program.title,
            'program_status': 'partially',
            'profile': {
                'username': enrollment.user.username
            }
        }, resp.context_data)
コード例 #59
0
 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)
コード例 #60
0
    def test_search_percolate_queries(self, mock_on_commit):
        """search_percolate_queries should find all PercolateQuery which match the given ProgramEnrollment"""
        with mute_signals(post_save):
            profile = ProfileFactory.create(filled_out=True)
        program_enrollment = ProgramEnrollmentFactory.create(user=profile.user)
        matching_query = {
            "query": {
                "match": {
                    "profile.first_name": profile.first_name,
                }
            }
        }
        query = PercolateQuery.objects.create(
            query=matching_query,
            original_query={},
            source_type=PercolateQuery.AUTOMATIC_EMAIL_TYPE,
        )

        # Another query which matches but has a different source_type
        PercolateQuery.objects.create(
            query=matching_query,
            original_query={},
            source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE,
        )

        # Another query that doesn't match
        PercolateQuery.objects.create(
            query={"query": {
                "match": {
                    "profile.first_name": "missing",
                }
            }},
            original_query={},
            source_type=PercolateQuery.AUTOMATIC_EMAIL_TYPE)

        # Only the first appears in the results
        assert list(
            search_percolate_queries(
                program_enrollment.id,
                PercolateQuery.AUTOMATIC_EMAIL_TYPE,
            ).values_list("id", flat=True)) == [query.id]