コード例 #1
0
    def two_no_show_exam_attempts(self):
        """Passed and later failed course, and two exam attempts"""
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)

        course = Course.objects.get(title='Digital Learning 200')
        course_run = CourseRunFactory(course=course, edx_course_key='course-passed')
        call_command(
            "alter_data", 'set_to_passed', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key
        )

        ExamProfileFactory.create(status='success', profile=self.user.profile)
        # run 1
        exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True)
        ExamAuthorizationFactory.create(
            user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True, exam_no_show=True
        )
        # run 2
        exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True)
        ExamAuthorizationFactory.create(
            user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True, exam_no_show=True
        )
        # another offered
        course_run = CourseRunFactory.create(course=course, edx_course_key='course-enrollable')
        call_command(
            "alter_data", 'set_to_offered', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key
        )
        course_run = CourseRunFactory.create(course=course, edx_course_key='course-failed')
        call_command(
            "alter_data", 'set_to_failed', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key, '--audit',
        )
コード例 #2
0
ファイル: utils_test.py プロジェクト: mitodl/micromasters
    def test_count_courses_mixed_fa(self):
        """
        Test count_courses_passed with mixed course-exam configuration
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program_financial_aid,
            edx_user_data=self.cached_edx_user_data
        )
        # this is course with exam run and the user has CombinedFinalGrade for it
        course_with_exam_1 = CourseFactory.create(program=self.program_financial_aid)
        ExamRunFactory.create(course=course_with_exam_1, date_grades_available=now_in_utc()-timedelta(weeks=1))
        CombinedFinalGrade.objects.create(user=self.user, course=course_with_exam_1, grade=0.7)
        # create course with exam run the user did not pass
        ExamRunFactory.create(
            course__program=self.program_financial_aid,
            date_grades_available=now_in_utc() - timedelta(weeks=1)
        )
        # another course with no exam
        FinalGradeFactory.create(
            user=self.user,
            course_run=self.crun_fa,
            passed=True
        )

        assert mmtrack.count_courses_passed() == 2
コード例 #3
0
ファイル: tasks_test.py プロジェクト: guaranta/micromasters
    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
コード例 #4
0
    def test_count_courses_mixed_fa(self):
        """
        Test count_courses_passed with mixed course-exam configuration
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program_financial_aid,
            edx_user_data=self.cached_edx_user_data
        )
        # this is course with exam run and the user has CombinedFinalGrade for it
        course_with_exam_1 = CourseFactory.create(program=self.program_financial_aid)
        ExamRunFactory.create(course=course_with_exam_1, date_grades_available=now_in_utc()-timedelta(weeks=1))
        CombinedFinalGrade.objects.create(user=self.user, course=course_with_exam_1, grade=0.7)
        # create course with exam run the user did not pass
        ExamRunFactory.create(
            course__program=self.program_financial_aid,
            date_grades_available=now_in_utc() - timedelta(weeks=1)
        )
        # another course with no exam
        FinalGradeFactory.create(
            user=self.user,
            course_run=self.crun_fa,
            passed=True
        )

        assert mmtrack.count_courses_passed() == 2
コード例 #5
0
    def create_missed_payment_for_exam(self, enrollable, future_exam, current):
        """Passed course but missed deadline to pay to take exam"""
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)
        if current:
            call_command(
                "alter_data", 'set_to_enrolled', '--username', 'staff',
                '--course-title', 'Digital Learning 200',
                '--missed-deadline'
            )
        else:
            call_command(
                "alter_data", 'set_past_run_to_passed', '--username', 'staff',
                '--course-title', 'Digital Learning 200', '--grade', '87', '--audit',
                '--missed-deadline'
            )
        course = Course.objects.get(title='Digital Learning 200')
        ExamProfileFactory.create(status='success', profile=self.user.profile)
        ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True)

        if enrollable:
            course_run = CourseRunFactory.create(course=course, edx_course_key='course-enrollable')
            call_command(
                "alter_data", 'set_to_offered', '--username', 'staff',
                '--course-run-key', course_run.edx_course_key
            )
        if future_exam:
            ExamRunFactory.create(
                scheduling_past=False,
                scheduling_future=True,
                authorized=True,
                course=course
            )
コード例 #6
0
    def test_get_exam_card_status_for_edx_exams(self, profile_status, expected_status, make_exam_run,
                                                make_profile, make_auth):
        """
        test get_exam_card_status
        """
        now = now_in_utc()
        exam_run = None
        if make_exam_run:
            exam_run = ExamRunFactory.create(
                course=self.course,
                date_first_eligible=now - timedelta(weeks=1),
                date_last_eligible=now + timedelta(weeks=1),
            )

        if make_profile:
            ExamProfileFactory.create(
                profile=self.user.profile,
                status=profile_status,
            )

        if make_auth:
            ExamAuthorizationFactory.create(
                user=self.user,
                status=ExamAuthorization.STATUS_SUCCESS,
                exam_run=exam_run,
            )

        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )

        assert mmtrack.get_exam_card_status() == expected_status
