def setUpTestData(cls):
     cls.user = UserFactory.create()
     # Create Programs, Courses, CourseRuns...
     cls.p1_course_run_keys = ['p1_course_run']
     cls.p2_course_run_keys = ['p2_course_run_1', 'p2_course_run_2']
     cls.p1_course_run = CourseRunFactory.create(
         edx_course_key=cls.p1_course_run_keys[0])
     p2 = FullProgramFactory.create()
     first_course = p2.course_set.first()
     extra_course = CourseFactory.create(program=p2)
     cls.p2_course_run_1 = CourseRunFactory.create(
         course=first_course, edx_course_key=cls.p2_course_run_keys[0])
     cls.p2_course_run_2 = CourseRunFactory.create(
         course=extra_course, edx_course_key=cls.p2_course_run_keys[1])
     all_course_runs = [
         cls.p1_course_run, cls.p2_course_run_1, cls.p2_course_run_2
     ]
     # Create cached edX data
     cls.enrollments = [
         CachedEnrollmentFactory.create(user=cls.user,
                                        course_run=course_run)
         for course_run in all_course_runs
     ]
     cls.certificates = [
         CachedCertificateFactory.create(user=cls.user,
                                         course_run=course_run)
         for course_run in all_course_runs
     ]
     cls.current_grades = [
         CachedCurrentGradeFactory.create(user=cls.user,
                                          course_run=course_run)
         for course_run in all_course_runs
     ]
Beispiel #2
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',
        )
Beispiel #3
0
def voucher_and_partial_matches(voucher_and_user_client):
    """
    Returns a voucher with partial matching CourseRuns
    """
    voucher = voucher_and_user_client.voucher
    company = CompanyFactory()
    course_run_1 = CourseRunFactory(
        start_date=datetime.combine(voucher.course_start_date_input,
                                    datetime.min.time(),
                                    tzinfo=pytz.UTC),
        live=True,
    )
    course_run_2 = CourseRunFactory(
        course__readable_id=voucher.course_id_input, live=True)
    course_run_3 = CourseRunFactory(course__title=voucher.course_title_input,
                                    live=True)
    course_run_4 = CourseRunFactory(
        course__readable_id=f"{voucher.course_id_input}-noise", live=True)
    course_run_5 = CourseRunFactory(
        course__title=f"{voucher.course_title_input}-noise", live=True)
    return SimpleNamespace(
        **vars(voucher_and_user_client),
        company=company,
        partial_matches=[
            course_run_1,
            course_run_2,
            course_run_3,
            course_run_4,
            course_run_5,
        ],
    )
Beispiel #4
0
    def create_audited_passed_enrolled_again_failed(self):
        """Make course passed and user retaking/auditing the course again"""
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)
        course = Course.objects.get(title='Digital Learning 200')
        CourseCertificateSignatoriesFactory.create(course=course)

        course_run = CourseRunFactory(course=course, edx_course_key='course-passed')
        set_course_run_past(course_run)
        call_command(
            "alter_data", 'set_to_passed', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key, '--grade', '80', '--audit'
        )
        final_grade = FinalGrade.objects.filter(
            course_run__course__title='Digital Learning 200', user=self.user
        ).first()
        CourseRunGradingStatus.objects.create(course_run=final_grade.course_run, status='complete')

        course_run = CourseRunFactory(course=course, edx_course_key='course-failed')
        set_course_run_past(course_run)
        call_command(
            "alter_data", 'set_to_failed', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key, '--grade', '10', '--audit'
        )

        course_run = CourseRunFactory(course=course, edx_course_key='course-offered')
        set_course_run_future(course_run)
        call_command(
            'alter_data', 'set_to_offered', '--username', 'staff',
            '--course-run-key', course_run.edx_course_key,
        )
Beispiel #5
0
def base_test_data():
    """
    Fixture for test data that should be available to any test case in the suite
    """
    # Create a live program with valid prices and financial aid
    program = ProgramFactory.create(
        live=True,
        financial_aid_availability=True,
        price=1000,
    )
    CourseRunFactory.create(course__program=program)
    TierProgramFactory.create_properly_configured_batch(2, program=program)
    # Create users
    staff_user, student_user = (create_user_for_login(is_staff=True),
                                create_user_for_login(is_staff=False))
    ProgramEnrollment.objects.create(program=program, user=staff_user)
    ProgramEnrollment.objects.create(program=program, user=student_user)
    Role.objects.create(
        role=Staff.ROLE_ID,
        user=staff_user,
        program=program,
    )
    return SimpleNamespace(staff_user=staff_user,
                           student_user=student_user,
                           program=program)
