Example #1
0
    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
Example #2
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
Example #3
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
Example #4
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(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
Example #5
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',
        )
    def test_process_result_exam(self):
        """Test that the authorization is marked as taken and a ProctoredExamGrade created"""
        exam_results = []
        auths = []

        # create a bunch of results that are passes
        for auth in ExamAuthorizationFactory.create_batch(5,
                                                          course=self.course):
            exam_results.append(
                EXAMResultFactory.create(
                    passed=True,
                    client_candidate_id=auth.user.profile.student_id,
                    client_authorization_id=auth.id,
                ))
            auths.append(auth)

        # create a bunch of results that are failed
        for auth in ExamAuthorizationFactory.create_batch(5,
                                                          course=self.course):
            exam_results.append(
                EXAMResultFactory.create(
                    failed=True,
                    client_candidate_id=auth.user.profile.student_id,
                    client_authorization_id=auth.id,
                ))
            auths.append(auth)

        grades = ProctoredExamGrade.objects.filter(course=self.course)
        assert grades.count() == 0

        with patch('exams.pearson.download.EXAMReader.read',
                   return_value=(exam_results, [])):
            assert self.processor.process_exam_file("/tmp/file.ext") == (True,
                                                                         [])

        for auth in auths:
            auth.refresh_from_db()
            assert auth.exam_no_show is False
            assert auth.exam_taken is True

        sorted_exam_results = sorted(
            exam_results, key=lambda result: result.client_authorization_id)
        sorted_grades = list(grades.order_by('client_authorization_id'))

        assert len(sorted_grades) == len(sorted_exam_results)

        for grade, exam_result in zip(sorted_grades, sorted_exam_results):
            assert grade.exam_date == exam_result.exam_date
            assert grade.passing_score == exam_result.passing_score
            assert grade.grade == exam_result.grade
            assert grade.score == exam_result.score
            assert grade.passed is (exam_result.grade == EXAM_GRADE_PASS)
            assert grade.percentage_grade == float(exam_result.score / 100.0)
            expected_data = dict(
                exam_result._asdict())  # _asdict() returns an OrderedDict
            expected_data['exam_date'] = expected_data['exam_date'].isoformat()
            assert grade.row_data == expected_data
Example #7
0
    def test_process_result_exam(self):
        """Test that the authorization is marked as taken and a ProctoredExamGrade created"""
        exam_results = []
        auths = []

        # create a bunch of results that are passes
        for auth in ExamAuthorizationFactory.create_batch(5, course=self.course):
            exam_results.append(EXAMResultFactory.create(
                passed=True,
                client_candidate_id=auth.user.profile.student_id,
                client_authorization_id=auth.id,
            ))
            auths.append(auth)

        # create a bunch of results that are failed
        for auth in ExamAuthorizationFactory.create_batch(5, course=self.course):
            exam_results.append(EXAMResultFactory.create(
                failed=True,
                client_candidate_id=auth.user.profile.student_id,
                client_authorization_id=auth.id,
            ))
            auths.append(auth)

        grades = ProctoredExamGrade.objects.filter(course=self.course)
        assert grades.count() == 0

        with patch('exams.pearson.download.EXAMReader.read', return_value=(exam_results, [])):
            assert self.processor.process_exam_file("/tmp/file.ext") == (True, [])

        for auth in auths:
            auth.refresh_from_db()
            assert auth.exam_no_show is False
            assert auth.exam_taken is True

        sorted_exam_results = sorted(exam_results, key=lambda result: result.client_authorization_id)
        sorted_grades = list(grades.order_by('client_authorization_id'))

        assert len(sorted_grades) == len(sorted_exam_results)

        for grade, exam_result in zip(sorted_grades, sorted_exam_results):
            assert grade.exam_date == exam_result.exam_date
            assert grade.passing_score == exam_result.passing_score
            assert grade.grade == exam_result.grade
            assert grade.score == exam_result.score
            assert grade.passed is (exam_result.grade == EXAM_GRADE_PASS)
            assert grade.percentage_grade == float(exam_result.score / 100.0)
            expected_data = dict(exam_result._asdict())  # _asdict() returns an OrderedDict
            expected_data['exam_date'] = expected_data['exam_date'].isoformat()
            assert grade.row_data == expected_data
