示例#1
0
    def test_course_ids_with_certs_for_user(self):
        # Create one user with certs and one without
        student_no_certs = UserFactory()
        student_with_certs = UserFactory()
        student_with_certs.profile.allow_certificate = True
        student_with_certs.profile.save()

        # Set up a couple of courses
        course_1 = CourseFactory.create()
        course_2 = CourseFactory.create()

        # Generate certificates
        GeneratedCertificateFactory.create(
            user=student_with_certs,
            course_id=course_1.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )
        GeneratedCertificateFactory.create(
            user=student_with_certs,
            course_id=course_2.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )

        # User with no certs should return an empty set.
        self.assertSetEqual(
            GeneratedCertificate.course_ids_with_certs_for_user(student_no_certs),
            set()
        )
        # User with certs should return a set with the two course_ids
        self.assertSetEqual(
            GeneratedCertificate.course_ids_with_certs_for_user(student_with_certs),
            {course_1.id, course_2.id}
        )
示例#2
0
    def test_refundable_when_certificate_exists(self, cutoff_date):
        """ Assert that enrollment is not refundable once a certificat has been generated."""

        cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(days=1)

        self.assertTrue(self.enrollment.refundable())

        GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified'
        )

        self.assertFalse(self.enrollment.refundable())
        self.assertFalse(
            self.enrollment.refundable(
                user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user)
            )
        )

        # Assert that can_refund overrides this and allows refund
        self.enrollment.can_refund = True
        self.assertTrue(self.enrollment.refundable())
        self.assertTrue(
            self.enrollment.refundable(
                user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user)
            )
        )
示例#3
0
    def test_linked_in_add_to_profile_btn_not_appearing_without_config(self):
        # Without linked-in config don't show Add Certificate to LinkedIn button
        self.client.login(username="******", password="******")

        CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='verified',
            mode_display_name='verified',
            expiration_datetime=datetime.now(pytz.UTC) - timedelta(days=1)
        )

        CourseEnrollment.enroll(self.user, self.course.id, mode='honor')

        self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
        self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
        self.course.display_name = u"Omega"
        self.course = self.update_course(self.course, self.user.id)

        download_url = 'www.edx.org'
        GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url=download_url
        )
        response = self.client.get(reverse('dashboard'))

        self.assertEquals(response.status_code, 200)
        self.assertNotIn('Add Certificate to LinkedIn', response.content)

        response_url = 'http://www.linkedin.com/profile/add?_ed='
        self.assertNotContains(response, escape(response_url))
示例#4
0
 def setUp(self):
     super(EligibleCertificateManagerTest, self).setUp()
     self.user = UserFactory()
     self.eligible_cert = GeneratedCertificateFactory.create(
         status=CertificateStatuses.downloadable,
         user=self.user,
         course_id=self.courses[0].id
     )
     self.ineligible_cert = GeneratedCertificateFactory.create(
         status=CertificateStatuses.audit_passing,
         user=self.user,
         course_id=self.courses[1].id
     )
示例#5
0
 def setUp(self):
     super(CertificateServiceTests, self).setUp()
     self.service = CertificateService()
     self.course = CourseFactory()
     self.user = UserFactory()
     self.user_id = self.user.id
     self.course_id = self.course.id
     GeneratedCertificateFactory.create(
         status=CertificateStatuses.downloadable,
         user=self.user,
         course_id=self.course.id,
         grade=1.0
     )
示例#6
0
    def test_linked_in_add_to_profile_btn_with_certificate(self):
        # If user has a certificate with valid linked-in config then Add Certificate to LinkedIn button
        # should be visible. and it has URL value with valid parameters.
        self.client.login(username="******", password="******")

        LinkedInAddToProfileConfiguration.objects.create(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True
        )

        CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='verified',
            mode_display_name='verified',
            expiration_datetime=datetime.now(pytz.UTC) - timedelta(days=1)
        )

        self.course.certificate_available_date = datetime.now(pytz.UTC) - timedelta(days=1)
        CourseEnrollment.enroll(self.user, self.course.id, mode='honor')

        self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
        self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
        self.course.display_name = u"Omega"
        self.course = self.update_course(self.course, self.user.id)

        download_url = 'www.edx.org'
        GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url=download_url
        )
        response = self.client.get(reverse('dashboard'))

        self.assertEquals(response.status_code, 200)
        self.assertIn('Add Certificate to LinkedIn', response.content)

        expected_url = (
            u'http://www.linkedin.com/profile/add'
            u'?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            u'pfCertificationName={platform}+Honor+Code+Certificate+for+Omega&'
            u'pfCertificationUrl=www.edx.org&'
            u'source=o'
        ).format(platform=quote(settings.PLATFORM_NAME.encode('utf-8')))

        self.assertContains(response, escape(expected_url))