Beispiel #6
0
    def create_paid_but_no_enrollable_run(self, enrollable, in_future, fuzzy):
        """Make paid but not enrolled, with offered currently, in future, and fuzzy """
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)
        course = Course.objects.get(title='Digital Learning 200')
        course_run = course.courserun_set.order_by('start_date').first()
        # course_run = CourseRunFactory.create(course=course, edx_course_key='course-paid')

        add_paid_order_for_course(user=self.user, course_run=course_run)
        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 in_future:
            course_run = CourseRunFactory.create(course=course, edx_course_key='course-in-future')
            call_command(
                "alter_data", 'set_to_offered', '--username', 'staff',
                '--course-run-key', course_run.edx_course_key, '--in-future'
            )
        if fuzzy:
            course_run = CourseRunFactory.create(course=course, edx_course_key='course-fuzzy')
            call_command(
                "alter_data", 'set_to_offered', '--username', 'staff',
                '--course-run-key', course_run.edx_course_key, '--fuzzy'
            )
Beispiel #7
0
def test_courseware_url(settings):
    """Test that the courseware_url property yields the correct values"""
    settings.OPENEDX_BASE_REDIRECT_URL = "http://example.com"
    course_run = CourseRunFactory.build(courseware_url_path="/path")
    course_run_no_path = CourseRunFactory.build(courseware_url_path=None)
    assert course_run.courseware_url == "http://example.com/path"
    assert course_run_no_path.courseware_url is None
Beispiel #8
0
def test_program_certificate_start_end_dates(user):
    """
    Test that the ProgramCertificate start_end_dates property works properly
    """
    now = now_in_utc()
    start_date = now + timedelta(days=1)
    end_date = now + timedelta(days=100)
    program = ProgramFactory.create()

    early_course_run = CourseRunFactory.create(course__program=program,
                                               start_date=start_date,
                                               end_date=end_date)
    later_course_run = CourseRunFactory.create(
        course__program=program,
        start_date=start_date + timedelta(days=1),
        end_date=end_date + timedelta(days=1),
    )

    # Need the course run certificates to be there in order for the start_end_dates
    # to return valid values
    CourseRunCertificateFactory.create(course_run=early_course_run, user=user)
    CourseRunCertificateFactory.create(course_run=later_course_run, user=user)

    certificate = ProgramCertificateFactory.create(program=program, user=user)
    program_start_date, program_end_date = certificate.start_end_dates
    assert program_start_date == early_course_run.start_date
    assert program_end_date == later_course_run.end_date
Beispiel #9
0
def base_test_data():
    """
    Fixture for test data that should be available to any test case in the suite
    """
    # Create a live program with valid prices and financial aid
    program = ProgramFactory.create(
        live=True,
        financial_aid_availability=True,
        price=1000,
    )
    CourseRunFactory.create(course__program=program)
    TierProgramFactory.create_properly_configured_batch(2, program=program)
    # Create users
    staff_user, student_user = (create_user_for_login(is_staff=True), create_user_for_login(is_staff=False))
    ProgramEnrollment.objects.create(program=program, user=staff_user)
    ProgramEnrollment.objects.create(program=program, user=student_user)
    Role.objects.create(
        role=Staff.ROLE_ID,
        user=staff_user,
        program=program,
    )
    return SimpleNamespace(
        staff_user=staff_user,
        student_user=student_user,
        program=program
    )
Beispiel #10
0
def test_program_first_unexpired_run():
    """
    Test that the first unexpired run of a program is returned
    """
    program = ProgramFactory()
    course = CourseFactory.create(program=program)
    now = now_in_utc()
    end_date = now + timedelta(days=100)
    enr_end_date = now + timedelta(days=100)
    first_run = CourseRunFactory.create(
        start_date=now,
        course=course,
        end_date=end_date,
        enrollment_end=enr_end_date,
        live=True,
    )

    # create another course and course run in program
    another_course = CourseFactory.create(program=program)
    second_run = CourseRunFactory.create(
        start_date=now + timedelta(days=50),
        course=another_course,
        end_date=end_date,
        enrollment_end=enr_end_date,
    )

    assert first_run.start_date < second_run.start_date
    assert program.first_unexpired_run == first_run
