Beispiel #1
0
    def test_retry_until_verification_status_updates(self, user_status_mock, generate_user_certs_mock):
        course_key = 'course-v1:edX+CS101+2017_T2'
        student = UserFactory()

        kwargs = {
            'student': student.id,
            'course_key': course_key,
            'expected_verification_status': IDVerificationAttempt.STATUS.approved
        }

        user_status_mock.side_effect = [
            {'status': 'pending', 'error': '', 'should_display': True},
            {'status': 'approved', 'error': '', 'should_display': True}
        ]

        generate_certificate.apply_async(kwargs=kwargs).get()

        user_status_mock.assert_has_calls([
            call(student),
            call(student)
        ])

        generate_user_certs_mock.assert_called_once_with(
            student=student,
            course_key=CourseKey.from_string(course_key)
        )
Beispiel #2
0
    def test_retry_until_verification_status_updates(self, user_status_mock, generate_user_certs_mock):
        course_key = 'course-v1:edX+CS101+2017_T2'
        student = UserFactory()

        kwargs = {
            'student': student.id,
            'course_key': course_key,
            'expected_verification_status': IDVerificationAttempt.STATUS.approved
        }

        user_status_mock.side_effect = [
            {'status': 'pending', 'error': '', 'should_display': True},
            {'status': 'approved', 'error': '', 'should_display': True}
        ]

        generate_certificate.apply_async(kwargs=kwargs).get()

        user_status_mock.assert_has_calls([
            call(student),
            call(student)
        ])

        generate_user_certs_mock.assert_called_once_with(
            student=student,
            course_key=CourseKey.from_string(course_key)
        )
Beispiel #3
0
    def test_missing_args(self, missing_arg):
        kwargs = {'student': 'a', 'course_key': 'b', 'otherarg': 'c'}
        del kwargs[missing_arg]

        with patch('lms.djangoapps.certificates.tasks.User.objects.get'):
            with self.assertRaisesRegex(KeyError, missing_arg):
                generate_certificate.apply_async(kwargs=kwargs).get()
Beispiel #4
0
    def test_generation_mode(self):
        """
        Verify the task handles V2 certificate generation with a generation mode
        """
        course_key = 'course-v1:edX+DemoX+Demo_Course'
        gen_mode = 'self'

        with mock.patch(
            'lms.djangoapps.certificates.tasks.generate_course_certificate',
            return_value=None
        ) as mock_generate_cert:
            kwargs = {
                'student': self.user.id,
                'course_key': course_key,
                'v2_certificate': True,
                'generation_mode': gen_mode
            }

            generate_certificate.apply_async(kwargs=kwargs)
            mock_generate_cert.assert_called_with(
                user=self.user,
                course_key=CourseKey.from_string(course_key),
                status=CertificateStatuses.downloadable,
                generation_mode=gen_mode
            )
    def test_generation_custom(self):
        """
        Verify the task handles certificate generation custom params
        """
        gen_mode = 'self'
        status = CertificateStatuses.notpassing
        enrollment_mode = CourseMode.AUDIT
        course_grade = '0.89'

        with mock.patch(
                'lms.djangoapps.certificates.tasks.generate_course_certificate',
                return_value=None) as mock_generate_cert:
            kwargs = {
                'status': status,
                'student': self.user.id,
                'course_key': self.course_key,
                'course_grade': course_grade,
                'enrollment_mode': enrollment_mode,
                'generation_mode': gen_mode,
                'what_about': 'dinosaurs'
            }

            generate_certificate.apply_async(kwargs=kwargs)
            mock_generate_cert.assert_called_with(
                user=self.user,
                course_key=CourseKey.from_string(self.course_key),
                status=status,
                enrollment_mode=enrollment_mode,
                course_grade=course_grade,
                generation_mode=gen_mode)
Beispiel #6
0
    def test_missing_args(self, missing_arg):
        kwargs = {'student': 'a', 'course_key': 'b', 'otherarg': 'c'}
        del kwargs[missing_arg]

        with patch('lms.djangoapps.certificates.tasks.User.objects.get'):
            with self.assertRaisesRegexp(KeyError, missing_arg):
                generate_certificate.apply_async(kwargs=kwargs).get()
def _generate_certificate_task(user,
                               course_key,
                               enrollment_mode,
                               course_grade,
                               status=None,
                               generation_mode=None,
                               delay_seconds=CERTIFICATE_DELAY_SECONDS):
    """
    Create a task to generate a certificate
    """
    log.info(
        f'About to create a regular certificate task for {user.id} : {course_key}'
    )

    course_grade_val = _get_grade_value(course_grade)

    kwargs = {
        'student': str(user.id),
        'course_key': str(course_key),
        'enrollment_mode': str(enrollment_mode),
        'course_grade': str(course_grade_val)
    }
    if status is not None:
        kwargs['status'] = status
    if generation_mode is not None:
        kwargs['generation_mode'] = generation_mode

    generate_certificate.apply_async(countdown=delay_seconds, kwargs=kwargs)
    return True