示例#7
0
 def _generate_cert(self, status):
     """ Dry method to generate certificate. """
     return GeneratedCertificateFactory.create(
         user=self.student,
         course_id=self.course.id,
         status=status,
         mode='verified'
     )
示例#8
0
    def setUp(self):
        freezer = freeze_time(self.now)
        freezer.start()
        self.addCleanup(freezer.stop)

        super(CertificatesDetailRestApiTest, self).setUp()

        GeneratedCertificateFactory.create(
            user=self.student,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88"
        )

        self.namespaced_url = 'certificates_api:v0:certificates:detail'
示例#9
0
 def test_cert_status_with_generating(self):
     GeneratedCertificateFactory.create(
         user=self.student,
         course_id=self.course.id,
         status=CertificateStatuses.generating,
         mode='verified'
     )
     self.assertEqual(
         certs_api.certificate_downloadable_status(self.student, self.course.id),
         {
             'is_downloadable': False,
             'is_generating': True,
             'is_unverified': False,
             'download_url': None,
             'uuid': None,
         }
     )
示例#10
0
    def test_generate_user_certificates_with_unverified_cert_status(self):
        """
        Generate user certificate when the certificate is unverified
        will trigger an update to the certificate if the user has since
        verified.
        """
        # generate certificate with unverified status.
        GeneratedCertificateFactory.create(
            user=self.student,
            course_id=self.course.id,
            status=CertificateStatuses.unverified,
            mode='verified'
        )

        with mock_passing_grade():
            with self._mock_queue():
                status = certs_api.generate_user_certificates(self.student, self.course.id)
                self.assertEqual(status, 'generating')
示例#11
0
 def setUp(self):
     super(CertificateInvalidationTest, self).setUp()
     self.course = CourseFactory()
     self.user = UserFactory()
     self.course_id = self.course.id
     self.certificate = GeneratedCertificateFactory.create(
         status=CertificateStatuses.downloadable,
         user=self.user,
         course_id=self.course_id
     )
示例#12
0
    def verify_pdf_certificate(self):
        """
        Verifies the correct URL is returned in the response
        for PDF certificates.
        """
        self.login_and_enroll()

        certificate_url = "http://test_certificate_url"
        GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url=certificate_url,
        )

        response = self.api_response()
        certificate_data = response.data[0]['certificate']
        self.assertEquals(certificate_data['url'], certificate_url)
示例#13
0
    def setUp(self):
        super(EligibleCertificateManagerTest, self).setUp()
        self.user = UserFactory()

        self.course1 = CourseOverviewFactory()
        self.course2 = CourseOverviewFactory(
            id=CourseKey.from_string('{}a'.format(self.course1.id))
        )

        self.eligible_cert = GeneratedCertificateFactory.create(
            status=CertificateStatuses.downloadable,
            user=self.user,
            course_id=self.course1.id
        )
        self.ineligible_cert = GeneratedCertificateFactory.create(
            status=CertificateStatuses.audit_passing,
            user=self.user,
            course_id=self.course2.id
        )
示例#14
0
    def test_course_milestone_collected(self):
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='998', display_name='Test Course')
        pre_requisite_course = CourseFactory.create(org='edx', number='999', display_name='Pre requisite Course')
        # set pre-requisite course
        set_prerequisite_courses(course.id, [unicode(pre_requisite_course.id)])
        # get milestones collected by user before completing the pre-requisite course
        completed_milestones = milestones_achieved_by_user(student, unicode(pre_requisite_course.id))
        self.assertEqual(len(completed_milestones), 0)

        GeneratedCertificateFactory.create(
            user=student,
            course_id=pre_requisite_course.id,
            status=CertificateStatuses.generating,
            mode='verified'
        )
        # get milestones collected by user after user has completed the pre-requisite course
        completed_milestones = milestones_achieved_by_user(student, unicode(pre_requisite_course.id))
        self.assertEqual(len(completed_milestones), 1)
        self.assertEqual(completed_milestones[0]['namespace'], unicode(pre_requisite_course.id))