def test_catalog_program_serializer(has_page, has_thumbnail):
    """Tests that the catalog serializer returns a correct data structure"""
    page = ProgramPageFactory.create(
        has_thumbnail=has_thumbnail) if has_page else None
    program = page.program if page else ProgramFactory.create()
    courses = CourseFactory.create_batch(3, program=program)
    for course in courses:
        CourseRunFactory.create_batch(2, course=course)
    faculty_name = "faculty"
    if has_page:
        ProgramFaculty.objects.create(
            program_page=page,
            name=faculty_name,
        )
    serialized = CatalogProgramSerializer(program).data
    # coerce OrderedDict objects to dict
    serialized = {
        **serialized, "courses": [{
            **course, "course_runs":
            [dict(run) for run in course["course_runs"]]
        } for course in serialized["courses"]]
    }
    assert serialized == {
        "id":
        program.id,
        "title":
        program.title,
        "programpage_url":
        page.get_full_url() if has_page else None,
        "thumbnail_url":
        (page.thumbnail_image.get_rendition('fill-300x186').url
         if has_page and has_thumbnail else None),
        "courses": [{
            "id":
            course.id,
            "edx_key":
            course.edx_key,
            "position_in_program":
            course.position_in_program,
            "course_runs": [{
                "id": course_run.id,
                "edx_course_key": course_run.edx_course_key,
            } for course_run in course.courserun_set.all()]
        } for course in courses],
        'topics': [{
            'name': topic.name
        } for topic in program.topics.iterator()],
        "instructors": [{
            "name": faculty_name
        }] if has_page else [],
        "start_date":
        courses[0].first_unexpired_run().start_date,
        "enrollment_start":
        courses[0].first_unexpired_run().enrollment_start,
        "end_date":
        courses[-1].courserun_set.last().end_date,
        "total_price":
        str(program.price * program.num_required_courses),
    }
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.run_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc() - timedelta(days=1),
            course__program__financial_aid_availability=True,
        )
        cls.run_fa_with_cert = CourseRunFactory.create(
            freeze_grade_date=None,
            course__program=cls.run_fa.course.program,
        )

        cls.run_no_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc() + timedelta(days=1),
            course__program__financial_aid_availability=False,
        )
        cls.run_no_fa_with_cert = CourseRunFactory.create(
            course__program=cls.run_no_fa.course.program, )

        all_course_runs = (
            cls.run_fa,
            cls.run_fa_with_cert,
            cls.run_no_fa,
            cls.run_no_fa_with_cert,
        )

        for run in all_course_runs:
            if run.course.program.financial_aid_availability:
                FinancialAidFactory.create(
                    user=cls.user,
                    tier_program=TierProgramFactory.create(
                        program=run.course.program,
                        income_threshold=0,
                        current=True),
                    status=FinancialAidStatus.RESET,
                )

        cls.enrollments = {
            course_run.edx_course_key:
            CachedEnrollmentFactory.create(user=cls.user,
                                           course_run=course_run)
            for course_run in all_course_runs
        }

        cls.current_grades = {
            course_run.edx_course_key:
            CachedCurrentGradeFactory.create(user=cls.user,
                                             course_run=course_run)
            for course_run in all_course_runs
        }

        cls.certificates = {
            course_run.edx_course_key:
            CachedCertificateFactory.create(user=cls.user,
                                            course_run=course_run)
            for course_run in (cls.run_fa_with_cert, cls.run_no_fa_with_cert)
        }

        cls.user_edx_data = CachedEdxUserData(cls.user)
Beispiel #13
0
 def failed_run_missed_payment_can_reenroll(self):
     """Failed User has missed payment but they can re-enroll"""
     call_command(
         "alter_data", 'set_to_failed', '--username', 'staff',
         '--course-title', 'Analog Learning 200', '--grade', '0', '--audit'
     )
     course = Course.objects.get(title='Analog Learning 200')
     CourseRunFactory.create(course=course)
Beispiel #14
0
 def missed_payment_can_reenroll(self):
     """User has missed payment but they can re-enroll"""
     call_command(
         "alter_data", 'set_to_needs_upgrade', '--username', 'staff',
         '--course-title', 'Analog Learning 200', '--missed-deadline',
     )
     course = Course.objects.get(title='Analog Learning 200')
     CourseRunFactory.create(course=course)
Beispiel #15
0
    def test_doesnt_list_courses_from_unlive_programs(self):
        """
        If the course belongs to a non-live program, hide it.
        """
        CourseRunFactory.create(course__program__live=False)

        resp = self.client.get(reverse('courserun-list'))

        assert len(resp.json()) == 0
Beispiel #16
0
def test_program_view(client, user, home_page, is_enrolled, has_product,
                      has_unexpired_run, is_anonymous):
    """
    Test that the program detail view has the right context and shows the right HTML for the enroll/view button
    """
    program = ProgramFactory.create(live=True, page__parent=home_page)

    if has_unexpired_run:
        now = now_in_utc()
        CourseRunFactory.create_batch(
            3,
            course=CourseFactory.create(program=program,
                                        live=True,
                                        position_in_program=1),
            live=True,
            start_date=now + timedelta(hours=2),
        )

    if has_product:
        product_id = ProductVersionFactory.create(product=ProductFactory(
            content_object=program)).product.id
    else:
        product_id = None
    if is_enrolled:
        ProgramEnrollmentFactory.create(user=user, program=program)

    if not is_anonymous:
        client.force_login(user)
    resp = client.get(program.page.get_url())
    assert resp.context["user"] == user if not is_anonymous else AnonymousUser(
    )
    assert resp.context["product_id"] == product_id
    assert resp.context["enrolled"] == (is_enrolled and not is_anonymous)

    # Anynoymous users don't see the enrolled/enroll-now button.
    # For logged in users:
    # a) product should exist, next courserun should be there, user not enrolled (enroll now button)
    # b) user is enrolled (enrolled button)
    has_button = ((has_product and has_unexpired_run and not is_enrolled)
                  or is_enrolled) and not is_anonymous
    url = ""  # make linter happy
    class_name = ""
    if not is_anonymous:
        if not is_enrolled and has_product and has_unexpired_run:
            url = f'{reverse("checkout-page")}?product={product_id}'
            class_name = "enroll-now"
        if is_enrolled:
            url = reverse("user-dashboard")
            class_name = "enrolled"

    assert (
        f'<a class="enroll-button {class_name}" href="{url}">'.encode("utf-8")
        in resp.content) is has_button
    assert ("Please Sign In to MITx PRO to enroll in a course".encode("utf-8")
            in resp.content) is (is_anonymous and has_product
                                 and has_unexpired_run)