コード例 #7
0
ファイル: utils_test.py プロジェクト: mitodl/micromasters
 def test_get_overall_final_grade_for_course(self):
     """
     Test for get_overall_final_grade_for_course to return CombinedFinalGrade for course
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program_financial_aid,
         edx_user_data=self.cached_edx_user_data
     )
     finaid_course = self.crun_fa.course
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == ""
     FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, passed=True, grade=0.8)
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == "80"
     ExamRunFactory.create(course=finaid_course)
     CombinedFinalGrade.objects.create(user=self.user, course=finaid_course, grade="74")
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == "74"
コード例 #8
0
ファイル: utils_test.py プロジェクト: mitodl/micromasters
    def test_get_pearson_exam_status(self, profile_status, expected_status, make_exam_run,
                                     make_profile, make_auth, log_error_called, log_mock):
        """
        test get_pearson_exam_status
        """
        now = now_in_utc()
        exam_run = None
        if make_exam_run:
            exam_run = ExamRunFactory.create(
                course=self.course,
                date_first_eligible=now - timedelta(weeks=1),
                date_last_eligible=now + timedelta(weeks=1),
            )

        if make_profile:
            ExamProfileFactory.create(
                profile=self.user.profile,
                status=profile_status,
            )

        if make_auth:
            ExamAuthorizationFactory.create(
                user=self.user,
                status=ExamAuthorization.STATUS_SUCCESS,
                exam_run=exam_run,
            )

        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )

        assert mmtrack.get_pearson_exam_status() == expected_status
        assert log_mock.error.called is log_error_called
コード例 #9
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    def test_exam_authorization_attempts_consumed(self):
        """
        test exam_authorization when user passed and paid, but used all their attempts
        """
        create_order(self.user, self.course_run)
        mmtrack = get_mmtrack(self.user, self.program)
        self.assertTrue(mmtrack.has_paid(self.course_run.edx_course_key))
        self.assertTrue(mmtrack.has_passed_course(self.course_run.edx_course_key))
        old_run = ExamRunFactory.create(course=self.course_run.course)
        ExamAuthorizationFactory.create_batch(
            ATTEMPTS_PER_PAID_RUN,
            exam_run=old_run,
            user=mmtrack.user,
            course=self.course_run.course,
            exam_taken=True,
        )

        assert ExamAuthorization.objects.filter(
            user=mmtrack.user,
            course=self.course_run.course
        ).count() == 2

        with self.assertRaises(ExamAuthorizationException):
            authorize_for_exam_run(mmtrack, self.course_run, self.exam_run)

        # assert no new authorizations got created
        assert ExamAuthorization.objects.filter(
            user=mmtrack.user,
            course=self.course_run.course
        ).count() == 2
コード例 #10
0
    def test_exam_authorization_attempts_consumed(self):
        """
        test exam_authorization when user passed and paid, but used all their attempts
        """
        create_order(self.user, self.course_run)
        mmtrack = get_mmtrack(self.user, self.program)
        self.assertTrue(mmtrack.has_paid(self.course_run.edx_course_key))
        self.assertTrue(
            mmtrack.has_passed_course(self.course_run.edx_course_key))
        old_run = ExamRunFactory.create(course=self.course_run.course)
        ExamAuthorizationFactory.create_batch(
            ATTEMPTS_PER_PAID_RUN,
            exam_run=old_run,
            user=mmtrack.user,
            course=self.course_run.course,
            exam_taken=True,
        )

        assert ExamAuthorization.objects.filter(
            user=mmtrack.user, course=self.course_run.course).count() == 2

        with self.assertRaises(ExamAuthorizationException):
            authorize_for_exam_run(self.user, self.course_run, self.exam_run)

        # assert no new authorizations got created
        assert ExamAuthorization.objects.filter(
            user=mmtrack.user, course=self.course_run.course).count() == 2
コード例 #11
0
 def test_get_overall_final_grade_for_course(self):
     """
     Test for get_overall_final_grade_for_course to return CombinedFinalGrade for course
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program_financial_aid,
         edx_user_data=self.cached_edx_user_data
     )
     finaid_course = self.crun_fa.course
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == ""
     FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, passed=True, grade=0.8)
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == "80"
     ExamRunFactory.create(course=finaid_course)
     CombinedFinalGrade.objects.create(user=self.user, course=finaid_course, grade="74")
     assert mmtrack.get_overall_final_grade_for_course(finaid_course) == "74"
コード例 #12
0
    def test_update_exam_run(self, update_mock):
        """Test update_exam_run()"""
        exam_run = ExamRunFactory.create()

        update_exam_run(exam_run.id)
        update_exam_run(-exam_run.id)

        update_mock.assert_called_once_with(exam_run)
