Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
    def test_count_courses_passed_normal(self):
        """
        Assert that count_courses_passed works in case of normal program.
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )
        assert mmtrack.count_courses_passed() == 0
        course_run = self.cruns[0]
        FinalGradeFactory.create(
            user=self.user,
            course_run=course_run,
            passed=True
        )
        assert mmtrack.count_courses_passed() == 1

        course = CourseFactory.create(program=self.program)
        final_grade = FinalGradeFactory.create(
            user=self.user,
            course_run__course=course,
            passed=True
        )
        mmtrack.edx_course_keys.add(final_grade.course_run.edx_course_key)
        assert mmtrack.count_courses_passed() == 2
Exemplo n.º 3
0
 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)
Exemplo n.º 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
Exemplo n.º 5
0
    def test_count_passing_courses_for_keys(self):
        """
        Assert that count_courses_passed works in case of normal program.
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )
        assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 0
        for crun_index in [0, 1]:
            course_run = self.cruns[crun_index]
            FinalGradeFactory.create(
                user=self.user,
                course_run=course_run,
                passed=True
            )
            assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 1

        # now create a grade for another course
        final_grade = FinalGradeFactory.create(
            user=self.user,
            course_run__course__program=self.program,
            passed=True
        )
        mmtrack.edx_course_keys.add(final_grade.course_run.edx_course_key)
        assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 2