Beispiel #17
0
 def test_serialized_semester_value(self):
     """
     Tests that semester information in a course run is serialized to the right values
     """
     valid_semester_course_run = CourseRunFactory.build(start_date=datetime(2017, 1, 1, tzinfo=pytz.UTC))
     no_semester_course_run = CourseRunFactory.build(start_date=None, edx_course_key='bad_key')
     valid_semester_serialized = UserProgramSearchSerializer.serialize_semester(valid_semester_course_run)
     no_semester_serialized = UserProgramSearchSerializer.serialize_semester(no_semester_course_run)
     assert valid_semester_serialized == '2017 - Spring'
     assert no_semester_serialized is None
Beispiel #18
0
def test_generate_program_certificate_failure(user, program):
    """
    Test that generate_program_certificate return (None, False) and not create program certificate
    if there is not any course_run certificate for the given course.
    """
    course = CourseFactory.create(program=program)
    CourseRunFactory.create_batch(3, course=course)

    result = generate_program_certificate(user=user, program=program)
    assert result == (None, False)
    assert len(ProgramCertificate.objects.all()) == 0
Beispiel #19
0
 def test_course_fuzzy_start_date(self):
     """Test course with promised course run"""
     CourseRunFactory.create(
         course=self.course,
         fuzzy_start_date="Fall 2017",
         start_date=None,
         end_date=None,
         enrollment_start=None,
         enrollment_end=None,
     )
     assert self.course.enrollment_text == 'Coming Fall 2017'
Beispiel #20
0
 def test_course_fuzzy_start_date(self):
     """Test course with promised course run"""
     CourseRunFactory.create(
         course=self.course,
         fuzzy_start_date="Fall 2017",
         start_date=None,
         end_date=None,
         enrollment_start=None,
         enrollment_end=None,
     )
     assert self.course.enrollment_text == 'Coming Fall 2017'
Beispiel #21
0
def test_course_run_invalid_expiration_date(start_delta, end_delta,
                                            expiration_delta):
    """
    Test that CourseRun.expiration_date raises ValidationError if expiration_date is before start_date or end_date
    """
    now = now_in_utc()
    with pytest.raises(ValidationError):
        CourseRunFactory.create(
            start_date=now + timedelta(days=start_delta),
            end_date=now + timedelta(days=end_delta),
            expiration_date=now + timedelta(days=expiration_delta),
        )
Beispiel #22
0
    def setUpTestData(cls):
        super().setUpTestData()
        # create an user
        cls.user = UserFactory.create()
        cls.cached_edx_user_data = MagicMock(
            spec=CachedEdxUserData,
            enrollments=CachedEnrollment.deserialize_edx_data(cls.enrollments_json),
            certificates=CachedCertificate.deserialize_edx_data(cls.certificates_json),
            current_grades=CachedCurrentGrade.deserialize_edx_data(cls.current_grades_json),
        )

        # create the programs
        cls.program = ProgramFactory.create(live=True, financial_aid_availability=False, price=1000)
        cls.program_financial_aid = ProgramFactory.create(live=True, financial_aid_availability=True, price=1000)

        # create course runs for the normal program
        cls.course = CourseFactory.create(program=cls.program)
        expected_course_keys = [
            "course-v1:edX+DemoX+Demo_Course",
            "course-v1:MITx+8.MechCX+2014_T1",
            '',
            None,
            'course-v1:odl+FOO102+CR-FALL16'
        ]

        cls.cruns = []
        for course_key in expected_course_keys:
            course_run = CourseRunFactory.create(
                course=cls.course,
                edx_course_key=course_key
            )
            if course_key:
                cls.cruns.append(course_run)

        # and the program with financial aid
        finaid_course = CourseFactory.create(program=cls.program_financial_aid)
        cls.now = now_in_utc()
        cls.end_date = cls.now - timedelta(weeks=45)
        cls.crun_fa = CourseRunFactory.create(
            course=finaid_course,
            start_date=cls.now-timedelta(weeks=52),
            end_date=cls.end_date,
            enrollment_start=cls.now-timedelta(weeks=62),
            enrollment_end=cls.now-timedelta(weeks=53),
            edx_course_key="course-v1:odl+FOO101+CR-FALL15"
        )
        cls.crun_fa2 = CourseRunFactory.create(
            course=finaid_course
        )
        CourseRunFactory.create(
            course=finaid_course,
            edx_course_key=None
        )