コード例 #13
0
ファイル: tasks_test.py プロジェクト: mitodl/micromasters
    def test_update_exam_run(self, update_mock):
        """Test update_exam_run()"""
        exam_run = ExamRunFactory.create()

        update_exam_run(exam_run.id)
        update_exam_run(-exam_run.id)

        update_mock.assert_called_once_with(exam_run)
コード例 #14
0
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.course_run = CourseRunFactory.create(
            course__program__financial_aid_availability=True)
        cls.exam_run = ExamRunFactory.create(
            course=cls.course_run.course,
            date_grades_available=now_in_utc() - timedelta(weeks=1))
        cls.not_passing_final_grade = FinalGradeFactory.create(
            user=cls.user, course_run=cls.course_run, grade=0.5, passed=False)
コード例 #15
0
    def test_exam_authorization_multiple_runs(self):
        """Test that if the first enrollment is invalid it checks the second, but not the third"""
        exam_run = ExamRunFactory.create(course=self.course)
        mmtrack = get_mmtrack(self.user, self.program)

        with patch('exams.api.authorize_for_exam_run') as mock:
            mock.side_effect = [ExamAuthorizationException('invalid'), None, None]
            authorize_for_latest_passed_course(mmtrack, exam_run)

        assert mock.call_count == 2
        for enrollment in self.final_grades[:2]:  # two most recent runs
            mock.assert_any_call(mmtrack, enrollment.course_run, exam_run)
コード例 #16
0
ファイル: tasks_test.py プロジェクト: mitodl/micromasters
    def test_authorize_exam_runs(self, authorized, bulk_authorize_for_exam_run_mock):
        """Test authorize_exam_runs()"""
        current_run = ExamRunFactory.create(authorized=authorized)
        past_run = ExamRunFactory.create(scheduling_future=True, authorized=authorized)
        future_run = ExamRunFactory.create(scheduling_past=True, authorized=authorized)

        authorize_exam_runs()

        if authorized:
            assert bulk_authorize_for_exam_run_mock.call_count == 0
        else:
            assert bulk_authorize_for_exam_run_mock.call_count == 2
            # past run shouldn't be called
            bulk_authorize_for_exam_run_mock.assert_any_call(current_run)
            bulk_authorize_for_exam_run_mock.assert_any_call(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
コード例 #17
0
    def test_bulk_authorize_for_exam_run_current(self):
        """Test that we do create an authorization for a current run"""
        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,
        ).count() == 1
コード例 #18
0
    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)
コード例 #19
0
 def test_get_corresponding_course_run(self, weeks, has_course_run):
     """test get_past_recent_exam_run"""
     now = now_in_utc()
     exam_run = ExamRunFactory.create(date_first_schedulable=now +
                                      datetime.timedelta(weeks=weeks))
     expected = CourseRunFactory.create(course=exam_run.course,
                                        start_date=now -
                                        datetime.timedelta(weeks=16),
                                        end_date=now)
     if has_course_run:
         self.assertEqual(get_corresponding_course_run(exam_run), expected)
     else:
         self.assertEqual(get_corresponding_course_run(exam_run), None)
コード例 #20
0
ファイル: models_test.py プロジェクト: mitodl/micromasters
    def test_has_future_exam(self):
        """Test course has exam"""
        course_run = self.create_run()

        assert course_run.has_future_exam is False
        exam_run = ExamRunFactory.create(course=course_run.course)
        assert course_run.has_future_exam is True
        exam_run.delete()

        assert course_run.has_future_exam is False
        exam_run = ExamRunFactory.create(
            course=course_run.course,
            date_last_eligible=now_in_utc().date(),
        )
        assert course_run.has_future_exam is False
        exam_run.delete()

        assert course_run.has_future_exam is False
        ExamRunFactory.create(
            course=course_run.course,
            date_last_eligible=(now_in_utc() - timedelta(days=1)).date(),
        )
        assert course_run.has_future_exam is False
コード例 #21
0
    def test_has_future_exam(self):
        """Test course has exam"""
        course_run = self.create_run()

        assert course_run.has_future_exam is False
        exam_run = ExamRunFactory.create(course=course_run.course)
        assert course_run.has_future_exam is True
        exam_run.delete()

        assert course_run.has_future_exam is False
        exam_run = ExamRunFactory.create(
            course=course_run.course,
            date_last_eligible=now_in_utc().date(),
        )
        assert course_run.has_future_exam is False
        exam_run.delete()

        assert course_run.has_future_exam is False
        ExamRunFactory.create(
            course=course_run.course,
            date_last_eligible=(now_in_utc() - timedelta(days=1)).date(),
        )
        assert course_run.has_future_exam is False
コード例 #22
0
    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
