Ejemplo n.º 1
0
def test_retry_failed_edx_enrollments(mocker, exception_raised):
    """
    Tests that retry_failed_edx_enrollments loops through enrollments that failed in edX
    and attempts to enroll them again
    """
    with freeze_time(now_in_utc() - timedelta(days=1)):
        failed_enrollments = CourseRunEnrollmentFactory.create_batch(
            3, edx_enrolled=False, user__is_active=True)
        CourseRunEnrollmentFactory.create(edx_enrolled=False,
                                          user__is_active=False)
    patched_enroll_in_edx = mocker.patch(
        "courseware.api.enroll_in_edx_course_runs",
        side_effect=[None, exception_raised or None, None],
    )
    patched_log_exception = mocker.patch("courseware.api.log.exception")
    successful_enrollments = retry_failed_edx_enrollments()

    assert patched_enroll_in_edx.call_count == len(failed_enrollments)
    assert len(successful_enrollments) == (3
                                           if exception_raised is None else 2)
    assert patched_log_exception.called == bool(exception_raised)
    if exception_raised:
        failed_enroll_user, failed_enroll_runs = patched_enroll_in_edx.call_args_list[
            1][0]
        expected_successful_enrollments = [
            e for e in failed_enrollments
            if e.user != failed_enroll_user and e.run != failed_enroll_runs[0]
        ]
        assert {e.id
                for e in successful_enrollments
                } == {e.id
                      for e in expected_successful_enrollments}
Ejemplo n.º 2
0
def test_defer_enrollment_validation(mocker, user):
    """
    defer_enrollment should raise an exception if the 'from' or 'to' course runs are invalid
    """
    courses = CourseFactory.create_batch(2)
    enrollments = CourseRunEnrollmentFactory.create_batch(
        3,
        user=user,
        active=factory.Iterator([False, True, True]),
        run__course=factory.Iterator([courses[0], courses[0], courses[1]]),
    )
    unenrollable_run = CourseRunFactory.create(enrollment_end=now_in_utc() -
                                               timedelta(days=1))
    patched_create_enrollments = mocker.patch(
        "courses.api.create_run_enrollments", return_value=([], False))
    mocker.patch("courses.api.deactivate_run_enrollment", return_value=[])

    with pytest.raises(ValidationError):
        # Deferring to the same course run should raise a validation error
        defer_enrollment(user, enrollments[0].run.courseware_id,
                         enrollments[0].run.courseware_id)
    patched_create_enrollments.assert_not_called()

    with pytest.raises(ValidationError):
        # Deferring to a course run that is outside of its enrollment period should raise a validation error
        defer_enrollment(user, enrollments[0].run.courseware_id,
                         unenrollable_run.courseware_id)
    patched_create_enrollments.assert_not_called()

    with pytest.raises(ValidationError):
        # Deferring from an inactive enrollment should raise a validation error
        defer_enrollment(user, enrollments[0].run.courseware_id,
                         enrollments[1].run.courseware_id)
    patched_create_enrollments.assert_not_called()

    with pytest.raises(ValidationError):
        # Deferring to a course run in a different course should raise a validation error
        defer_enrollment(user, enrollments[1].run.courseware_id,
                         enrollments[2].run.courseware_id)
    patched_create_enrollments.assert_not_called()

    # The last two cases should not raise an exception if the 'force' flag is set to True
    defer_enrollment(
        user,
        enrollments[0].run.courseware_id,
        enrollments[1].run.courseware_id,
        force=True,
    )
    assert patched_create_enrollments.call_count == 1
    defer_enrollment(
        user,
        enrollments[1].run.courseware_id,
        enrollments[2].run.courseware_id,
        force=True,
    )
    assert patched_create_enrollments.call_count == 2
Ejemplo n.º 3
0
def test_get_program_run_enrollments(user):
    """
    Test that the get_program_run_enrollments helper method for CourseRunEnrollment returns
    the appropriate course run enrollments for a program
    """
    programs = ProgramFactory.create_batch(2)
    program = programs[0]
    course_run_enrollments = CourseRunEnrollmentFactory.create_batch(
        2,
        user=user,
        run__course__program=factory.Iterator([program, program, programs[1]]),
    )
    expected_run_enrollments = set(course_run_enrollments[0:2])
    assert (set(CourseRunEnrollment.get_program_run_enrollments(
        user, program)) == expected_run_enrollments)