Beispiel #8
0
def _fire_ungenerated_certificate_task(user,
                                       course_key,
                                       expected_verification_status=None):
    """
    Helper function to fire certificate generation task.
    Auto-generation of certificates is available for following course modes:
        1- VERIFIED
        2- CREDIT_MODE
        3- PROFESSIONAL
        4- NO_ID_PROFESSIONAL_MODE

    Certificate generation task is fired to either generate a certificate
    when there is no generated certificate for user in a particular course or
    update a certificate if it has 'unverified' status.

    Task is fired to attempt an update to a certificate
    with 'unverified' status as this method is called when a user is
    successfully verified, any certificate associated
    with such user can now be verified.

    NOTE: Purpose of restricting other course modes (HONOR and AUDIT) from auto-generation is to reduce
    traffic to workers.
    """

    message = u'Entered into Ungenerated Certificate task for {user} : {course}'
    log.info(message.format(user=user.id, course=course_key))

    allowed_enrollment_modes_list = [
        CourseMode.VERIFIED,
        CourseMode.CREDIT_MODE,
        CourseMode.PROFESSIONAL,
        CourseMode.NO_ID_PROFESSIONAL_MODE,
        CourseMode.MASTERS,
        CourseMode.EXECUTIVE_EDUCATION,
    ]
    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(
        user, course_key)
    cert = GeneratedCertificate.certificate_for_student(user, course_key)

    generate_learner_certificate = (
        enrollment_mode in allowed_enrollment_modes_list
        and (cert is None or cert.status == 'unverified'))

    if generate_learner_certificate:
        kwargs = {
            'student': six.text_type(user.id),
            'course_key': six.text_type(course_key)
        }
        if expected_verification_status:
            kwargs['expected_verification_status'] = six.text_type(
                expected_verification_status)
        generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS,
                                         kwargs=kwargs)
        return True

    message = u'Certificate Generation task failed for {user} : {course}'
    log.info(message.format(user=user.id, course=course_key))
    return False
    def test_missing_args(self, missing_arg):
        kwargs = {
            'student': self.user.id,
            'course_key': self.course_key,
            'other_arg': 'shiny',
            'enrollment_mode': CourseMode.MASTERS
        }
        del kwargs[missing_arg]

        with patch('lms.djangoapps.certificates.tasks.User.objects.get'):
            with self.assertRaisesRegex(KeyError, missing_arg):
                generate_certificate.apply_async(kwargs=kwargs).get()
Beispiel #10
0
def _generate_certificate_task(user, course_key, generation_mode=None):
    """
    Create a task to generate a certificate
    """
    log.info(f'About to create a V2 certificate task for {user.id} : {course_key}')

    kwargs = {
        'student': str(user.id),
        'course_key': str(course_key),
        'v2_certificate': True
    }
    if generation_mode is not None:
        kwargs['generation_mode'] = generation_mode

    generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS, kwargs=kwargs)
    return True
Beispiel #11
0
def fire_ungenerated_certificate_task(user, course_key, expected_verification_status=None):
    """
    Helper function to fire certificate generation task.
    Auto-generation of certificates is available for following course modes:
        1- VERIFIED
        2- CREDIT_MODE
        3- PROFESSIONAL
        4- NO_ID_PROFESSIONAL_MODE

    Certificate generation task is fired to either generate a certificate
    when there is no generated certificate for user in a particular course or
    update a certificate if it has 'unverified' status.

    Task is fired to attempt an update to a certificate
    with 'unverified' status as this method is called when a user is
    successfully verified, any certificate associated
    with such user can now be verified.

    NOTE: Purpose of restricting other course modes (HONOR and AUDIT) from auto-generation is to reduce
    traffic to workers.
    """

    allowed_enrollment_modes_list = [
        CourseMode.VERIFIED,
        CourseMode.CREDIT_MODE,
        CourseMode.PROFESSIONAL,
        CourseMode.NO_ID_PROFESSIONAL_MODE,
        CourseMode.MASTERS,
    ]
    enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(user, course_key)
    cert = GeneratedCertificate.certificate_for_student(user, course_key)

    generate_learner_certificate = (
        enrollment_mode in allowed_enrollment_modes_list and (cert is None or cert.status == 'unverified')
    )

    if generate_learner_certificate:
        kwargs = {
            'student': unicode(user.id),
            'course_key': unicode(course_key)
        }
        if expected_verification_status:
            kwargs['expected_verification_status'] = unicode(expected_verification_status)
        generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS, kwargs=kwargs)
        return True