示例#15
0
    def setUpClass(cls):
        cls.freezer = freeze_time(cls.now)
        cls.freezer.start()

        super(CertificateGetTests, cls).setUpClass()
        cls.student = UserFactory()
        cls.student_no_cert = UserFactory()
        cls.uuid = uuid.uuid4().hex
        cls.web_cert_course = CourseFactory.create(
            org='edx',
            number='verified_1',
            display_name='Verified Course 1',
            cert_html_view_enabled=True
        )
        cls.pdf_cert_course = CourseFactory.create(
            org='edx',
            number='verified_2',
            display_name='Verified Course 2',
            cert_html_view_enabled=False
        )
        # certificate for the first course
        GeneratedCertificateFactory.create(
            user=cls.student,
            course_id=cls.web_cert_course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88",
            verify_uuid=cls.uuid,
        )
        # certificate for the second course
        GeneratedCertificateFactory.create(
            user=cls.student,
            course_id=cls.pdf_cert_course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            download_url='www.gmail.com',
            grade="0.99",
            verify_uuid=cls.uuid,
        )
示例#16
0
    def test_certificate_info_for_user_when_grade_changes(self, allow_certificate, whitelisted, grade, output):
        """
        Verify that certificate_info_for_user works as expect in scenario when grading of problems
        changes after certificates already generated. In such scenario `Certificate delivered` should not depend
        on student's eligibility to get certificates since in above scenario eligibility can change over period
        of time.
        """
        student = UserFactory()
        student.profile.allow_certificate = allow_certificate
        student.profile.save()

        certificate1 = GeneratedCertificateFactory.create(
            user=student,
            course_id=self.instructor_paced_course.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )

        certificate2 = GeneratedCertificateFactory.create(
            user=student,
            course_id=self.self_paced_course.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )

        # for instructor paced course
        certificate_info = certificate_info_for_user(
            student, self.instructor_paced_course.id, grade,
            whitelisted, certificate1
        )
        self.assertEqual(certificate_info, output)

        # for self paced course
        certificate_info = certificate_info_for_user(
            student, self.self_paced_course.id, grade,
            whitelisted, certificate2
        )
        self.assertEqual(certificate_info, output)
示例#17
0
    def setUp(self):
        freezer = freeze_time(self.now)
        freezer.start()
        self.addCleanup(freezer.stop)

        super(CertificatesRestApiTest, self).setUp()

        self.student = UserFactory.create(password=USER_PASSWORD)
        self.student_no_cert = UserFactory.create(password=USER_PASSWORD)
        self.staff_user = UserFactory.create(password=USER_PASSWORD, is_staff=True)

        GeneratedCertificateFactory.create(
            user=self.student,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88"
        )

        self.namespaced_url = 'certificates_api:v0:certificates:detail'

        # create a configuration for django-oauth-toolkit (DOT)
        dot_app_user = UserFactory.create(password=USER_PASSWORD)
        dot_app = dot_models.Application.objects.create(
            name='test app',
            user=dot_app_user,
            client_type='confidential',
            authorization_grant_type='authorization-code',
            redirect_uris='http://localhost:8079/complete/edxorg/'
        )
        self.dot_access_token = dot_models.AccessToken.objects.create(
            user=self.student,
            application=dot_app,
            expires=datetime.utcnow() + timedelta(weeks=1),
            scope='read write',
            token='16MGyP3OaQYHmpT1lK7Q6MMNAZsjwF'
        )
示例#18
0
 def test_badge_callback(self, handler):
     student = UserFactory()
     course = CourseFactory.create(org='edx', number='998', display_name='Test Course', issue_badges=True)
     CourseCompleteImageConfigurationFactory()
     CourseEnrollmentFactory(user=student, course_id=course.location.course_key, mode='honor')
     cert = GeneratedCertificateFactory.create(
         user=student,
         course_id=course.id,
         status=CertificateStatuses.generating,
         mode='verified'
     )
     cert.status = CertificateStatuses.downloadable
     cert.save()
     self.assertTrue(handler.return_value.award.called)