Exemplo n.º 6
0
    def test_update_exam_authorization_final_grade(self):
        """
        Verify that update_exam_authorization_final_grade is called when a FinalGrade saves
        """
        create_order(self.profile.user, self.course_run)
        with mute_signals(post_save):
            # muted because enrollment also trigger signal for profile creation. right now we are just
            # looking final grades
            CachedEnrollmentFactory.create(user=self.profile.user, course_run=self.course_run)

        # There is no ExamProfile or ExamAuthorization before creating the FinalGrade.
        assert ExamProfile.objects.filter(profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is False

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
        )

        # assert Exam Authorization and profile created.
        assert ExamProfile.objects.filter(profile=self.profile).exists() is True
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is True
Exemplo n.º 7
0
    def test_combined_grade_created_updated(self):
        """
        Test create and update
        """
        combined_grade_qset = CombinedFinalGrade.objects.filter(user=self.user, course=self.course_run.course)
        # no passing final grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is False

        FinalGradeFactory.create(user=self.user, course_run__course=self.course_run.course, grade=0.6, passed=True)
        # no passing exam grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is False
        ProctoredExamGradeFactory.create(
            user=self.user,
            course=self.course_run.course,
            percentage_grade=0.8,
            passed=True,
            exam_run=self.exam_run
        )

        # now should create combined grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is True

        # now update it with a new grade
        FinalGradeFactory.create(user=self.user, course_run__course=self.course_run.course, grade=0.8, passed=True)
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.first().grade == 80.0
Exemplo n.º 8
0
    def test_update_exam_authorization_final_grade(self):
        """
        Verify that update_exam_authorization_final_grade is called when a FinalGrade saves
        """
        create_order(self.profile.user, self.course_run)
        with mute_signals(post_save):
            # muted because enrollment also trigger signal for profile creation. right now we are just
            # looking final grades
            CachedEnrollmentFactory.create(user=self.profile.user,
                                           course_run=self.course_run)

        # There is no ExamProfile or ExamAuthorization before creating the FinalGrade.
        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is False

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
        )

        # assert Exam Authorization and profile created.
        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is True
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is True
Exemplo n.º 9
0
    def test_update_exam_authorization_order(self, order_status):
        """
        Verify that update_exam_authorization_final_grade is called when a fulfilled Order saves
        """
        with mute_signals(post_save):
            # muted because enrollment also trigger signal for profile creation. right now we are just
            # looking final grades
            CachedEnrollmentFactory.create(user=self.profile.user, course_run=self.course_run)

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
        )

        order = OrderFactory.create(user=self.profile.user, fulfilled=False)
        LineFactory.create(course_key=self.course_run.edx_course_key, order=order)

        # There is no ExamProfile or ExamAuthorization before creating the FinalGrade.
        assert ExamProfile.objects.filter(profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is False

        order.status = order_status
        order.save()

        # assert Exam Authorization and profile created.
        assert ExamProfile.objects.filter(profile=self.profile).exists() is True
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is True
Exemplo n.º 10
0
    def test_update_exam_authorization_final_grade_when_user_not_paid(self):
        """
        Verify that update_exam_authorization_final_grade is called and log exception when
        FinalGrade saves user dont match exam authorization criteria
        """
        with mute_signals(post_save):
            # muting signal for CachedEnrollment. Because CachedEnrollment and FinalGrade both omits
            # signal, we want to see behaviour of FinalGrade here
            CachedEnrollmentFactory.create(user=self.profile.user, course_run=self.course_run)

        assert ExamProfile.objects.filter(profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is False

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
            course_run_paid_on_edx=False,
        )

        # assert Exam Authorization and profile not created.
        assert ExamProfile.objects.filter(profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course
        ).exists() is False
Exemplo n.º 11
0
    def test_combined_grade_created_updated(self):
        """
        Test create and update
        """
        combined_grade_qset = CombinedFinalGrade.objects.filter(user=self.user, course=self.course_run.course)
        # no passing final grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is False

        FinalGradeFactory.create(user=self.user, course_run__course=self.course_run.course, grade=0.6, passed=True)
        # no passing exam grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is False
        ProctoredExamGradeFactory.create(
            user=self.user,
            course=self.course_run.course,
            percentage_grade=0.8,
            passed=True,
            exam_run=self.exam_run
        )

        # now should create combined grade
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.exists() is True

        # now update it with a new grade
        FinalGradeFactory.create(user=self.user, course_run__course=self.course_run.course, grade=0.8, passed=True)
        api.update_or_create_combined_final_grade(self.user, self.course_run.course)
        assert combined_grade_qset.first().grade == 80.0
Exemplo n.º 12
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
Exemplo n.º 13
0
    def test_count_courses_passed_normal(self):
        """
        Assert that count_courses_passed works in case of normal program.
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )
        assert mmtrack.count_courses_passed() == 0
        course_run = self.cruns[0]
        FinalGradeFactory.create(
            user=self.user,
            course_run=course_run,
            passed=True
        )
        assert mmtrack.count_courses_passed() == 1

        course = CourseFactory.create(program=self.program)
        final_grade = FinalGradeFactory.create(
            user=self.user,
            course_run__course=course,
            passed=True
        )
        mmtrack.edx_course_keys.add(final_grade.course_run.edx_course_key)
        assert mmtrack.count_courses_passed() == 2
Exemplo n.º 14
0
    def test_count_passing_courses_for_keys(self):
        """
        Assert that count_courses_passed works in case of normal program.
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program,
            edx_user_data=self.cached_edx_user_data
        )
        assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 0
        for crun_index in [0, 1]:
            course_run = self.cruns[crun_index]
            FinalGradeFactory.create(
                user=self.user,
                course_run=course_run,
                passed=True
            )
            assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 1

        # now create a grade for another course
        final_grade = FinalGradeFactory.create(
            user=self.user,
            course_run__course__program=self.program,
            passed=True
        )
        mmtrack.edx_course_keys.add(final_grade.course_run.edx_course_key)
        assert mmtrack.count_passing_courses_for_keys(mmtrack.edx_course_keys) == 2
Exemplo n.º 15
0
    def test_update_exam_authorization_final_grade_when_user_not_paid(self):
        """
        Verify that update_exam_authorization_final_grade is called and log exception when
        FinalGrade saves user dont match exam authorization criteria
        """
        with mute_signals(post_save):
            # muting signal for CachedEnrollment. Because CachedEnrollment and FinalGrade both omits
            # signal, we want to see behaviour of FinalGrade here
            CachedEnrollmentFactory.create(user=self.profile.user,
                                           course_run=self.course_run)

        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is False

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
            course_run_paid_on_edx=False,
        )

        # assert Exam Authorization and profile not created.
        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is False