Example #8
0
    def test_write_ead_file(self):
        """
        Tests that write_ead_file outputs correctly
        """
        kwargs = {
            'id': 143,
            'operation': 'add',
            'exam_run__exam_series_code': 'MM-DEDP',
            'exam_run__date_first_eligible': date(2016, 5, 15),
            'exam_run__date_last_eligible': date(2016, 10, 15),
        }

        with mute_signals(post_save):
            profile = ProfileFactory(id=14879)
            exam_auths = [ExamAuthorizationFactory.create(user=profile.user, **kwargs)]
            exam_auths[0].updated_on = FIXED_DATETIME

        self.ead_writer.write(self.tsv_file, exam_auths)

        assert self.tsv_rows[0] == (
            "add\t143\t"
            "14879\tMM-DEDP\t\t"
            "\t2016/05/15\t2016/10/15\t"  # accommodation blank intentionally
            "2016/05/15 15:02:55"
        )
Example #9
0
    def test_write_ead_file(self):
        """
        Tests that write_ead_file outputs correctly
        """
        kwargs = {
            'id': 143,
            'operation': 'add',
            'exam_run__exam_series_code': 'MM-DEDP',
            'exam_run__date_first_eligible': date(2016, 5, 15),
            'exam_run__date_last_eligible': date(2016, 10, 15),
        }

        with mute_signals(post_save):
            profile = ProfileFactory(id=14879)
            exam_auths = [
                ExamAuthorizationFactory.create(user=profile.user, **kwargs)
            ]
            exam_auths[0].updated_on = FIXED_DATETIME

        self.ead_writer.write(self.tsv_file, exam_auths)

        assert self.tsv_rows[0] == (
            "add\t143\t"
            "14879\tMM-DEDP\t\t"
            "\t2016/05/15\t2016/10/15\t"  # accommodation blank intentionally
            "2016/05/15 15:02:55")
Example #10
0
    def test_get_exam_card_status_eligible(self):
        """
        test get_exam_card_status against valid eligibility dates
        """

        ExamProfileFactory.create(
            profile=self.user.profile,
            status=ExamProfile.PROFILE_SUCCESS,
        )

        now = datetime(2016, 3, 15, tzinfo=pytz.UTC)
        past = datetime(2016, 3, 10, tzinfo=pytz.UTC)
        future = datetime(2016, 3, 20, tzinfo=pytz.UTC)
        valid_dates = [
            past - timedelta(days=1),
            past,
            now,
            future,
        ]
        invalid_dates = [
            future + timedelta(days=1),
        ]

        ExamAuthorizationFactory.create(
            user=self.user,
            status=ExamAuthorization.STATUS_SUCCESS,
            exam_run__course=self.course,
            exam_run__date_first_eligible=past.date(),
            exam_run__date_last_eligible=future.date(),
        )

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

        # should be considered schedulable if past <= datetime.now() <= future
        for now_value in valid_dates:
            mmtrack.now = now_value
            assert mmtrack.get_exam_card_status() == ExamProfile.PROFILE_SCHEDULABLE

        # not eligible
        for now_value in invalid_dates:
            mmtrack.now = now_value
            assert mmtrack.get_exam_card_status() == ExamProfile.PROFILE_SUCCESS
Example #11
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
Example #12
0
    def test_get_pearson_exam_status_eligible(self):
        """
        test get_pearson_exam_status against valid eligibility dates
        """

        ExamProfileFactory.create(
            profile=self.user.profile,
            status=ExamProfile.PROFILE_SUCCESS,
        )

        now = datetime(2016, 3, 15, tzinfo=pytz.UTC)
        past = datetime(2016, 3, 10, tzinfo=pytz.UTC)
        future = datetime(2016, 3, 20, tzinfo=pytz.UTC)
        valid_dates = [
            past - timedelta(days=1),
            past,
            now,
            future,
        ]
        invalid_dates = [
            future + timedelta(days=1),
        ]

        ExamAuthorizationFactory.create(
            user=self.user,
            status=ExamAuthorization.STATUS_SUCCESS,
            exam_run__course=self.course,
            exam_run__date_first_eligible=past.date(),
            exam_run__date_last_eligible=future.date(),
        )

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

        # should be considered schedulable if past <= datetime.now() <= future
        for now_value in valid_dates:
            mmtrack.now = now_value
            assert mmtrack.get_pearson_exam_status() == ExamProfile.PROFILE_SCHEDULABLE

        # not eligible
        for now_value in invalid_dates:
            mmtrack.now = now_value
            assert mmtrack.get_pearson_exam_status() == ExamProfile.PROFILE_SUCCESS