コード例 #23
0
    def test_authorize_exam_runs(self, authorized,
                                 bulk_authorize_for_exam_run_mock):
        """Test authorize_exam_runs()"""
        current_run = ExamRunFactory.create(authorized=authorized)
        past_run = ExamRunFactory.create(scheduling_future=True,
                                         authorized=authorized)
        future_run = ExamRunFactory.create(scheduling_past=True,
                                           authorized=authorized)

        authorize_exam_runs()

        if authorized:
            assert bulk_authorize_for_exam_run_mock.call_count == 0
        else:
            assert bulk_authorize_for_exam_run_mock.call_count == 2
            # past run shouldn't be called
            bulk_authorize_for_exam_run_mock.assert_any_call(current_run)
            bulk_authorize_for_exam_run_mock.assert_any_call(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
コード例 #24
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.course_run = CourseRunFactory.create(
            course__program__financial_aid_availability=True
        )
        cls.exam_run = ExamRunFactory.create(
            course=cls.course_run.course,
            date_grades_available=now_in_utc() - timedelta(weeks=1)
        )
        cls.not_passing_final_grade = FinalGradeFactory.create(
            user=cls.user,
            course_run=cls.course_run,
            grade=0.5,
            passed=False
        )
コード例 #25
0
    def test_bulk_authorize_for_exam_run_past(self):
        """Test that we don't create an authorization for a run in the past"""
        exam_run = ExamRunFactory.create(
            scheduling_past=True,
            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,
        ).count() == 0
コード例 #26
0
    def setUpTestData(cls):
        with mute_signals(post_save):
            profile = ProfileFactory.create()

        cls.program, _ = create_program(past=True)
        cls.user = profile.user
        cls.course_run = cls.program.course_set.first().courserun_set.first()
        with mute_signals(post_save):
            CachedEnrollmentFactory.create(user=cls.user, course_run=cls.course_run)
        cls.exam_run = ExamRunFactory.create(course=cls.course_run.course)
        with mute_signals(post_save):
            cls.final_grade = FinalGradeFactory.create(
                user=cls.user,
                course_run=cls.course_run,
                passed=True,
                course_run_paid_on_edx=False,
            )
コード例 #27
0
    def test_update_authorizations_for_exam_run(self, is_future, is_past):
        """Tests update_authorizations_for_exam_run()"""
        exam_run = ExamRunFactory.create(scheduling_future=is_future,
                                         scheduling_past=is_past)
        taken_auth = ExamAuthorizationFactory.create(
            exam_run=exam_run,
            exam_taken=True,
            status=ExamAuthorization.STATUS_SUCCESS,
            operation=ExamAuthorization.OPERATION_ADD,
        )
        pending_auth = ExamAuthorizationFactory.create(
            exam_run=exam_run,
            status=ExamAuthorization.STATUS_PENDING,
            operation=ExamAuthorization.OPERATION_ADD,
        )
        nonpending_auths = []
        for status in [
                ExamAuthorization.STATUS_IN_PROGRESS,
                ExamAuthorization.STATUS_FAILED,
                ExamAuthorization.STATUS_SUCCESS,
        ]:
            nonpending_auths.append(
                ExamAuthorizationFactory.create(
                    exam_run=exam_run,
                    status=status,
                    operation=ExamAuthorization.OPERATION_ADD,
                ))

        update_authorizations_for_exam_run(exam_run)

        taken_auth.refresh_from_db()
        assert taken_auth.status == ExamAuthorization.STATUS_SUCCESS
        assert taken_auth.operation == ExamAuthorization.OPERATION_ADD

        pending_auth.refresh_from_db()
        assert pending_auth.status == ExamAuthorization.STATUS_PENDING
        assert pending_auth.operation == ExamAuthorization.OPERATION_ADD

        for auth in nonpending_auths:
            auth.refresh_from_db()
            if is_past or is_future:
                assert auth.status != ExamAuthorization.STATUS_PENDING
                assert auth.operation == ExamAuthorization.OPERATION_ADD
            else:
                assert auth.status == ExamAuthorization.STATUS_PENDING
                assert auth.operation == ExamAuthorization.OPERATION_UPDATE
コード例 #28
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    def test_update_authorizations_for_exam_run(self, is_future, is_past):
        """Tests update_authorizations_for_exam_run()"""
        exam_run = ExamRunFactory.create(scheduling_future=is_future, scheduling_past=is_past)
        taken_auth = ExamAuthorizationFactory.create(
            exam_run=exam_run,
            exam_taken=True,
            status=ExamAuthorization.STATUS_SUCCESS,
            operation=ExamAuthorization.OPERATION_ADD,
        )
        pending_auth = ExamAuthorizationFactory.create(
            exam_run=exam_run,
            status=ExamAuthorization.STATUS_PENDING,
            operation=ExamAuthorization.OPERATION_ADD,
        )
        nonpending_auths = []
        for status in [
                ExamAuthorization.STATUS_IN_PROGRESS,
                ExamAuthorization.STATUS_FAILED,
                ExamAuthorization.STATUS_SUCCESS,
        ]:
            nonpending_auths.append(ExamAuthorizationFactory.create(
                exam_run=exam_run,
                status=status,
                operation=ExamAuthorization.OPERATION_ADD,
            ))

        update_authorizations_for_exam_run(exam_run)

        taken_auth.refresh_from_db()
        assert taken_auth.status == ExamAuthorization.STATUS_SUCCESS
        assert taken_auth.operation == ExamAuthorization.OPERATION_ADD

        pending_auth.refresh_from_db()
        assert pending_auth.status == ExamAuthorization.STATUS_PENDING
        assert pending_auth.operation == ExamAuthorization.OPERATION_ADD

        for auth in nonpending_auths:
            auth.refresh_from_db()
            if is_past or is_future:
                assert auth.status != ExamAuthorization.STATUS_PENDING
                assert auth.operation == ExamAuthorization.OPERATION_ADD
            else:
                assert auth.status == ExamAuthorization.STATUS_PENDING
                assert auth.operation == ExamAuthorization.OPERATION_UPDATE
コード例 #29
0
    def test_exam_authorization_course_mismatch(self):
        """
        test exam_authorization fails if course_run and exam_run courses mismatch
        """
        # Neither user has exam profile nor authorization.
        assert ExamProfile.objects.filter(
            profile=self.user.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.user, course=self.course_run.course).exists() is False

        exam_run = ExamRunFactory.create()

        with self.assertRaises(ExamAuthorizationException):
            authorize_for_exam_run(self.user, self.course_run, exam_run)

        # Assert user has exam profile and authorization.
        assert ExamProfile.objects.filter(
            profile=self.user.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.user, course=self.course_run.course).exists() is False
コード例 #30
0
def test_create_combined_final_grade(mocker):
    """
    Test create_combined_final_grade creates the grade when it is missing
    """
    update_mock = mocker.patch(
        'grades.api.update_or_create_combined_final_grade', autospec=True)
    course_run = CourseRunFactory.create(
        freeze_grade_date=now_in_utc() - timedelta(days=1),
        course__program__financial_aid_availability=True,
        course__program__live=True)
    course = course_run.course
    CourseRunGradingStatus.objects.create(course_run=course_run,
                                          status='complete')
    # Create exam run for course with date_grades_available True
    exam_run_grades_available = ExamRunFactory.create(
        course=course, date_grades_available=now_in_utc() - timedelta(weeks=1))

    exam_grades = ProctoredExamGradeFactory.create_batch(
        5,
        course=course,
        exam_run=exam_run_grades_available,
        passed=True,
    )
    for exam_grade in exam_grades[:3]:
        CombinedFinalGrade.objects.create(user=exam_grade.user,
                                          course=course,
                                          grade=0.7)
    # Only 3 users will have combined grades
    for exam_grade in exam_grades[3:]:
        FinalGradeFactory.create(user=exam_grade.user,
                                 course_run=course_run,
                                 passed=True)

    tasks.create_combined_final_grades.delay()

    assert update_mock.call_count == 2

    update_mock.assert_has_calls(
        [call(exam_grades[3].user, course),
         call(exam_grades[4].user, course)],
        any_order=True)
コード例 #31
0
ファイル: signals_test.py プロジェクト: mitodl/micromasters
    def setUpTestData(cls):
        with mute_signals(post_save):
            cls.profile = ProfileFactory.create()

        cls.program, _ = create_program(past=True)
        cls.course_run = cls.program.course_set.first().courserun_set.first()
        CachedCurrentGradeFactory.create(
            user=cls.profile.user,
            course_run=cls.course_run,
            data={
                "passed": True,
                "percent": 0.9,
                "course_key": cls.course_run.edx_course_key,
                "username": cls.profile.user.username
            }
        )
        CachedCertificateFactory.create(user=cls.profile.user, course_run=cls.course_run)
        cls.exam_run = ExamRunFactory.create(
            course=cls.course_run.course,
            date_first_schedulable=now_in_utc() - timedelta(days=1),
        )
コード例 #32
0
    def setUpTestData(cls):
        with mute_signals(post_save):
            cls.profile = ProfileFactory.create()

        cls.program, _ = create_program(past=True)
        cls.course_run = cls.program.course_set.first().courserun_set.first()
        CachedCurrentGradeFactory.create(user=cls.profile.user,
                                         course_run=cls.course_run,
                                         data={
                                             "passed": True,
                                             "percent": 0.9,
                                             "course_key":
                                             cls.course_run.edx_course_key,
                                             "username":
                                             cls.profile.user.username
                                         })
        CachedCertificateFactory.create(user=cls.profile.user,
                                        course_run=cls.course_run)
        cls.exam_run = ExamRunFactory.create(
            course=cls.course_run.course,
            date_first_schedulable=now_in_utc() - timedelta(days=1),
        )
コード例 #33
0
def test_create_combined_final_grade(mocker):
    """
    Test create_combined_final_grade creates the grade when it is missing
    """
    update_mock = mocker.patch('grades.api.update_or_create_combined_final_grade', autospec=True)
    course_run = CourseRunFactory.create(
        freeze_grade_date=now_in_utc()-timedelta(days=1),
        course__program__financial_aid_availability=True,
        course__program__live=True
    )
    course = course_run.course
    CourseRunGradingStatus.objects.create(course_run=course_run, status='complete')
    # Create exam run for course with date_grades_available True
    exam_run_grades_available = ExamRunFactory.create(
        course=course,
        date_grades_available=now_in_utc() - timedelta(weeks=1))

    exam_grades = ProctoredExamGradeFactory.create_batch(
        5,
        course=course,
        exam_run=exam_run_grades_available,
        passed=True,
    )
    for exam_grade in exam_grades[:3]:
        CombinedFinalGrade.objects.create(user=exam_grade.user, course=course, grade=0.7)
    # Only 3 users will have combined grades
    for exam_grade in exam_grades[3:]:
        FinalGradeFactory.create(user=exam_grade.user, course_run=course_run, passed=True)

    tasks.create_combined_final_grades.delay()

    assert update_mock.call_count == 2

    update_mock.assert_has_calls(
        [call(exam_grades[3].user, course), call(exam_grades[4].user, course)],
        any_order=True
    )
コード例 #34
0
    def test_exam_authorization_for_missed_payment_deadline(self):
        """
        test exam_authorization when user paid, but only after deadline
        """
        create_order(self.user, self.course_run)
        mmtrack = get_mmtrack(self.user, self.program)
        course = self.course_run.course
        now = now_in_utc()
        exam_run = ExamRunFactory.create(course=course,
                                         authorized=True,
                                         date_first_schedulable=now,
                                         date_last_schedulable=now +
                                         datetime.timedelta(weeks=2))

        self.course_run.upgrade_deadline = exam_run.date_first_schedulable - datetime.timedelta(
            weeks=8)
        self.course_run.save()
        # paid after deadline
        order_qset = Order.objects.filter(
            user=self.user, line__course_key=self.course_run.edx_course_key)
        order_qset.update(modified_at=now - datetime.timedelta(weeks=5))

        with patch('exams.api.get_corresponding_course_run') as mock:
            mock.side_effect = [self.course_run]
            with self.assertRaises(ExamAuthorizationException):
                authorize_for_exam_run(self.user, self.course_run,
                                       self.exam_run)

        assert ExamAuthorization.objects.filter(
            user=mmtrack.user, course=course).exists() is False
        # paid before deadline
        order_qset.update(modified_at=exam_run.date_first_schedulable -
                          datetime.timedelta(weeks=9))
        authorize_for_exam_run(self.user, self.course_run, self.exam_run)

        assert ExamAuthorization.objects.filter(user=mmtrack.user,
                                                course=course).exists() is True
コード例 #35
0
ファイル: api_test.py プロジェクト: mitodl/micromasters
    def test_exam_authorization_course_mismatch(self):
        """
        test exam_authorization fails if course_run and exam_run courses mismatch
        """
        mmtrack = get_mmtrack(self.user, self.program)

        # Neither user has exam profile nor authorization.
        assert ExamProfile.objects.filter(profile=mmtrack.user.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=mmtrack.user,
            course=self.course_run.course
        ).exists() is False

        exam_run = ExamRunFactory.create()

        with self.assertRaises(ExamAuthorizationException):
            authorize_for_exam_run(mmtrack, self.course_run, exam_run)

        # Assert user has exam profile and authorization.
        assert ExamProfile.objects.filter(profile=mmtrack.user.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=mmtrack.user,
            course=self.course_run.course
        ).exists() is False
コード例 #36
0
    def test_update_existing_combined_final_grade_for_exam_run(self, update_or_create_mock):
        """
        Test update_existing_combined_final_grade_for_exam_run
        """

        ProctoredExamGradeFactory.create(
            user=self.user,
            course=self.course_run.course,
            percentage_grade=0.6,
            passed=True,
            exam_run=self.exam_run
        )
        FinalGradeFactory.create(user=self.user, course_run__course=self.course_run.course, grade=0.8, passed=True)

        # should only update if combined grade already exists for user
        api.update_existing_combined_final_grade_for_exam_run(self.exam_run)
        assert update_or_create_mock.called is False

        CombinedFinalGrade.objects.create(user=self.user, course=self.course_run.course, grade=0.7)
        # should call it once since there is an existing combined grade
        api.update_existing_combined_final_grade_for_exam_run(self.exam_run)
        update_or_create_mock.assert_called_once_with(self.user, self.course_run.course)
        exam_run = ExamRunFactory.create(
            course=self.course_run.course,
            date_grades_available=now_in_utc() - timedelta(weeks=1)
        )
        ProctoredExamGradeFactory.create(
            user=self.user,
            course=self.course_run.course,
            percentage_grade=0.8,
            passed=True,
            exam_run=exam_run
        )
        # should call it again for a different exam grade
        api.update_existing_combined_final_grade_for_exam_run(exam_run)
        assert update_or_create_mock.call_count == 2
コード例 #37
0
    def create_exams(self, current, edx_passed, exam_passed, new_offering, can_schedule, future_exam, need_to_pay):
        """Create an exam and mark it and the related course as passed or not passed"""
        # pylint: disable-msg=too-many-arguments
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)
        course = Course.objects.get(title='Digital Learning 200')
        if current:
            course_run = CourseRunFactory(course=course)
            call_command(
                "alter_data", 'set_to_enrolled', '--username', 'staff',
                '--course-run-key', course_run.edx_course_key
            )
            FinalGradeFactory.create(
                user=self.user, course_run=course_run, grade=0.8 if edx_passed else 0.2, passed=True
            )
        else:
            if edx_passed:
                call_command(
                    "alter_data", 'set_to_passed', '--username', 'staff',
                    '--course-title', 'Digital Learning 200', '--grade', '75',
                )
            else:
                call_command(
                    "alter_data", 'set_to_failed', '--username', 'staff',
                    '--course-title', 'Digital Learning 200', '--grade', '45',
                )
            course_run = course.courserun_set.first()

        ExamProfileFactory.create(status='success', profile=self.user.profile)
        exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True)
        ExamAuthorizationFactory.create(
            user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True
        )
        LineFactory.create(
            order__status=Order.FULFILLED,
            course_key=course_run
        )

        ProctoredExamGradeFactory.create(
            user=self.user,
            course=course,
            exam_run=exam_run,
            passed=exam_passed,
            percentage_grade=0.8 if exam_passed else 0.3
        )
        if new_offering:
            CourseRunFactory.create(course=course)

        if can_schedule:
            exam_run = ExamRunFactory.create(
                scheduling_past=False,
                scheduling_future=False,
                authorized=True,
                course=course
            )
            ExamAuthorizationFactory.create(
                user=self.user, course=course, exam_run=exam_run, status='success',
            )

        if future_exam:
            ExamRunFactory.create(
                scheduling_past=False,
                scheduling_future=True,
                authorized=True,
                course=course
            )
        if need_to_pay:
            exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True)
            ExamAuthorizationFactory.create(
                user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True
            )
            ProctoredExamGradeFactory.create(
                user=self.user,
                course=course,
                exam_run=exam_run,
                passed=False,
                percentage_grade=0.3
            )