Beispiel #12
0
    def test_generate_user_certs(self, user_get_mock, generate_user_certs_mock):
        course_key = 'course-v1:edX+CS101+2017_T2'
        kwargs = {
            'student': 'student-id',
            'course_key': course_key,
            'otherarg': 'c',
            'otherotherarg': 'd'
        }
        generate_certificate.apply_async(kwargs=kwargs).get()

        expected_student = user_get_mock.return_value
        generate_user_certs_mock.assert_called_with(
            student=expected_student,
            course_key=CourseKey.from_string(course_key),
            otherarg='c',
            otherotherarg='d'
        )
        user_get_mock.assert_called_once_with(id='student-id')
Beispiel #13
0
    def test_generate_user_certs(self, user_get_mock, generate_user_certs_mock):
        course_key = 'course-v1:edX+CS101+2017_T2'
        kwargs = {
            'student': 'student-id',
            'course_key': course_key,
            'otherarg': 'c',
            'otherotherarg': 'd'
        }
        generate_certificate.apply_async(kwargs=kwargs).get()

        expected_student = user_get_mock.return_value
        generate_user_certs_mock.assert_called_with(
            student=expected_student,
            course_key=CourseKey.from_string(course_key),
            otherarg='c',
            otherotherarg='d'
        )
        user_get_mock.assert_called_once_with(id='student-id')
def _generate_certificate_task(user,
                               course_key,
                               enrollment_mode,
                               course_grade,
                               status=None,
                               generation_mode=None,
                               delay_seconds=CERTIFICATE_DELAY_SECONDS):
    """
    Create a task to generate a certificate
    """
    log.info(
        f'About to create a regular certificate task for {user.id} : {course_key}'
    )

    course_grade_val = _get_grade_value(course_grade)

    try:
        # .. filter_implemented_name: CertificateCreationRequested
        # .. filter_type: org.openedx.learning.certificate.creation.requested.v1
        user, course_key, enrollment_mode, status, course_grade, generation_mode = CertificateCreationRequested.run_filter(  # pylint: disable=line-too-long
            user=user,
            course_key=course_key,
            mode=enrollment_mode,
            status=status,
            grade=course_grade,
            generation_mode=generation_mode,
        )
    except CertificateCreationRequested.PreventCertificateCreation as exc:
        raise CertificateGenerationNotAllowed(str(exc)) from exc

    kwargs = {
        'student': str(user.id),
        'course_key': str(course_key),
        'enrollment_mode': str(enrollment_mode),
        'course_grade': str(course_grade_val)
    }
    if status is not None:
        kwargs['status'] = status
    if generation_mode is not None:
        kwargs['generation_mode'] = generation_mode

    generate_certificate.apply_async(countdown=delay_seconds, kwargs=kwargs)
    return True
Beispiel #15
0
def generate_allowlist_certificate_task(user, course_key):
    """
    Create a task to generate an allowlist certificate for this user in this course run.
    """
    if not can_generate_allowlist_certificate(user, course_key):
        log.info(
            'Cannot generate an allowlist certificate for {user} : {course}'.format(user=user.id, course=course_key))
        return False

    log.info(
        'About to create an allowlist certificate task for {user} : {course}'.format(user=user.id, course=course_key))

    kwargs = {
        'student': str(user.id),
        'course_key': str(course_key),
        'allowlist_certificate': True
    }
    generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS, kwargs=kwargs)
    return True
def generate_regular_certificate_task(user, course_key):
    """
    Create a task to generate a regular (non-allowlist) certificate for this user in this course run, if the user is
    eligible and a certificate can be generated.
    """
    if not _can_generate_v2_certificate(user, course_key):
        log.info(
            f'Cannot generate a v2 course certificate for {user.id} : {course_key}'
        )
        return False

    log.info(
        f'About to create a v2 course certificate task for {user.id} : {course_key}'
    )

    kwargs = {
        'student': str(user.id),
        'course_key': str(course_key),
        'v2_certificate': True
    }
    generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS,
                                     kwargs=kwargs)
    return True
    def test_generation(self):
        """
        Verify the task handles certificate generation
        """
        enrollment_mode = CourseMode.VERIFIED

        with mock.patch(
                'lms.djangoapps.certificates.tasks.generate_course_certificate',
                return_value=None) as mock_generate_cert:
            kwargs = {
                'student': self.user.id,
                'course_key': self.course_key,
                'enrollment_mode': enrollment_mode
            }

            generate_certificate.apply_async(kwargs=kwargs)
            mock_generate_cert.assert_called_with(
                user=self.user,
                course_key=CourseKey.from_string(self.course_key),
                status=CertificateStatuses.downloadable,
                enrollment_mode=enrollment_mode,
                course_grade='',
                generation_mode='batch')