Example #13
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
    def setUpTestData(cls):
        sftp = Mock()
        cls.processor = download.ArchivedResponseProcessor(sftp)
        cls.course = course = CourseFactory.create()
        cls.success_auths = ExamAuthorizationFactory.create_batch(
            2, course=course)
        cls.failure_auths = ExamAuthorizationFactory.create_batch(
            2, course=course)

        cls.success_results = ([
            EACResult(
                client_authorization_id=auth.id,
                client_candidate_id=auth.user.profile.student_id,
                date=FIXED_DATETIME,
                status=EAC_SUCCESS_STATUS,
                message='',
            ) for auth in cls.success_auths
        ], [])
        cls.failed_results = ([
            EACResult(
                client_authorization_id=cls.failure_auths[0].id,
                client_candidate_id=cls.failure_auths[0].user.profile.
                student_id,
                date=FIXED_DATETIME,
                status=EAC_FAILURE_STATUS,
                message='',
            ),
            EACResult(
                client_authorization_id=cls.failure_auths[1].id,
                client_candidate_id=cls.failure_auths[1].user.profile.
                student_id,
                date=FIXED_DATETIME,
                status=EAC_FAILURE_STATUS,
                message='wrong username',
            ),
        ], [])

        cls.all_results = (
            cls.success_results[0] + cls.failed_results[0],
            cls.success_results[1] + cls.failed_results[1],
        )
Example #15
0
    def setUpTestData(cls):
        sftp = Mock()
        cls.processor = download.ArchivedResponseProcessor(sftp)
        cls.course = course = CourseFactory.create()
        cls.success_auths = ExamAuthorizationFactory.create_batch(2, course=course)
        cls.failure_auths = ExamAuthorizationFactory.create_batch(2, course=course)

        cls.success_results = ([
            EACResult(
                client_authorization_id=auth.id,
                client_candidate_id=auth.user.profile.student_id,
                date=FIXED_DATETIME,
                status=EAC_SUCCESS_STATUS,
                message='',
            ) for auth in cls.success_auths
        ], [])
        cls.failed_results = ([
            EACResult(
                client_authorization_id=cls.failure_auths[0].id,
                client_candidate_id=cls.failure_auths[0].user.profile.student_id,
                date=FIXED_DATETIME,
                status=EAC_FAILURE_STATUS,
                message='',
            ),
            EACResult(
                client_authorization_id=cls.failure_auths[1].id,
                client_candidate_id=cls.failure_auths[1].user.profile.student_id,
                date=FIXED_DATETIME,
                status=EAC_FAILURE_STATUS,
                message='wrong username',
            ),
        ], [])

        cls.all_results = (
            cls.success_results[0] + cls.failed_results[0],
            cls.success_results[1] + cls.failed_results[1],
        )
Example #16
0
    def test_process_result_exam_no_show(self):
        """Test process_exam_file against no-show rows"""
        exam_auth = ExamAuthorizationFactory.create(course=self.course)
        exam_result = EXAMResultFactory.create(
            noshow=True,
            client_candidate_id=exam_auth.user.profile.student_id,
            client_authorization_id=exam_auth.id,
        )

        with patch('exams.pearson.download.EXAMReader.read', return_value=([exam_result], [])):
            assert self.processor.process_exam_file("/tmp/file.ext") == (True, [])

        exam_auth.refresh_from_db()
        assert exam_auth.exam_no_show is True
        assert exam_auth.exam_taken is True

        assert not ProctoredExamGrade.objects.filter(course=self.course).exists()
    def test_process_result_exam_no_show(self):
        """Test process_exam_file against no-show rows"""
        exam_auth = ExamAuthorizationFactory.create(course=self.course)
        exam_result = EXAMResultFactory.create(
            noshow=True,
            client_candidate_id=exam_auth.user.profile.student_id,
            client_authorization_id=exam_auth.id,
        )

        with patch('exams.pearson.download.EXAMReader.read',
                   return_value=([exam_result], [])):
            assert self.processor.process_exam_file("/tmp/file.ext") == (True,
                                                                         [])

        exam_auth.refresh_from_db()
        assert exam_auth.exam_no_show is True
        assert exam_auth.exam_taken is True

        assert not ProctoredExamGrade.objects.filter(
            course=self.course).exists()
 def setUpTestData(cls):
     with mute_signals(post_save):
         cls.exam_auths = ExamAuthorizationFactory.create_batch(
             10, status=ExamAuthorization.STATUS_PENDING)
Example #19
0
 def setUpTestData(cls):
     with mute_signals(post_save):
         cls.exam_auths = ExamAuthorizationFactory.create_batch(10, status=ExamAuthorization.STATUS_PENDING)
Example #20
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
            )