コード例 #38
0
 def test_has_exam(self):
     """test that creating an exam run makes has_exam == true"""
     assert self.course.has_exam is False
     ExamRunFactory.create(course=self.course)
     assert self.course.has_exam is True
コード例 #39
0
def test_generate_course_certificates():
    """
    Test that generate_course_certificates_for_fa_students creates certificates for appropriate FinalGrades
    """
    program = ProgramFactory.create(financial_aid_availability=True, live=True)
    week_ago = now_in_utc() - timedelta(weeks=1)
    # Course without exams
    course = CourseFactory.create(program=program)
    passed_final_grades = FinalGradeFactory.create_batch(
        4,
        course_run__course=course,
        course_run__freeze_grade_date=week_ago,
        passed=True
    )
    # create a duplicate final grade for course for user
    FinalGradeFactory.create(
        user=passed_final_grades[0].user,
        course_run__course=course,
        course_run__freeze_grade_date=week_ago,
        passed=True
    )
    # 2nd course for user
    course_2 = CourseFactory.create(program=program)
    FinalGradeFactory.create(
        course_run__course=course_2,
        course_run__freeze_grade_date=week_ago,
        passed=True,
        user=passed_final_grades[1].user
    )

    # Another non-fa course
    non_fa_course = CourseFactory.create(program__financial_aid_availability=False)

    # Course with exams
    # Create two exam runs for course with different date_grades_available
    exam_run_grades_available = ExamRunFactory.create(
        course__program=program,
        date_grades_available=now_in_utc() - timedelta(weeks=1))
    course_with_exams = exam_run_grades_available.course
    exam_run_no_grades = ExamRunFactory.create(
        course=course_with_exams,
        date_grades_available=now_in_utc() + timedelta(weeks=1))
    passed_final_grades_with_exam = FinalGradeFactory.create_batch(
        6,
        course_run__course=course_with_exams,
        passed=True
    )

    # Create ProctoredExamGrade records with a mix of passed and failed outcomes, and exam grade availability
    final_grades_with_passed_exam = passed_final_grades_with_exam[:2]

    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in final_grades_with_passed_exam]),
        course=course_with_exams,
        exam_run=exam_run_grades_available,
        passed=True,
    )
    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in passed_final_grades_with_exam[2:4]]),
        course=course_with_exams,
        exam_run=exam_run_no_grades,
        passed=True,
    )
    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in passed_final_grades_with_exam[4:6]]),
        course=course_with_exams,
        passed=False,
    )
    # course runs need to have CourseRunGradingStatus to get certificates
    all_grades = FinalGrade.objects.filter(course_run__course__in=[course, course_2, course_with_exams, non_fa_course])
    for final_grade in all_grades:
        CourseRunGradingStatus.objects.create(course_run=final_grade.course_run, status='complete')
    tasks.generate_course_certificates_for_fa_students.delay()

    # Make sure that certificates were created only for passed and 'complete' status FinalGrades that either
    # had no course exam, or had a passed ProctoredExamGrade.
    certificates = MicromastersCourseCertificate.objects.filter(course__in=[course, course_2, course_with_exams])
    assert certificates.count() == 7
    expected_certificate_final_grades = passed_final_grades + final_grades_with_passed_exam
    assert set(certificates.values_list('user', flat=True)) == {
        final_grade.user.id for final_grade in expected_certificate_final_grades
    }