Exemplo n.º 16
0
 def test_create_final_grade_fa(self, generate_letter_mock, update_grade_mock, mock_on_commit):
     """
     Test that final grades created for non-FA courses will try to update combined final grades.
     """
     fa_course_run = CourseRunFactory.create(course__program__financial_aid_availability=True)
     FinalGradeFactory.create(user=self.user, course_run=fa_course_run, grade=0.9)
     update_grade_mock.assert_called_once_with(self.user, fa_course_run.course)
     generate_letter_mock.assert_not_called()
Exemplo n.º 17
0
 def test_course_final_grade_serialization(self):
     """
     Tests that a user's final grades for a course run are properly serialized
     """
     # Final grades should all be None since none have been created yet
     serialized_program_user = UserProgramSearchSerializer.serialize(self.fa_program_enrollment)
     assert all(enrollment['final_grade'] is None for enrollment in serialized_program_user['courses'])
     # Add some final grades and test that their values are properly serialized
     for enrollment in self.fa_enrollments:
         FinalGradeFactory.create(user=self.user, course_run=enrollment.course_run, grade=0.8, passed=True)
     serialized_program_user = UserProgramSearchSerializer.serialize(self.fa_program_enrollment)
     assert all(enrollment['final_grade'] == 80.0 for enrollment in serialized_program_user['courses'])
Exemplo n.º 18
0
 def test_create_final_grade_fa(self, generate_letter_mock,
                                update_grade_mock, mock_on_commit):
     """
     Test that final grades created for non-FA courses will try to update combined final grades.
     """
     fa_course_run = CourseRunFactory.create(
         course__program__financial_aid_availability=True)
     FinalGradeFactory.create(user=self.user,
                              course_run=fa_course_run,
                              grade=0.9)
     update_grade_mock.assert_called_once_with(self.user,
                                               fa_course_run.course)
     generate_letter_mock.assert_not_called()
Exemplo n.º 19
0
 def test_final_grade_with_no_certificate(self):
     """
     Test has a final grade but no certificate
     """
     FinalGradeFactory.create(
         user=self.user,
         course_run=self.run_1,
         passed=True,
         status='complete',
         grade=0.8
     )
     CourseRunGradingStatus.objects.create(course_run=self.run_1, status='complete')
     cert_qset = MicromastersProgramCertificate.objects.filter(user=self.user, program=self.program)
     assert cert_qset.exists() is False
     api.generate_program_certificate(self.user, self.program)
     assert cert_qset.exists() is False
Exemplo n.º 20
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"
Exemplo n.º 21
0
 def test_final_grade_with_no_certificate(self):
     """
     Test has a final grade but no certificate
     """
     FinalGradeFactory.create(
         user=self.user,
         course_run=self.run_1,
         passed=True,
         status='complete',
         grade=0.8
     )
     CourseRunGradingStatus.objects.create(course_run=self.run_1, status='complete')
     cert_qset = MicromastersProgramCertificate.objects.filter(user=self.user, program=self.program)
     assert cert_qset.exists() is False
     api.generate_program_certificate(self.user, self.program)
     assert cert_qset.exists() is False