Beispiel #23
0
    def test_course_run_finder_success(self):
        """Tests that CourseRunFinder will return a desired course run"""
        course_run = CourseRunFactory.create(title='courserun1', edx_course_key='coursekey1')
        CourseRunFactory.create(title='courserun2', edx_course_key='coursekey2')

        found_course_runs = [
            CourseRunFinder.find(course_run_title='courserun1'),
            CourseRunFinder.find(course_run_title='run1'),
            CourseRunFinder.find(course_run_key='coursekey1'),
            CourseRunFinder.find(course_run_key='key1')
        ]
        assert all([course_run == found_course_run for found_course_run in found_course_runs])
Beispiel #24
0
    def setUpTestData(cls):
        super().setUpTestData()
        # create an user
        cls.user = UserFactory.create()
        cls.cached_edx_user_data = MagicMock(
            spec=CachedEdxUserData,
            enrollments=CachedEnrollment.deserialize_edx_data(cls.enrollments_json),
            certificates=CachedCertificate.deserialize_edx_data(cls.certificates_json),
            current_grades=CachedCurrentGrade.deserialize_edx_data(cls.current_grades_json),
        )

        # create the programs
        cls.program = ProgramFactory.create(live=True, financial_aid_availability=False, price=1000)
        cls.program_financial_aid = ProgramFactory.create(live=True, financial_aid_availability=True, price=1000)

        # create course runs for the normal program
        cls.course = CourseFactory.create(program=cls.program)
        expected_course_keys = [
            "course-v1:edX+DemoX+Demo_Course",
            "course-v1:MITx+8.MechCX+2014_T1",
            '',
            None,
            'course-v1:odl+FOO102+CR-FALL16'
        ]

        cls.cruns = []
        for course_key in expected_course_keys:
            course_run = CourseRunFactory.create(
                course=cls.course,
                edx_course_key=course_key
            )
            if course_key:
                cls.cruns.append(course_run)

        # and the program with financial aid
        finaid_course = CourseFactory.create(program=cls.program_financial_aid)
        cls.now = now_in_utc()
        cls.end_date = cls.now - timedelta(weeks=45)
        cls.crun_fa = CourseRunFactory.create(
            course=finaid_course,
            start_date=cls.now-timedelta(weeks=52),
            end_date=cls.end_date,
            enrollment_start=cls.now-timedelta(weeks=62),
            enrollment_end=cls.now-timedelta(weeks=53),
            edx_course_key="course-v1:odl+FOO101+CR-FALL15"
        )
        cls.crun_fa2 = CourseRunFactory.create(
            course=finaid_course
        )
        CourseRunFactory.create(
            course=finaid_course,
            edx_course_key=None
        )
Beispiel #25
0
    def test_lists_catalog(self):
        """Course Runs should show up"""
        program = ProgramFactory.create(live=True)
        for course in CourseFactory.create_batch(3, program=program):
            CourseRunFactory.create_batch(2, course=course)

        resp = self.client.get(reverse('catalog-list'))

        assert len(resp.json()) == 1
        data = CatalogProgramSerializer(program).data

        assert_drf_json_equal([data], resp.json())
Beispiel #26
0
 def setUpTestData(cls):
     """Create a set of course runs for testing"""
     super().setUpTestData()
     cls.run1 = CourseRunFactory.create(
         course__program__live=True,
         course__program__financial_aid_availability=True,
     )
     cls.program = cls.run1.course.program
     cls.run2 = CourseRunFactory.create(course=cls.run1.course)
     cls.runs = [cls.run1, cls.run2]
     cls.user = UserFactory.create()
     ProgramEnrollment.objects.create(user=cls.user, program=cls.run1.course.program)
Beispiel #27
0
 def setUpTestData(cls):
     """Create a set of course runs for testing"""
     super().setUpTestData()
     cls.run1 = CourseRunFactory.create(
         course__program__live=True,
         course__program__financial_aid_availability=True,
     )
     cls.program = cls.run1.course.program
     cls.run2 = CourseRunFactory.create(course=cls.run1.course)
     cls.runs = [cls.run1, cls.run2]
     cls.user = UserFactory.create()
     ProgramEnrollment.objects.create(user=cls.user, program=cls.run1.course.program)
 def setUpTestData(cls):
     cls.user = UserFactory.create(username='******',
                                   email='*****@*****.**')
     cls.course_runs = {
         'fa':
         CourseRunFactory.create(
             course__program__financial_aid_availability=True),
         'non_fa':
         CourseRunFactory.create(
             course__program__financial_aid_availability=False)
     }
     for course_run in cls.course_runs.values():
         ProgramEnrollmentFactory.create(user=cls.user,
                                         program=course_run.course.program)
Beispiel #29
0
 def test_serialized_semester_value(self):
     """
     Tests that semester information in a course run is serialized to the right values
     """
     valid_semester_course_run = CourseRunFactory.build(
         start_date=datetime(2017, 1, 1, tzinfo=pytz.UTC))
     no_semester_course_run = CourseRunFactory.build(
         start_date=None, edx_course_key='bad_key')
     valid_semester_serialized = UserProgramSearchSerializer.serialize_semester(
         valid_semester_course_run)
     no_semester_serialized = UserProgramSearchSerializer.serialize_semester(
         no_semester_course_run)
     assert valid_semester_serialized == '2017 - Spring'
     assert no_semester_serialized is None