コード例 #40
0
ファイル: models_test.py プロジェクト: mitodl/micromasters
 def test_has_exam(self):
     """test that creating an exam run makes has_exam == true"""
     assert self.course.has_exam is False
     ExamRunFactory.create(course=self.course)
     assert self.course.has_exam is True
コード例 #41
0
def test_generate_course_certificates():
    """
    Test that generate_course_certificates_for_fa_students creates certificates for appropriate FinalGrades
    """
    program = ProgramFactory.create(financial_aid_availability=True, live=True)
    week_ago = now_in_utc() - timedelta(weeks=1)
    # Course without exams
    course = CourseFactory.create(program=program)
    passed_final_grades = FinalGradeFactory.create_batch(
        4,
        course_run__course=course,
        course_run__freeze_grade_date=week_ago,
        passed=True
    )
    # create a duplicate final grade for course for user
    FinalGradeFactory.create(
        user=passed_final_grades[0].user,
        course_run__course=course,
        course_run__freeze_grade_date=week_ago,
        passed=True
    )
    # 2nd course for user
    course_2 = CourseFactory.create(program=program)
    FinalGradeFactory.create(
        course_run__course=course_2,
        course_run__freeze_grade_date=week_ago,
        passed=True,
        user=passed_final_grades[1].user
    )

    # Another non-fa course
    non_fa_course = CourseFactory.create(program__financial_aid_availability=False)

    # Course with exams
    # Create two exam runs for course with different date_grades_available
    exam_run_grades_available = ExamRunFactory.create(
        course__program=program,
        date_grades_available=now_in_utc() - timedelta(weeks=1))
    course_with_exams = exam_run_grades_available.course
    exam_run_no_grades = ExamRunFactory.create(
        course=course_with_exams,
        date_grades_available=now_in_utc() + timedelta(weeks=1))
    passed_final_grades_with_exam = FinalGradeFactory.create_batch(
        6,
        course_run__course=course_with_exams,
        passed=True
    )

    # Create ProctoredExamGrade records with a mix of passed and failed outcomes, and exam grade availability
    final_grades_with_passed_exam = passed_final_grades_with_exam[:2]

    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in final_grades_with_passed_exam]),
        course=course_with_exams,
        exam_run=exam_run_grades_available,
        passed=True,
    )
    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in passed_final_grades_with_exam[2:4]]),
        course=course_with_exams,
        exam_run=exam_run_no_grades,
        passed=True,
    )
    ProctoredExamGradeFactory.create_batch(
        2,
        user=factory.Iterator([final_grade.user for final_grade in passed_final_grades_with_exam[4:6]]),
        course=course_with_exams,
        passed=False,
    )
    # course runs need to have CourseRunGradingStatus to get certificates
    all_grades = FinalGrade.objects.filter(course_run__course__in=[course, course_2, course_with_exams, non_fa_course])
    for final_grade in all_grades:
        CourseRunGradingStatus.objects.create(course_run=final_grade.course_run, status='complete')
    tasks.generate_course_certificates_for_fa_students.delay()

    # Make sure that certificates were created only for passed and 'complete' status FinalGrades that either
    # had no course exam, or had a passed ProctoredExamGrade.
    certificates = MicromastersCourseCertificate.objects.filter(course__in=[course, course_2, course_with_exams])
    assert certificates.count() == 7
    expected_certificate_final_grades = passed_final_grades + final_grades_with_passed_exam
    assert set(certificates.values_list('user', flat=True)) == set(
        [final_grade.user.id for final_grade in expected_certificate_final_grades]
    )