Exemplo n.º 22
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"
Exemplo n.º 23
0
    def test_successful_program_certificate_generation_with_electives(self):
        """
        Test has final grade and a certificate with elective courses
        """
        run_2 = CourseRunFactory.create(
            freeze_grade_date=now_in_utc() - timedelta(days=1),
            course__program=self.program,
        )
        electives_set = ElectivesSet.objects.create(program=self.program, required_number=1)

        for run in [self.run_1, run_2]:
            final_grade = FinalGradeFactory.create(
                user=self.user,
                course_run=run,
                passed=True,
                status='complete',
                grade=0.7
            )
            CourseRunGradingStatus.objects.create(course_run=run, status='complete')
            ElectiveCourse.objects.create(course=run.course, electives_set=electives_set)
            with mute_signals(post_save):
                MicromastersCourseCertificate.objects.create(course=final_grade.course_run.course, user=self.user)

        cert_qset = MicromastersProgramCertificate.objects.filter(user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_certificate(self.user, self.program)
        assert cert_qset.exists() is True
Exemplo n.º 24
0
 def test_has_paid_for_any_in_program(self):
     """
     Assert that has_paid_for_any_in_program returns True if any CourseRun associated with a Program has been
     paid for.
     """
     new_program = ProgramFactory.create()
     new_course_runs = CourseRunFactory.create_batch(2, course__program=new_program)
     mmtrack = MMTrack(
         user=self.user,
         program=new_program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.has_paid_for_any_in_program() is False
     fg = FinalGradeFactory.create(user=self.user, course_run=new_course_runs[0], course_run_paid_on_edx=True)
     assert mmtrack.has_paid_for_any_in_program() is True
     fg.delete()
     FinalGradeFactory.create(user=self.user, course_run=new_course_runs[1], course_run_paid_on_edx=True)
     assert mmtrack.has_paid_for_any_in_program() is True
Exemplo n.º 25
0
    def test_with_fa_program(self):
        """
        Test that letter won't be created if program is FA-enabled
        """
        self.program.financial_aid_availability = True
        self.program.save()
        with mute_signals(post_save):
            FinalGradeFactory.create(user=self.user,
                                     course_run=self.run_1,
                                     passed=True,
                                     status='complete',
                                     grade=0.8)

        cert_qset = MicromastersProgramCommendation.objects.filter(
            user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_letter(self.user, self.program)
        assert cert_qset.exists() is False
Exemplo n.º 26
0
    def test_successful_program_letter_generation(self):
        """
        Test happy scenario
        """
        self.program.financial_aid_availability = False
        self.program.save()
        with mute_signals(post_save):
            FinalGradeFactory.create(user=self.user,
                                     course_run=self.run_1,
                                     passed=True,
                                     status='complete',
                                     grade=0.8)

        cert_qset = MicromastersProgramCommendation.objects.filter(
            user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_letter(self.user, self.program)
        assert cert_qset.exists() is True
Exemplo n.º 27
0
 def test_has_paid_for_any_in_program(self):
     """
     Assert that has_paid_for_any_in_program returns True if any CourseRun associated with a Program has been
     paid for.
     """
     new_program = ProgramFactory.create()
     new_course_runs = CourseRunFactory.create_batch(2, course__program=new_program)
     mmtrack = MMTrack(
         user=self.user,
         program=new_program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.has_paid_for_any_in_program() is False
     fg = FinalGradeFactory.create(user=self.user, course_run=new_course_runs[0], course_run_paid_on_edx=True)
     assert mmtrack.has_paid_for_any_in_program() is True
     fg.delete()
     FinalGradeFactory.create(user=self.user, course_run=new_course_runs[1], course_run_paid_on_edx=True)
     assert mmtrack.has_paid_for_any_in_program() is True
Exemplo n.º 28
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)
Exemplo n.º 29
0
    def test_successful_program_letter_generation(self):
        """
        Test happy scenario
        """
        self.program.financial_aid_availability = False
        self.program.save()
        with mute_signals(post_save):
            FinalGradeFactory.create(
                user=self.user,
                course_run=self.run_1,
                passed=True,
                status='complete',
                grade=0.8
            )

        cert_qset = MicromastersProgramCommendation.objects.filter(user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_letter(self.user, self.program)
        assert cert_qset.exists() is True
Exemplo n.º 30
0
    def test_with_fa_program(self):
        """
        Test that letter won't be created if program is FA-enabled
        """
        self.program.financial_aid_availability = True
        self.program.save()
        with mute_signals(post_save):
            FinalGradeFactory.create(
                user=self.user,
                course_run=self.run_1,
                passed=True,
                status='complete',
                grade=0.8
            )

        cert_qset = MicromastersProgramCommendation.objects.filter(user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_letter(self.user, self.program)
        assert cert_qset.exists() is False
Exemplo n.º 31
0
 def test_course_final_grade_serialization(self):
     """
     Tests that a user's final grades for a course run are properly serialized
     """
     # Final grades should all be None since none have been created yet
     serialized_program_user = UserProgramSearchSerializer.serialize(
         self.fa_program_enrollment)
     assert all(enrollment['final_grade'] is None
                for enrollment in serialized_program_user['courses'])
     # Add some final grades and test that their values are properly serialized
     for enrollment in self.fa_enrollments:
         FinalGradeFactory.create(user=self.user,
                                  course_run=enrollment.course_run,
                                  grade=0.8,
                                  passed=True)
     serialized_program_user = UserProgramSearchSerializer.serialize(
         self.fa_program_enrollment)
     assert all(enrollment['final_grade'] == 80.0
                for enrollment in serialized_program_user['courses'])
Exemplo n.º 32
0
    def test_get_best_final_grade_for_course(self):
        """
        Test for get_best_final_grade_for_course to return the highest grade over all course runs
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program_financial_aid,
            edx_user_data=self.cached_edx_user_data
        )
        finaid_course = self.crun_fa.course

        FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, grade=0.3, passed=False)
        assert mmtrack.get_best_final_grade_for_course(finaid_course) is None

        for grade in [0.3, 0.5, 0.8]:
            course_run = CourseRunFactory.create(
                course=finaid_course,
            )
            FinalGradeFactory.create(user=self.user, course_run=course_run, grade=grade, passed=True)
        assert mmtrack.get_best_final_grade_for_course(finaid_course).grade == 0.8
Exemplo n.º 33
0
    def test_get_best_final_grade_for_course(self):
        """
        Test for get_best_final_grade_for_course to return the highest grade over all course runs
        """
        mmtrack = MMTrack(
            user=self.user,
            program=self.program_financial_aid,
            edx_user_data=self.cached_edx_user_data
        )
        finaid_course = self.crun_fa.course

        FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, grade=0.3, passed=False)
        assert mmtrack.get_best_final_grade_for_course(finaid_course) is None

        for grade in [0.3, 0.5, 0.8]:
            course_run = CourseRunFactory.create(
                course=finaid_course,
            )
            FinalGradeFactory.create(user=self.user, course_run=course_run, grade=grade, passed=True)
        assert mmtrack.get_best_final_grade_for_course(finaid_course).grade == 0.8
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)
Exemplo n.º 35
0
    def test_exam_authorization_for_inactive_user(self):
        """
        test exam_authorization when inactive user passed and paid for course.
        """
        with mute_signals(post_save):
            profile = ProfileFactory.create()

        user = profile.user
        user.is_active = False
        user.save()
        with mute_signals(post_save):
            CachedEnrollmentFactory.create(user=user,
                                           course_run=self.course_run)

        with mute_signals(post_save):
            FinalGradeFactory.create(
                user=user,
                course_run=self.course_run,
                passed=True,
                course_run_paid_on_edx=False,
            )
        create_order(user, self.course_run)
        mmtrack = get_mmtrack(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))

        # 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

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

        # Assert user doesn't have 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
Exemplo n.º 36
0
    def test_exam_authorization_for_inactive_user(self):
        """
        test exam_authorization when inactive user passed and paid for course.
        """
        with mute_signals(post_save):
            profile = ProfileFactory.create()

        user = profile.user
        user.is_active = False
        user.save()
        with mute_signals(post_save):
            CachedEnrollmentFactory.create(user=user, course_run=self.course_run)

        with mute_signals(post_save):
            FinalGradeFactory.create(
                user=user,
                course_run=self.course_run,
                passed=True,
                course_run_paid_on_edx=False,
            )
        create_order(user, self.course_run)
        mmtrack = get_mmtrack(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))

        # 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

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

        # Assert user doesn't have 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
Exemplo n.º 37
0
 def test_has_paid_final_grade(self, has_paid):
     """
     Test that has_paid_final_grade returns True when the associated FinalGrade is paid
     """
     final_grade = FinalGradeFactory.create(user=self.user,
                                            course_run=self.cruns[0],
                                            course_run_paid_on_edx=has_paid)
     mmtrack = MMTrack(user=self.user,
                       program=self.program,
                       edx_user_data=self.cached_edx_user_data)
     assert mmtrack.has_paid_final_grade(
         final_grade.course_run.edx_course_key) is has_paid
Exemplo n.º 38
0
 def test_has_final_grade(self):
     """
     Test that has_final_grade returns True when a FinalGrade exists
     """
     final_grade = FinalGradeFactory.create(user=self.user,
                                            course_run=self.cruns[0])
     mmtrack = MMTrack(user=self.user,
                       program=self.program,
                       edx_user_data=self.cached_edx_user_data)
     assert mmtrack.has_final_grade(
         final_grade.course_run.edx_course_key) is True
     assert mmtrack.has_final_grade('random-course-id') is False
Exemplo n.º 39
0
 def test_has_passed_course(self, final_grade_passed):
     """
     Test that has_passed_course returns True when a passed FinalGrade exists
     """
     final_grade = FinalGradeFactory.create(user=self.user,
                                            course_run=self.cruns[0],
                                            passed=final_grade_passed)
     mmtrack = MMTrack(user=self.user,
                       program=self.program,
                       edx_user_data=self.cached_edx_user_data)
     assert mmtrack.has_passed_course(
         final_grade.course_run.edx_course_key) is final_grade_passed
Exemplo n.º 40
0
 def test_get_required_final_grade(self):
     """
     Test that get_required_final_grade returns the FinalGrade associated with a user's course run
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0],
     )
     mmtrack = MMTrack(user=self.user,
                       program=self.program,
                       edx_user_data=self.cached_edx_user_data)
     assert mmtrack.get_required_final_grade(
         final_grade.course_run.edx_course_key) == final_grade
Exemplo n.º 41
0
 def test_get_required_final_grade(self):
     """
     Test that get_required_final_grade returns the FinalGrade associated with a user's course run
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0],
     )
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.get_required_final_grade(final_grade.course_run.edx_course_key) == final_grade
Exemplo n.º 42
0
 def test_get_final_grade_percent(self):
     """
     Test that get_final_grade_percent returns a final grade in percent form
     """
     final_grade = FinalGradeFactory.create(user=self.user,
                                            course_run=self.cruns[0],
                                            grade=0.57)
     mmtrack = MMTrack(user=self.user,
                       program=self.program,
                       edx_user_data=self.cached_edx_user_data)
     # calling round here because we do not want to add it in `get_final_grade` and let the frontend handle it
     assert round(
         mmtrack.get_final_grade_percent(
             final_grade.course_run.edx_course_key)) == 57.0
Exemplo n.º 43
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,
         )
Exemplo n.º 44
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
    )
Exemplo n.º 45
0
 def test_has_final_grade(self):
     """
     Test that has_final_grade returns True when a FinalGrade exists
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0]
     )
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.has_final_grade(final_grade.course_run.edx_course_key) is True
     assert mmtrack.has_final_grade('random-course-id') is False
Exemplo n.º 46
0
    def test_update_exam_authorization_order(self, order_status):
        """
        Verify that update_exam_authorization_final_grade is called when a fulfilled Order saves
        """
        with mute_signals(post_save):
            # muted because enrollment also trigger signal for profile creation. right now we are just
            # looking final grades
            CachedEnrollmentFactory.create(user=self.profile.user,
                                           course_run=self.course_run)

        FinalGradeFactory.create(
            user=self.profile.user,
            course_run=self.course_run,
            passed=True,
        )

        order = OrderFactory.create(user=self.profile.user, fulfilled=False)
        LineFactory.create(course_key=self.course_run.edx_course_key,
                           order=order)

        # There is no ExamProfile or ExamAuthorization before creating the FinalGrade.
        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is False
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is False

        order.status = order_status
        order.save()

        # assert Exam Authorization and profile created.
        assert ExamProfile.objects.filter(
            profile=self.profile).exists() is True
        assert ExamAuthorization.objects.filter(
            user=self.profile.user,
            course=self.course_run.course).exists() is True
Exemplo n.º 47
0
 def test_has_passed_course(self, final_grade_passed):
     """
     Test that has_passed_course returns True when a passed FinalGrade exists
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0],
         passed=final_grade_passed
     )
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.has_passed_course(final_grade.course_run.edx_course_key) is final_grade_passed
Exemplo n.º 48
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
Exemplo n.º 49
0
 def test_has_paid_final_grade(self, has_paid):
     """
     Test that has_paid_final_grade returns True when the associated FinalGrade is paid
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0],
         course_run_paid_on_edx=has_paid
     )
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     assert mmtrack.has_paid_final_grade(final_grade.course_run.edx_course_key) is has_paid
Exemplo n.º 50
0
 def test_get_final_grade_percent(self):
     """
     Test that get_final_grade_percent returns a final grade in percent form
     """
     final_grade = FinalGradeFactory.create(
         user=self.user,
         course_run=self.cruns[0],
         grade=0.57
     )
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     # calling round here because we do not want to add it in `get_final_grade` and let the frontend handle it
     assert round(mmtrack.get_final_grade_percent(final_grade.course_run.edx_course_key)) == 57.0