Beispiel #30
0
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.run_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc()-timedelta(days=1),
            course__program__financial_aid_availability=True,
        )
        cls.run_fa_with_cert = CourseRunFactory.create(
            freeze_grade_date=None,
            course__program=cls.run_fa.course.program,
        )

        cls.run_no_fa = CourseRunFactory.create(
            freeze_grade_date=now_in_utc()+timedelta(days=1),
            course__program__financial_aid_availability=False,
        )
        cls.run_no_fa_with_cert = CourseRunFactory.create(
            course__program=cls.run_no_fa.course.program,
        )

        all_course_runs = (cls.run_fa, cls.run_fa_with_cert, cls.run_no_fa, cls.run_no_fa_with_cert, )

        for run in all_course_runs:
            if run.course.program.financial_aid_availability:
                FinancialAidFactory.create(
                    user=cls.user,
                    tier_program=TierProgramFactory.create(
                        program=run.course.program, income_threshold=0, current=True
                    ),
                    status=FinancialAidStatus.RESET,
                )

        cls.enrollments = {
            course_run.edx_course_key: CachedEnrollmentFactory.create(
                user=cls.user, course_run=course_run) for course_run in all_course_runs
        }

        cls.current_grades = {
            course_run.edx_course_key: CachedCurrentGradeFactory.create(
                user=cls.user, course_run=course_run) for course_run in all_course_runs
        }

        cls.certificates = {
            course_run.edx_course_key: CachedCertificateFactory.create(
                user=cls.user, course_run=course_run) for course_run in (cls.run_fa_with_cert, cls.run_no_fa_with_cert)
        }

        cls.user_edx_data = CachedEdxUserData(cls.user)
    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
            )
Beispiel #32
0
    def setUpTestData(cls):
        super().setUpTestData()

        cls.user = UserFactory()
        cls.user.social_auth.create(
            provider='not_edx',
        )
        cls.user.social_auth.create(
            provider=EdxOrgOAuth2.name,
            uid="{}_edx".format(cls.user.username),
        )
        cls.order = OrderFactory.create(status=Order.CREATED, user=cls.user)
        cls.line1 = LineFactory.create(order=cls.order)
        cls.line2 = LineFactory.create(order=cls.order)
        cls.course_run1 = CourseRunFactory.create(edx_course_key=cls.line1.course_key)
        cls.course_run2 = CourseRunFactory.create(edx_course_key=cls.line2.course_key)
Beispiel #33
0
 def test_program(self):  # pylint: disable=no-self-use
     """
     Make sure program id appears correctly
     """
     course_run = CourseRunFactory.create()
     result = CourseRunSerializer().to_representation(course_run)
     assert result['program'] == course_run.course.program.id
Beispiel #34
0
 def _generate_cached_enrollments(user,
                                  program,
                                  num_course_runs=1,
                                  data=None):
     """
     Helper method to generate CachedEnrollments for test cases
     """
     fake = faker.Factory.create()
     course = CourseFactory.create(program=program)
     course_run_params = dict(before_now=True,
                              after_now=False,
                              tzinfo=pytz.utc)
     course_runs = [
         CourseRunFactory.create(
             course=course,
             enrollment_start=fake.date_time_this_month(
                 **course_run_params),
             start_date=fake.date_time_this_month(**course_run_params),
             enrollment_end=fake.date_time_this_month(**course_run_params),
             end_date=fake.date_time_this_year(**course_run_params),
         ) for _ in range(num_course_runs)
     ]
     factory_kwargs = dict(user=user)
     if data is not None:
         factory_kwargs['data'] = data
     return [
         CachedEnrollmentFactory.create(course_run=course_run,
                                        **factory_kwargs)
         for course_run in course_runs
     ]
    def test_course_keys(self):
        """
        Coupon.course_keys should return a list of all course run keys in a program, course, or course run
        """
        run1 = CourseRunFactory.create(course__program__financial_aid_availability=True)
        run2 = CourseRunFactory.create(course=run1.course)
        run3 = CourseRunFactory.create(course__program=run1.course.program)
        run4 = CourseRunFactory.create(course=run3.course)

        coupon_program = CouponFactory.create(
            content_object=run1.course.program,
        )
        assert sorted(coupon_program.course_keys) == sorted([run.edx_course_key for run in [run1, run2, run3, run4]])

        coupon_course = CouponFactory.create(content_object=run1.course)
        assert sorted(coupon_course.course_keys) == sorted([run.edx_course_key for run in [run1, run2]])