示例#19
0
    def test_certificate_info_for_user_when_grade_changes(self, allow_certificate, whitelisted, grade, output):
        """
        Verify that certificate_info_for_user works as expect in scenario when grading of problems
        changes after certificates already generated. In such scenario `Certificate delivered` should not depend
        on student's eligibility to get certificates since in above scenario eligibility can change over period
        of time.
        """
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='verified', display_name='Verified Course')
        student.profile.allow_certificate = allow_certificate
        student.profile.save()

        certificate = GeneratedCertificateFactory.create(
            user=student,
            course_id=course.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )
        certificate_info = certificate_info_for_user(student, grade, whitelisted, certificate)
        self.assertEqual(certificate_info, output)
示例#20
0
    def setUp(self):
        super(AwardCourseCertificatesTestCase, self).setUp()

        self.course = CourseOverviewFactory.create(
            self_paced=True  # Any option to allow the certificate to be viewable for the course
        )
        self.student = UserFactory.create(username='******')
        # Instantiate the Certificate first so that the config doesn't execute issuance
        self.certificate = GeneratedCertificateFactory.create(
            user=self.student,
            mode='verified',
            course_id=self.course.id,
            status='downloadable'
        )

        self.create_credentials_config()
        self.site = SiteFactory()

        ClientFactory.create(name='credentials')
        UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
示例#21
0
    def verify_downloadable_pdf_cert(self):
        """
        Verifies certificate_downloadable_status returns the
        correct response for PDF certificates.
        """
        cert = GeneratedCertificateFactory.create(
            user=self.student,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
        )

        self.assertEqual(
            certs_api.certificate_downloadable_status(self.student, self.course.id),
            {
                'is_downloadable': True,
                'is_generating': False,
                'is_unverified': False,
                'download_url': 'www.google.com',
                'uuid': cert.verify_uuid
            }
        )
示例#22
0
    def test_query_counts(self):
        # Test student with no certificates
        student_no_cert = UserFactory.create(password=self.user_password)
        with self.assertNumQueries(22):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=student_no_cert,
                requested_user=student_no_cert,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 0)

        # Test student with 1 certificate
        with self.assertNumQueries(17):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=self.student,
                requested_user=self.student,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 1)

        # Test student with 2 certificates
        student_2_certs = UserFactory.create(password=self.user_password)
        course = CourseFactory.create(
            org='edx',
            number='test',
            display_name='Test Course',
            self_paced=True,
        )
        CourseOverviewFactory.create(
            id=course.id,
            display_org_with_default='edx',
            display_name='Test Course',
            cert_html_view_enabled=True,
            self_paced=True,
        )
        GeneratedCertificateFactory.create(
            user=student_2_certs,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88",
        )
        GeneratedCertificateFactory.create(
            user=student_2_certs,
            course_id=course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88",
        )
        with self.assertNumQueries(17):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=student_2_certs,
                requested_user=student_2_certs,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 2)