Ejemplo n.º 4
0
    def test_deactivate_program_enrollment(self, user, patches):
        """
        deactivate_program_enrollment set the local program enrollment record to inactive as well as all
        associated course run enrollments
        """
        order = OrderFactory.create()
        program_enrollment = ProgramEnrollmentFactory.create(user=user,
                                                             order=order)
        course = CourseFactory.create(program=program_enrollment.program)
        course_run_enrollments = CourseRunEnrollmentFactory.create_batch(
            3,
            user=user,
            run__course=course,
            active=True,
            order=factory.Iterator([order, order, None]),
        )
        expected_inactive_run_enrollments = course_run_enrollments[0:2]
        expected_ignored_run_enrollment = course_run_enrollments[2]

        returned_program_enrollment, returned_run_enrollments = deactivate_program_enrollment(
            program_enrollment, change_status=ENROLL_CHANGE_STATUS_REFUNDED)
        program_enrollment.refresh_from_db()
        assert program_enrollment.change_status == ENROLL_CHANGE_STATUS_REFUNDED
        assert program_enrollment.active is False
        assert returned_program_enrollment == program_enrollment
        assert {e.id
                for e in returned_run_enrollments
                } == {e.id
                      for e in expected_inactive_run_enrollments}
        assert patches.edx_unenroll.call_count == len(
            expected_inactive_run_enrollments)
        assert patches.send_unenrollment_email.call_count == len(
            expected_inactive_run_enrollments)
        for run_enrollment in expected_inactive_run_enrollments:
            run_enrollment.refresh_from_db()
            assert run_enrollment.change_status == ENROLL_CHANGE_STATUS_REFUNDED
            assert run_enrollment.active is False
        assert expected_ignored_run_enrollment.active is True
Ejemplo n.º 5
0
def test_serialize_program_enrollments(settings, has_company,
                                       receipts_enabled):
    """Test that ProgramEnrollmentSerializer has correct data"""
    settings.ENABLE_ORDER_RECEIPTS = receipts_enabled
    program = ProgramFactory.create()
    course_run_enrollments = CourseRunEnrollmentFactory.create_batch(
        3,
        run__course__program=factory.Iterator([program, program, None]),
        run__course__position_in_program=factory.Iterator([2, 1, None]),
    )
    program_enrollment = ProgramEnrollmentFactory.create(
        program=program, has_company_affiliation=has_company)
    serialized_data = ProgramEnrollmentSerializer(program_enrollment,
                                                  context={
                                                      "course_run_enrollments":
                                                      course_run_enrollments
                                                  }).data
    assert serialized_data == {
        "id":
        program_enrollment.id,
        "program":
        BaseProgramSerializer(program).data,
        "company": (CompanySerializer(program_enrollment.company).data
                    if has_company else None),
        # Only enrollments for the given program should be serialized, and they should be
        # sorted by position in program.
        "course_run_enrollments":
        CourseRunEnrollmentSerializer(
            [course_run_enrollments[1], course_run_enrollments[0]],
            many=True).data,
        "certificate":
        None,
        "receipt":
        program_enrollment.order_id
        if program_enrollment.order.status == Order.FULFILLED
        and receipts_enabled else None,
    }
Ejemplo n.º 6
0
def test_get_user_enrollments(user):
    """Test that get_user_enrollments returns an object with a user's program and course enrollments"""
    past_date = now_in_utc() - timedelta(days=1)
    past_start_dates = [
        now_in_utc() - timedelta(days=2),
        now_in_utc() - timedelta(days=3),
        now_in_utc() - timedelta(days=4),
    ]
    program = ProgramFactory.create()
    past_program = ProgramFactory.create()

    program_course_runs = CourseRunFactory.create_batch(
        3, course__program=program)
    past_program_course_runs = CourseRunFactory.create_batch(
        3,
        start_date=factory.Iterator(past_start_dates),
        end_date=past_date,
        course__program=past_program,
    )
    non_program_course_runs = CourseRunFactory.create_batch(
        2, course__program=None)
    past_non_program_course_runs = CourseRunFactory.create_batch(
        2,
        start_date=factory.Iterator(past_start_dates),
        end_date=past_date,
        course__program=None,
    )
    all_course_runs = (program_course_runs + past_program_course_runs +
                       non_program_course_runs + past_non_program_course_runs)
    course_run_enrollments = CourseRunEnrollmentFactory.create_batch(
        len(all_course_runs), run=factory.Iterator(all_course_runs), user=user)
    program_enrollment = ProgramEnrollmentFactory.create(program=program,
                                                         user=user)
    past_program_enrollment = ProgramEnrollmentFactory.create(
        program=past_program, user=user)
    # Add a non-active enrollment so we can confirm that it isn't returned
    CourseRunEnrollmentFactory.create(user=user, active=False)

    def key_func(enrollment):
        """ Function for sorting runs by start_date"""
        return enrollment.run.start_date

    user_enrollments = get_user_enrollments(user)
    assert list(user_enrollments.programs) == [program_enrollment]
    assert list(user_enrollments.past_programs) == [past_program_enrollment]
    assert list(user_enrollments.program_runs) == sorted(
        [
            run_enrollment for run_enrollment in course_run_enrollments
            if run_enrollment.run in program_course_runs +
            past_program_course_runs
        ],
        key=key_func,
    )
    assert list(user_enrollments.non_program_runs) == sorted(
        [
            run_enrollment for run_enrollment in course_run_enrollments
            if run_enrollment.run in non_program_course_runs
        ],
        key=key_func,
    )

    assert list(user_enrollments.past_non_program_runs) == sorted(
        [
            run_enrollment for run_enrollment in course_run_enrollments
            if run_enrollment.run in past_non_program_course_runs
        ],
        key=key_func,
    )