Exemplo n.º 51
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
        )
Exemplo n.º 52
0
 def test_has_paid_not_fa_with_final_grade(self):
     """
     Assert that has_paid works for non-FA programs in case there is a final grade
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     key = "course-v1:odl+FOO102+CR-FALL16"
     assert mmtrack.has_paid(key) is False
     course_run = self.cruns[-1]
     final_grade = FinalGradeFactory.create(user=self.user, course_run=course_run, course_run_paid_on_edx=True)
     assert mmtrack.has_paid(key) is True
     final_grade.course_run_paid_on_edx = False
     final_grade.save()
     assert mmtrack.has_paid(key) is False
Exemplo n.º 53
0
 def test_not_paid_fa_with_course_run_paid_on_edx(self):
     """
     Test for has_paid is False for FA programs even in case
     there is a final grade with course_run_paid_on_edx=True
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program_financial_aid,
         edx_user_data=self.cached_edx_user_data
     )
     key = self.crun_fa.edx_course_key
     assert mmtrack.has_paid(key) is False
     final_grade = FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, course_run_paid_on_edx=True)
     assert mmtrack.has_paid(key) is False
     final_grade.course_run_paid_on_edx = False
     final_grade.save()
     assert mmtrack.has_paid(key) is False
Exemplo n.º 54
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,
            )