示例#23
0
    def _multisetup(self):
        """
        setup certs across two course runs
        """
        course_run = CourseFactory()
        course_run_key = course_run.id
        course_run2 = CourseFactory()
        course_run_key2 = course_run2.id

        user = UserFactory()
        CourseEnrollmentFactory(
            user=user,
            course_id=course_run_key,
            is_active=True,
            mode=CourseMode.VERIFIED,
        )
        GeneratedCertificateFactory(user=user,
                                    course_id=course_run_key,
                                    mode=GeneratedCertificate.MODES.verified,
                                    status=CertificateStatuses.unverified)

        user1 = UserFactory()
        CourseEnrollmentFactory(
            user=user1,
            course_id=course_run_key,
            is_active=True,
            mode=CourseMode.VERIFIED,
        )
        GeneratedCertificateFactory(user=user1,
                                    course_id=course_run_key,
                                    mode=GeneratedCertificate.MODES.verified,
                                    status=CertificateStatuses.unverified)

        user2 = UserFactory()
        CourseEnrollmentFactory(
            user=user2,
            course_id=course_run_key2,
            is_active=True,
            mode=CourseMode.VERIFIED,
        )
        GeneratedCertificateFactory(user=user2,
                                    course_id=course_run_key2,
                                    mode=GeneratedCertificate.MODES.verified,
                                    status=CertificateStatuses.unverified)

        user_verified = UserFactory()
        CourseEnrollmentFactory(
            user=user_verified,
            course_id=course_run_key,
            is_active=True,
            mode=CourseMode.VERIFIED,
        )
        GeneratedCertificateFactory(user=user_verified,
                                    course_id=course_run_key,
                                    mode=GeneratedCertificate.MODES.verified,
                                    status=CertificateStatuses.downloadable)

        user_failing = UserFactory()
        CourseEnrollmentFactory(
            user=user_failing,
            course_id=course_run_key2,
            is_active=True,
            mode=CourseMode.VERIFIED,
        )
        GeneratedCertificateFactory(user=user_failing,
                                    course_id=course_run_key2,
                                    mode=GeneratedCertificate.MODES.verified,
                                    status=CertificateStatuses.notpassing)
        return (course_run_key, course_run_key2)
    def test_linked_in_add_to_profile_btn_with_certificate(self):
        # If user has a certificate with valid linked-in config then Add Certificate to LinkedIn button
        # should be visible. and it has URL value with valid parameters.
        self.client.login(username="******", password="******")

        linkedin_config = LinkedInAddToProfileConfiguration.objects.create(
            company_identifier='1337', enabled=True)
        CourseModeFactory.create(course_id=self.course.id,
                                 mode_slug='verified',
                                 mode_display_name='verified',
                                 expiration_datetime=datetime.now(pytz.UTC) -
                                 timedelta(days=1))
        CourseEnrollment.enroll(self.user, self.course.id, mode='honor')
        self.course.certificate_available_date = datetime.now(
            pytz.UTC) - timedelta(days=1)
        self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
        self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
        self.course.display_name = 'Omega'
        self.course = self.update_course(self.course, self.user.id)

        cert = GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url='https://www.edx.org')
        response = self.client.get(reverse('dashboard'))

        assert response.status_code == 200
        self.assertContains(response, 'Add Certificate to LinkedIn')

        # We can switch to this and the commented out assertContains once edx-platform reaches Python 3.8
        # expected_url = (
        #     'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&'
        #     'name={platform}+Honor+Code+Certificate+for+Omega&certUrl={cert_url}&'
        #     'organizationId={company_identifier}'
        # ).format(
        #     platform=quote(settings.PLATFORM_NAME.encode('utf-8')),
        #     cert_url=quote(cert.download_url, safe=''),
        #     company_identifier=linkedin_config.company_identifier,
        # )

        # self.assertContains(response, escape(expected_url))

        # These can be removed (in favor of the above) once we are on Python 3.8. Fails in 3.5 because of dict ordering
        self.assertContains(
            response,
            escape(
                'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME'
            ))
        self.assertContains(
            response,
            escape('&name={platform}+Honor+Code+Certificate+for+Omega'.format(
                platform=quote(settings.PLATFORM_NAME.encode('utf-8')))))
        self.assertContains(
            response,
            escape('&certUrl={cert_url}'.format(
                cert_url=quote(cert.download_url, safe=''))))
        self.assertContains(
            response,
            escape('&organizationId={company_identifier}'.format(
                company_identifier=linkedin_config.company_identifier)))
示例#25
0
    def test_enrolled_course_metadata(self, logged_in, enrollment_mode):
        check_public_access = mock.Mock()
        check_public_access.return_value = ACCESS_DENIED
        with mock.patch('lms.djangoapps.courseware.access_utils.check_public_access', check_public_access):
            if not logged_in:
                self.client.logout()
            if enrollment_mode == 'verified':
                cert = GeneratedCertificateFactory.create(
                    user=self.user,
                    course_id=self.course.id,
                    status='downloadable',
                    mode='verified',
                )
            if enrollment_mode:
                CourseEnrollment.enroll(self.user, self.course.id, enrollment_mode)

            response = self.client.get(self.url)
            assert response.status_code == 200

            enrollment = response.data['enrollment']
            assert enrollment_mode == enrollment['mode']
            assert enrollment['is_active']

            assert not response.data['user_has_passing_grade']
            assert response.data['celebrations']['first_section']
            assert not response.data['celebrations']['weekly_goal']

            # This import errors in cms if it is imported at the top level
            from lms.djangoapps.course_goals.api import get_course_goal
            selected_goal = get_course_goal(self.user, self.course.id)
            if selected_goal:
                assert response.data['course_goals']['selected_goal'] == {
                    'days_per_week': selected_goal.days_per_week,
                    'subscribed_to_reminders': selected_goal.subscribed_to_reminders,
                }

            if enrollment_mode == 'audit':
                assert response.data['verify_identity_url'] is None
                assert response.data['verification_status'] == 'none'
                assert response.data['linkedin_add_to_profile_url'] is None
            else:
                assert response.data['certificate_data']['cert_status'] == 'earned_but_not_available'
                expected_verify_identity_url = IDVerificationService.get_verify_location(
                    course_id=self.course.id
                )
                # The response contains an absolute URL so this is only checking the path of the final
                assert expected_verify_identity_url in response.data['verify_identity_url']
                assert response.data['verification_status'] == 'none'

                request = RequestFactory().request()
                cert_url = get_certificate_url(course_id=self.course.id, uuid=cert.verify_uuid)
                linkedin_url_params = {
                    'name': '{platform_name} Verified Certificate for {course_name}'.format(
                        platform_name=settings.PLATFORM_NAME, course_name=self.course.display_name,
                    ),
                    'certUrl': request.build_absolute_uri(cert_url),
                    # default value from the LinkedInAddToProfileConfigurationFactory company_identifier
                    'organizationId': 1337,
                    'certId': cert.verify_uuid,
                    'issueYear': cert.created_date.year,
                    'issueMonth': cert.created_date.month,
                }
                expected_linkedin_url = (
                    'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&{params}'.format(
                        params=urlencode(linkedin_url_params)
                    )
                )
                assert response.data['linkedin_add_to_profile_url'] == expected_linkedin_url