Beispiel #36
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
Beispiel #37
0
 def test_course_serialization_format(self):
     """
     Tests that a user's course enrollments are serialized in a specific format
     """
     for program_enrollment in (self.non_fa_program_enrollment,
                                self.fa_program_enrollment):
         program = program_enrollment.program
         # Generate a new course run on an existing course, and create an unverified enrollment in it
         existing_course = program.course_set.first()
         new_course_run = CourseRunFactory(course=existing_course)
         self.unverified_enroll(self.user, course_run=new_course_run)
         # Generate a new course with only unverified course run enrollments
         unver_course, unver_course_runs = self.generate_course_with_runs(
             program,
             course_params=dict(title='Unverified Course'),
             course_run_count=2)
         for course_run in unver_course_runs:
             self.unverified_enroll(self.user, course_run=course_run)
         # Serialize the program enrollment and make sure each course is serialized properly
         serialized_program_user = UserProgramSearchSerializer.serialize(
             program_enrollment)
         serialized_enrollments = serialized_program_user['courses']
         assert len(serialized_enrollments) == 2
         # A course with a mix of verified and unverified course runs should be serialized as verified
         assert self.is_course_serialized_with_status(
             serialized_enrollments, existing_course, is_verified=True)
         # A course with a mix of all unverified course runs should be serialized as unverified
         assert self.is_course_serialized_with_status(
             serialized_enrollments, unver_course, is_verified=False)
Beispiel #38
0
    def setUpTestData(cls):
        super().setUpTestData()

        cls.user = UserFactory()
        cls.user.social_auth.create(
            provider='not_edx',
        )
        cls.user.social_auth.create(
            provider=EdxOrgOAuth2.name,
            uid="{}_edx".format(cls.user.username),
        )
        cls.order = OrderFactory.create(status=Order.CREATED, user=cls.user)
        cls.line1 = LineFactory.create(order=cls.order)
        cls.line2 = LineFactory.create(order=cls.order)
        cls.course_run1 = CourseRunFactory.create(edx_course_key=cls.line1.course_key)
        cls.course_run2 = CourseRunFactory.create(edx_course_key=cls.line2.course_key)
Beispiel #39
0
    def setUpTestData(cls):
        cls.users = [UserFactory.create() for _ in range(35)]

        freeze_date = now_in_utc()-timedelta(days=1)
        future_freeze_date = now_in_utc()+timedelta(days=1)
        cls.course_run1 = CourseRunFactory.create(freeze_grade_date=freeze_date)
        cls.course_run2 = CourseRunFactory.create(freeze_grade_date=freeze_date)
        cls.all_freezable_runs = [cls.course_run1, cls.course_run2]

        cls.course_run_future = CourseRunFactory.create(freeze_grade_date=future_freeze_date)
        cls.course_run_frozen = CourseRunFactory.create(freeze_grade_date=freeze_date)

        CourseRunGradingStatus.objects.create(course_run=cls.course_run_frozen, status=FinalGradeStatus.COMPLETE)

        for user in cls.users:
            CachedEnrollmentFactory.create(user=user, course_run=cls.course_run1)
            CachedCurrentGradeFactory.create(user=user, course_run=cls.course_run1)
Beispiel #40
0
 def generate_course_with_runs(program, course_params=None, course_run_count=1):
     """
     Helper method to generate a Course with CourseRuns for a Program
     """
     course_params = course_params or {}
     course = CourseFactory.create(program=program, **course_params)
     course_runs = CourseRunFactory.create_batch(course_run_count, course=course)
     return course, course_runs
Beispiel #41
0
    def test_user_has_redemptions_left(self, order_status, has_unpurchased_run, another_already_redeemed, expected):
        """
        Coupon.user_has_redemptions_left should be true if user has not yet purchased all course runs
        """
        run1 = CourseRunFactory.create(course__program__financial_aid_availability=True)
        if has_unpurchased_run:
            CourseRunFactory.create(course__program=run1.course.program)

        line = LineFactory.create(course_key=run1.edx_course_key, order__status=order_status)
        coupon = CouponFactory.create(content_object=run1.course.program)
        with patch(
            'ecommerce.models.Coupon.another_user_already_redeemed',
            autospec=True,
        ) as _already_redeemed:
            _already_redeemed.return_value = another_already_redeemed
            assert coupon.user_has_redemptions_left(line.order.user) is expected
        _already_redeemed.assert_called_with(coupon, line.order.user)
    def create_passed_and_offered_course_run(self, grades_frozen, with_certificate):
        """Make passed and currently offered course run, and see the View Certificate and Re-Enroll"""
        self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED)
        call_command(
            "alter_data", 'set_to_passed', '--username', 'staff',
            '--course-title', 'Digital Learning 200', '--grade', '89',
        )
        course = Course.objects.get(title='Digital Learning 200')
        # create another currently offered run
        CourseRunFactory.create(course=course)

        if grades_frozen:
            final_grade = FinalGrade.objects.filter(user=self.user, course_run__course=course, passed=True).first()
            CourseRunGradingStatus.objects.create(course_run=final_grade.course_run, status='complete')
            if with_certificate:
                MicromastersCourseCertificate.objects.create(user=self.user, course=course)
                CourseCertificateSignatoriesFactory.create(course=course)
Beispiel #43
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()
Beispiel #44
0
    def setUpTestData(cls):
        cls.user = SocialUserFactory.create()

        cls.run_1 = CourseRunFactory.create(
            freeze_grade_date=now_in_utc()-timedelta(days=1),
            course__program__financial_aid_availability=True,
        )
        cls.program = cls.run_1.course.program