Exemplo n.º 55
0
 def test_not_paid_fa_with_course_run_paid_on_edx(self):
     """
     Test for has_paid is False for FA programs even in case
     there is a final grade with course_run_paid_on_edx=True
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program_financial_aid,
         edx_user_data=self.cached_edx_user_data
     )
     key = self.crun_fa.edx_course_key
     assert mmtrack.has_paid(key) is False
     final_grade = FinalGradeFactory.create(user=self.user, course_run=self.crun_fa, course_run_paid_on_edx=True)
     assert mmtrack.has_paid(key) is False
     final_grade.course_run_paid_on_edx = False
     final_grade.save()
     assert mmtrack.has_paid(key) is False
Exemplo n.º 56
0
 def test_has_paid_not_fa_with_final_grade(self):
     """
     Assert that has_paid works for non-FA programs in case there is a final grade
     """
     mmtrack = MMTrack(
         user=self.user,
         program=self.program,
         edx_user_data=self.cached_edx_user_data
     )
     key = "course-v1:odl+FOO102+CR-FALL16"
     assert mmtrack.has_paid(key) is False
     course_run = self.cruns[-1]
     final_grade = FinalGradeFactory.create(user=self.user, course_run=course_run, course_run_paid_on_edx=True)
     assert mmtrack.has_paid(key) is True
     final_grade.course_run_paid_on_edx = False
     final_grade.save()
     assert mmtrack.has_paid(key) is False
Exemplo n.º 57
0
    def test_successful_program_certificate_generation(self):
        """
        Test has final grade and a certificate
        """
        final_grade = FinalGradeFactory.create(
            user=self.user,
            course_run=self.run_1,
            passed=True,
            status='complete',
            grade=0.8
        )
        CourseRunGradingStatus.objects.create(course_run=self.run_1, status='complete')
        with mute_signals(post_save):
            MicromastersCourseCertificate.objects.create(course=final_grade.course_run.course, user=self.user)

        cert_qset = MicromastersProgramCertificate.objects.filter(user=self.user, program=self.program)
        assert cert_qset.exists() is False
        api.generate_program_certificate(self.user, self.program)
        assert cert_qset.exists() is True
Exemplo n.º 58
0
 def setUpTestData(cls):
     with mute_signals(post_save):
         cls.profile = profile = ProfileFactory.create()
     cls.user = profile.user
     EducationFactory.create(profile=profile)
     EmploymentFactory.create(profile=profile)
     # create a normal program
     program = ProgramFactory.create()
     cls.enrollments = cls._generate_cached_enrollments(cls.user, program, num_course_runs=2)
     certificate_grades_vals = [0.7, 0.8]
     cls.current_grades_vals = [0.9, 1.0]
     cls.certificates = []
     cls.current_grades = []
     for i, enrollment in enumerate(cls.enrollments):
         cls.certificates.append(
             CachedCertificateFactory.create(
                 user=cls.user,
                 course_run=enrollment.course_run,
                 data={
                     "grade": certificate_grades_vals[i],
                     "certificate_type": "verified",
                     "course_id": enrollment.course_run.edx_course_key,
                     "status": "downloadable",
                 }
             )
         )
         cls.current_grades.append(
             CachedCurrentGradeFactory.create(
                 user=cls.user,
                 course_run=enrollment.course_run,
                 data={
                     "passed": True,
                     "percent": cls.current_grades_vals[i],
                     "course_key": enrollment.course_run.edx_course_key,
                 }
             )
         )
         FinalGradeFactory.create(
             user=cls.user,
             course_run=enrollment.course_run,
             grade=certificate_grades_vals[i],
             passed=True,
         )
     non_fa_cached_edx_data = CachedEdxUserData(cls.user, program=program)
     non_fa_mmtrack = MMTrack(cls.user, program, non_fa_cached_edx_data)
     cls.serialized_enrollments = UserProgramSearchSerializer.serialize_enrollments(non_fa_mmtrack)
     cls.serialized_course_enrollments = UserProgramSearchSerializer.serialize_course_enrollments(non_fa_mmtrack)
     cls.semester_enrollments = UserProgramSearchSerializer.serialize_course_runs_enrolled(non_fa_mmtrack)
     cls.program_enrollment = ProgramEnrollment.objects.create(user=cls.user, program=program)
     # create a financial aid program
     cls.fa_program, _ = create_program()
     cls.fa_program_enrollment = ProgramEnrollment.objects.create(user=cls.user, program=cls.fa_program)
     cls.fa_enrollments = cls._generate_cached_enrollments(cls.user, cls.fa_program, num_course_runs=2)
     cls.current_grades = []
     for i, enrollment in enumerate(cls.fa_enrollments):
         order = OrderFactory.create(user=cls.user, status='fulfilled')
         LineFactory.create(order=order, course_key=enrollment.course_run.edx_course_key)
         cls.current_grades.append(
             CachedCurrentGradeFactory.create(
                 user=cls.user,
                 course_run=enrollment.course_run,
                 data={
                     "passed": True,
                     "percent": cls.current_grades_vals[i],
                     "course_key": enrollment.course_run.edx_course_key,
                 }
             )
         )
         FinalGradeFactory.create(
             user=cls.user,
             course_run=enrollment.course_run,
             grade=cls.current_grades_vals[i],
             passed=True,
         )
     fa_cached_edx_data = CachedEdxUserData(cls.user, program=cls.fa_program)
     fa_mmtrack = MMTrack(cls.user, cls.fa_program, fa_cached_edx_data)
     cls.fa_serialized_course_enrollments = (
         UserProgramSearchSerializer.serialize_course_enrollments(fa_mmtrack)
     )
     cls.fa_serialized_enrollments = (
         UserProgramSearchSerializer.serialize_enrollments(fa_mmtrack)
     )