示例#26
0
    def setUp(self):
        super().setUp()
        self.user = UserFactory.create()
        self.user2 = UserFactory.create()

        with freeze_time(datetime(2017, 1, 1)):
            self.cert1 = GeneratedCertificateFactory(
                user=self.user, course_id='course-v1:edX+Test+1')
        with freeze_time(datetime(2017, 2, 1, 0)):
            self.cert2 = GeneratedCertificateFactory(
                user=self.user, course_id='course-v1:edX+Test+2')
        with freeze_time(datetime(2017, 3, 1)):
            self.cert3 = GeneratedCertificateFactory(
                user=self.user, course_id='course-v1:testX+Test+3')
        with freeze_time(datetime(2017, 2, 1, 5)):
            self.cert4 = GeneratedCertificateFactory(
                user=self.user2,
                course_id='course-v1:edX+Test+4',
                status=CertificateStatuses.downloadable)
        print(('self.cert1.modified_date', self.cert1.modified_date))

        # No factory for these
        with freeze_time(datetime(2017, 1, 1)):
            self.grade1 = PersistentCourseGrade.objects.create(
                user_id=self.user.id,
                course_id='course-v1:edX+Test+1',
                percent_grade=1)
        with freeze_time(datetime(2017, 2, 1)):
            self.grade2 = PersistentCourseGrade.objects.create(
                user_id=self.user.id,
                course_id='course-v1:edX+Test+2',
                percent_grade=1)
        with freeze_time(datetime(2017, 3, 1)):
            self.grade3 = PersistentCourseGrade.objects.create(
                user_id=self.user.id,
                course_id='course-v1:testX+Test+3',
                percent_grade=1)
        with freeze_time(datetime(2017, 2, 1, 5)):
            self.grade4 = PersistentCourseGrade.objects.create(
                user_id=self.user2.id,
                course_id='course-v1:edX+Test+4',
                percent_grade=1)
        print(('self.grade1.modified', self.grade1.modified))

        self.options = {
            'args_from_database': False,
            'auto': False,
            'courses': None,
            'delay': 0,
            'dry_run': False,
            'end_date': None,
            'force_color': False,
            'no_color': False,
            'notify_programs': False,
            'page_size': 100,
            'pythonpath': None,
            'settings': None,
            'site': None,
            'start_date': None,
            'traceback': False,
            'user_ids': None,
            'verbose': False,
            'verbosity': 1,
            'skip_checks': True,
        }
