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} )
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) ) )
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))
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 )
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 )
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))
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 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'
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, } )
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')
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 )
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)
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 )
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))
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, )
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)
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' )
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)
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)
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)
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 } )
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)
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)))
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
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, }
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']
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)
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
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)
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}
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)