Beispiel #45
0
 def setUpTestData(cls):
     cls.user = SocialUserFactory.create()
     cls.run_1 = CourseRunFactory.create(
         freeze_grade_date=now_in_utc()-timedelta(days=1),
         course__program__financial_aid_availability=True,
     )
     CourseRunGradingStatus.objects.create(course_run=cls.run_1, status='complete')
     cls.program = cls.run_1.course.program
Beispiel #46
0
 def test_course_with_run(self):
     """
     Make sure the course URL serializes properly
     """
     course_run = CourseRunFactory.create()
     course = course_run.course
     data = CourseSerializer(course).data
     assert data['url'] == course_run.enrollment_url
     assert data['enrollment_text'] == course.enrollment_text
Beispiel #47
0
 def setUpTestData(cls):
     """
     Create user, run, and coupons for testing
     """
     super().setUpTestData()
     cls.user = SocialProfileFactory.create().user
     UserSocialAuthFactory.create(user=cls.user, provider='not_edx')
     run = CourseRunFactory.create(course__program__financial_aid_availability=True)
     cls.coupon = CouponFactory.create(content_object=run.course.program)
     UserCoupon.objects.create(coupon=cls.coupon, user=cls.user)
Beispiel #48
0
 def test_coupon_allowed_course(self):
     """
     Assert that the price is not adjusted if the coupon is for a different course in the same program
     """
     course_run, _ = create_purchasable_course_run()
     other_course = CourseRunFactory.create(course__program=course_run.course.program).course
     price = Decimal('0.3')
     coupon = CouponFactory.create(content_object=other_course)
     assert coupon.content_object != course_run
     assert calculate_coupon_price(coupon, price, course_run.edx_course_key) == price
Beispiel #49
0
    def test_another_user_already_redeemed(self, order_status, other_user_redeemed, is_automatic, expected):
        """
        Tests for Coupon.another_user_already_redeemed
        """
        run1 = CourseRunFactory.create(course__program__financial_aid_availability=True)
        run2 = CourseRunFactory.create(course=run1.course)
        coupon = CouponFactory.create(
            content_object=run1.course,
            coupon_type=Coupon.DISCOUNTED_PREVIOUS_COURSE if is_automatic else Coupon.STANDARD,
        )

        line1 = LineFactory.create(course_key=run1.edx_course_key, order__status=Order.FULFILLED)
        RedeemedCoupon.objects.create(order=line1.order, coupon=coupon)

        if other_user_redeemed:
            line2 = LineFactory.create(course_key=run2.edx_course_key, order__status=order_status)
            RedeemedCoupon.objects.create(order=line2.order, coupon=coupon)

        assert coupon.another_user_already_redeemed(line1.order.user) is expected
Beispiel #50
0
 def test_deserialize_user_data(self):
     """Test that user data is correctly deserialized"""
     new_course_run = CourseRunFactory.create(edx_course_key='course-v1:MITx+Analog+Learning+100+Aug_2015')
     new_program = new_course_run.course.program
     with mute_signals(post_save):
         user = deserialize_user_data(self.USER_DATA, [new_program])
     assert user.username == '{}mario.medina'.format(FAKE_USER_USERNAME_PREFIX)
     assert user.profile.first_name == 'Mario'
     assert user.profile.date_of_birth == '1961-04-29'
     assert CachedEnrollment.objects.filter(user=user, course_run=new_course_run).count() == 1
Beispiel #51
0
 def test_course_run(self):
     """
     Make sure course run serializer correctly
     """
     course_run = CourseRunFactory.create()
     data = CourseRunSerializer(course_run).data
     expected = {
         'edx_course_key': course_run.edx_course_key,
         'program_title': course_run.course.program.title,
     }
     assert data == expected
Beispiel #52
0
    def setUpTestData(cls):
        super().setUpTestData()
        # create a user
        cls.user = SocialUserFactory.create()

        # create the course run
        cls.course_id = "edx+fake+key"
        cls.course_run = CourseRunFactory.create(edx_course_key=cls.course_id)

        # url for the dashboard
        cls.url = reverse('user_course_enrollments')
Beispiel #53
0
    def create_frozen_run(self, course):
        """helper function to create frozen course runs"""

        now = now_in_utc()
        run = CourseRunFactory.create(
            course=course,
            title="Title Run",
            freeze_grade_date=now - timedelta(weeks=1),
        )
        CourseRunGradingStatus.objects.create(course_run=run, status='complete')
        return run
Beispiel #54
0
 def test_validate_discount_prev_run_coupon_type(self):
     """Coupon must be for a course if Coupon.coupon_type is DISCOUNTED_PREVIOUS_RUN"""
     run = CourseRunFactory.create()
     with self.assertRaises(ValidationError) as ex:
         CouponFactory.create(
             coupon_type=Coupon.DISCOUNTED_PREVIOUS_COURSE,
             content_object=run.course.program,
         )
     assert ex.exception.args[0]['__all__'][0].args[0] == (
         'coupon must be for a course if coupon_type is discounted-previous-course'
     )