示例#27
0
    def test_course_metadata(self, logged_in, enrollment_mode,
                             enable_anonymous,
                             is_microfrontend_enabled_for_user):
        is_microfrontend_enabled_for_user.return_value = True
        check_public_access = mock.Mock()
        check_public_access.return_value = enable_anonymous
        with mock.patch(
                'lms.djangoapps.courseware.access_utils.check_public_access',
                check_public_access):
            if not logged_in:
                self.client.logout()
            if enrollment_mode:
                CourseEnrollment.enroll(self.user, self.course.id,
                                        enrollment_mode)
            if enrollment_mode == 'verified':
                cert = GeneratedCertificateFactory.create(
                    user=self.user,
                    course_id=self.course.id,
                    status='downloadable',
                    mode='verified',
                )

            response = self.client.get(self.url)
            assert response.status_code == 200
            if enrollment_mode:
                enrollment = response.data['enrollment']
                assert enrollment_mode == enrollment['mode']
                assert enrollment['is_active']
                assert len(response.data['tabs']) == 6
                found = False
                for tab in response.data['tabs']:
                    if tab['type'] == 'external_link':
                        assert tab[
                            'url'] != 'http://hidden.com', "Hidden tab is not hidden"
                        if tab['url'] == 'http://zombo.com':
                            found = True
                assert found, 'external link not in course tabs'

                assert not response.data['user_has_passing_grade']
                if enrollment_mode == 'audit':
                    assert response.data['verify_identity_url'] is None
                    assert response.data['verification_status'] == 'none'  # lint-amnesty, pylint: disable=literal-comparison
                    assert response.data['linkedin_add_to_profile_url'] is None
                else:
                    assert response.data['certificate_data'][
                        'cert_status'] == 'earned_but_not_available'
                    expected_verify_identity_url = IDVerificationService.get_verify_location(
                        course_id=self.course.id)
                    # The response contains an absolute URL so this is only checking the path of the final
                    assert expected_verify_identity_url in response.data[
                        'verify_identity_url']
                    assert response.data['verification_status'] == 'none'  # lint-amnesty, pylint: disable=literal-comparison

                    request = RequestFactory().request()
                    cert_url = get_certificate_url(course_id=self.course.id,
                                                   uuid=cert.verify_uuid)
                    linkedin_url_params = {
                        'name':
                        '{platform_name} Verified Certificate for {course_name}'
                        .format(
                            platform_name=settings.PLATFORM_NAME,
                            course_name=self.course.display_name,
                        ),
                        'certUrl':
                        request.build_absolute_uri(cert_url),
                        # default value from the LinkedInAddToProfileConfigurationFactory company_identifier
                        'organizationId':
                        1337,
                        'certId':
                        cert.verify_uuid,
                        'issueYear':
                        cert.created_date.year,
                        'issueMonth':
                        cert.created_date.month,
                    }
                    expected_linkedin_url = (
                        'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&{params}'
                        .format(params=urlencode(linkedin_url_params)))
                    assert response.data[
                        'linkedin_add_to_profile_url'] == expected_linkedin_url
            elif enable_anonymous and not logged_in:
                # multiple checks use this handler
                check_public_access.assert_called()
                assert response.data['enrollment']['mode'] is None
                assert response.data['can_load_courseware']['has_access']
            else:
                assert not response.data['can_load_courseware']['has_access']
示例#28
0
    def test_cert_changed(self, mock_send_grade_if_interesting):
        user = UserFactory()

        self.assertFalse(mock_send_grade_if_interesting.called)
        GeneratedCertificateFactory(user=user)
        self.assertTrue(mock_send_grade_if_interesting.called)
示例#29
0
    def test_cert_changed(self, mock_send_grade_if_interesting):
        user = UserFactory()

        assert not mock_send_grade_if_interesting.called
        GeneratedCertificateFactory(user=user)
        assert mock_send_grade_if_interesting.called
示例#30
0
    def test_query_counts(self):
        # Test student with no certificates
        student_no_cert = UserFactory.create(password=self.user_password)
        with self.assertNumQueries(21):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=student_no_cert,
                requested_user=student_no_cert,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 0)

        # Test student with 1 certificate
        with self.assertNumQueries(14):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=self.student,
                requested_user=self.student,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 1)

        # Test student with 2 certificates
        student_2_certs = UserFactory.create(password=self.user_password)
        course = CourseFactory.create(
            org='edx',
            number='test',
            display_name='Test Course',
            self_paced=True,
        )
        CourseOverviewFactory.create(
            id=course.id,
            display_org_with_default='edx',
            display_name='Test Course',
            cert_html_view_enabled=True,
            self_paced=True,
        )
        GeneratedCertificateFactory.create(
            user=student_2_certs,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88",
        )
        GeneratedCertificateFactory.create(
            user=student_2_certs,
            course_id=course.id,
            status=CertificateStatuses.downloadable,
            mode='verified',
            download_url='www.google.com',
            grade="0.88",
        )
        with self.assertNumQueries(14):
            resp = self.get_response(
                AuthType.jwt,
                requesting_user=student_2_certs,
                requested_user=student_2_certs,
            )
            self.assertEqual(resp.status_code, status.HTTP_200_OK)
            self.assertEqual(len(resp.data), 2)
示例#31
0
    def test_cert_info(self):
        user = UserFactory.create()
        survey_url = "http://a_survey.com"
        course = CourseOverviewFactory.create(
            end_of_course_survey_url=survey_url,
            certificates_display_behavior='end',
        )
        cert = GeneratedCertificateFactory.create(
            user=user,
            course_id=course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url='http://s3.edx/cert'
        )

        assert _cert_info(user, course, None) ==\
               {'status': 'processing', 'show_survey_button': False, 'can_unenroll': True}

        cert_status = {'status': 'unavailable', 'mode': 'honor', 'uuid': None}
        assert _cert_info(user, course, cert_status) == {'status': 'processing', 'show_survey_button': False,
                                                         'mode': 'honor', 'linked_in_url': None, 'can_unenroll': True}

        cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor', 'uuid': None}
        with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade:
            patch_persisted_grade.return_value = Mock(percent=1.0)
            assert _cert_info(user, course, cert_status) == {'status': 'generating', 'show_survey_button': True,
                                                             'survey_url': survey_url, 'grade': '1.0', 'mode': 'honor',
                                                             'linked_in_url': None, 'can_unenroll': False}

        cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor', 'uuid': None}
        assert _cert_info(user, course, cert_status) == {'status': 'generating', 'show_survey_button': True,
                                                         'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor',
                                                         'linked_in_url': None, 'can_unenroll': False}

        cert_status = {
            'status': 'downloadable',
            'grade': '0.67',
            'download_url': cert.download_url,
            'mode': 'honor',
            'uuid': 'fakeuuidbutitsfine',
        }
        assert _cert_info(user, course, cert_status) == {'status': 'downloadable', 'download_url': cert.download_url,
                                                         'show_survey_button': True, 'survey_url': survey_url,
                                                         'grade': '0.67', 'mode': 'honor', 'linked_in_url': None,
                                                         'can_unenroll': False}

        cert_status = {
            'status': 'notpassing', 'grade': '0.67',
            'download_url': cert.download_url,
            'mode': 'honor',
            'uuid': 'fakeuuidbutitsfine',
        }
        assert _cert_info(user, course, cert_status) == {'status': 'notpassing', 'show_survey_button': True,
                                                         'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor',
                                                         'linked_in_url': None, 'can_unenroll': True}

        # Test a course that doesn't have a survey specified
        course2 = Mock(end_of_course_survey_url=None, id=CourseLocator(org="a", course="b", run="c"))
        cert_status = {
            'status': 'notpassing', 'grade': '0.67',
            'download_url': cert.download_url, 'mode': 'honor', 'uuid': 'fakeuuidbutitsfine'
        }
        assert _cert_info(user, course2, cert_status) == {'status': 'notpassing', 'show_survey_button': False,
                                                          'grade': '0.67', 'mode': 'honor', 'linked_in_url': None,
                                                          'can_unenroll': True}

        # test when the display is unavailable or notpassing, we get the correct results out
        course2.certificates_display_behavior = 'early_no_info'
        cert_status = {'status': 'unavailable', 'mode': 'honor', 'uuid': None}
        assert _cert_info(user, course2, cert_status) == {'status': 'processing', 'show_survey_button': False,
                                                          'can_unenroll': True}

        cert_status = {
            'status': 'notpassing', 'grade': '0.67',
            'download_url': cert.download_url,
            'mode': 'honor',
            'uuid': 'fakeuuidbutitsfine'
        }
        assert _cert_info(user, course2, cert_status) == {'status': 'processing', 'show_survey_button': False,
                                                          'can_unenroll': True}
示例#32
0
 def _generate_cert(self, status):
     """ Dry method to generate certificate. """
     return GeneratedCertificateFactory.create(user=self.student,
                                               course_id=self.course.id,
                                               status=status,
                                               mode='verified')
 def test_cert_already_generated(self):
     goal = self.make_valid_goal()
     GeneratedCertificateFactory(user=goal.user,
                                 course_id=goal.course_key,
                                 status=CertificateStatuses.downloadable)
     self.call_command(expect_sent=False)