class CertificateDisplayTest(ModuleStoreTestCase): """Tests display of certificates on the student dashboard. """ USERNAME = "******" PASSWORD = "******" DOWNLOAD_URL = "http://www.example.com/certificate.pdf" def setUp(self): super(CertificateDisplayTest, self).setUp() self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD) result = self.client.login(username=self.USERNAME, password=self.PASSWORD) self.assertTrue(result, msg="Could not log in") self.course = CourseFactory() self.course.certificates_display_behavior = "early_with_info" self.update_course(self.course, self.user.username) @ddt.data('verified', 'professional') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate(self, enrollment_mode): self._create_certificate(enrollment_mode) self._check_can_download_certificate() @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate_no_id(self): """ Confirm that if we get a certificate with a no-id-professional mode we still can download our certificate """ self._create_certificate(CourseMode.NO_ID_PROFESSIONAL_MODE) self._check_can_download_certificate_no_id() @ddt.data('verified', 'honor') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_display_download_certificate_button(self, enrollment_mode): """ Tests if CERTIFICATES_HTML_VIEW is True and course has enabled web certificates via cert_html_view_enabled setting and no active certificate configuration available then any of the Download certificate button should not be visible. """ self.course.cert_html_view_enabled = True self.course.save() self.store.update_item(self.course, self.user.id) self._create_certificate(enrollment_mode) self._check_can_not_download_certificate() @ddt.data('verified') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_linked_student_to_web_view_credential(self, enrollment_mode): test_url = get_certificate_url( user_id=self.user.id, course_id=unicode(self.course.id) ) self._create_certificate(enrollment_mode) certificates = [ { 'id': 0, 'name': 'Test Name', 'description': 'Test Description', 'is_active': True, 'signatories': [], 'version': 1 } ] self.course.certificates = {'certificates': certificates} self.course.cert_html_view_enabled = True self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) response = self.client.get(reverse('dashboard')) self.assertContains(response, u'View Test_Certificate') self.assertContains(response, test_url) def _create_certificate(self, enrollment_mode): """Simulate that the user has a generated certificate. """ CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id, mode=enrollment_mode) GeneratedCertificateFactory( user=self.user, course_id=self.course.id, mode=enrollment_mode, download_url=self.DOWNLOAD_URL, status="downloadable", grade=0.98, ) def _check_can_download_certificate(self): response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download Your ID Verified') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_download_certificate_no_id(self): """ Inspects the dashboard to see if a certificate for a non verified course enrollment is present """ response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download') self.assertContains(response, u'(PDF)') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_not_download_certificate(self): """ Make sure response does not have any of the download certificate buttons """ response = self.client.get(reverse('dashboard')) self.assertNotContains(response, u'View Test_Certificate') self.assertNotContains(response, u'Download Your Test_Certificate (PDF)') self.assertNotContains(response, u'Download Test_Certificate (PDF)') self.assertNotContains(response, self.DOWNLOAD_URL)
class CertificateSearchTests(ModuleStoreTestCase, CertificateSupportTestCase): """ Tests for the certificate search end-point used by the support team. """ def setUp(self): """ Create a course """ super(CertificateSearchTests, self).setUp() self.course = CourseFactory() self.course.cert_html_view_enabled = True #course certificate configurations certificates = [{ 'id': 1, 'name': 'Name 1', 'description': 'Description 1', 'course_title': 'course_title_1', 'signatories': [], 'version': 1, 'is_active': True }] self.course.certificates = {'certificates': certificates} self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) @ddt.data( (GlobalStaff, True), (SupportStaffRole, True), (None, False), ) @ddt.unpack def test_access_control(self, role, has_access): # Create a user and log in user = UserFactory(username="******", password="******") success = self.client.login(username="******", password="******") self.assertTrue(success, msg="Could not log in") # Assign the user to the role if role is not None: role().add_users(user) # Retrieve the page response = self._search("foo") if has_access: self.assertContains(response, json.dumps([])) else: self.assertEqual(response.status_code, 403) @ddt.data( (CertificateSupportTestCase.STUDENT_USERNAME, True), (CertificateSupportTestCase.STUDENT_EMAIL, True), ("bar", False), ("*****@*****.**", False), ) @ddt.unpack def test_search(self, query, expect_result): response = self._search(query) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1 if expect_result else 0) def test_results(self): response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual(retrieved_cert["username"], self.STUDENT_USERNAME) self.assertEqual(retrieved_cert["course_key"], unicode(self.CERT_COURSE_KEY)) self.assertEqual(retrieved_cert["created"], self.cert.created_date.isoformat()) self.assertEqual(retrieved_cert["modified"], self.cert.modified_date.isoformat()) self.assertEqual(retrieved_cert["grade"], unicode(self.CERT_GRADE)) self.assertEqual(retrieved_cert["status"], self.CERT_STATUS) self.assertEqual(retrieved_cert["type"], self.CERT_MODE) self.assertEqual(retrieved_cert["download_url"], self.CERT_DOWNLOAD_URL) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_download_link(self): self.cert.course_id = self.course.id # pylint: disable=no-member self.cert.download_url = '' self.cert.save() response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual( retrieved_cert["download_url"], reverse( 'certificates:html_view', kwargs={ "user_id": self.student.id, "course_id": self.course.id } # pylint: disable=no-member )) def _search(self, query): """Execute a search and return the response. """ url = reverse("certificates:search") + "?query=" + query return self.client.get(url)
class CertificateSearchTests(CertificateSupportTestCase): """ Tests for the certificate search end-point used by the support team. """ def setUp(self): """ Create a course """ super().setUp() self.course = CourseFactory( org=self.CERT_COURSE_KEY.org, course=self.CERT_COURSE_KEY.course, run=self.CERT_COURSE_KEY.run, ) self.course.cert_html_view_enabled = True self.course_key = self.course.id # pylint: disable=no-member # Course certificate configurations certificates = [{ 'id': 1, 'name': 'Name 1', 'description': 'Description 1', 'course_title': 'course_title_1', 'signatories': [], 'version': 1, 'is_active': True }] self.course.certificates = {'certificates': certificates} self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) self.course_overview = CourseOverviewFactory( id=self.course_key, cert_html_view_enabled=True, ) @ddt.data( (GlobalStaff, True), (SupportStaffRole, True), (None, False), ) @ddt.unpack def test_access_control(self, role, has_access): # Create a user and log in user = UserFactory(username="******", password="******") success = self.client.login(username="******", password="******") assert success, 'Could not log in' # Assign the user to the role if role is not None: role().add_users(user) # Retrieve the page response = self._search("foo") if has_access: self.assertContains(response, json.dumps([])) else: assert response.status_code == 403 @ddt.data( (CertificateSupportTestCase.STUDENT_USERNAME, True), (CertificateSupportTestCase.STUDENT_EMAIL, True), ("bar", False), ("*****@*****.**", False), ("", False), (CertificateSupportTestCase.STUDENT_USERNAME, False, 'invalid_key'), (CertificateSupportTestCase.STUDENT_USERNAME, False, str(CertificateSupportTestCase.COURSE_NOT_EXIST_KEY)), (CertificateSupportTestCase.STUDENT_USERNAME, True, str(CertificateSupportTestCase.EXISTED_COURSE_KEY_1)), ) @ddt.unpack def test_search(self, user_filter, expect_result, course_filter=None): response = self._search(user_filter, course_filter) if expect_result: assert response.status_code == 200 results = json.loads(response.content.decode('utf-8')) assert len(results) == 1 else: assert response.status_code == 400 def test_search_with_plus_sign(self): """ Test that email address that contains '+' accepted by student support """ self.student.email = "*****@*****.**" self.student.save() response = self._search(self.student.email) assert response.status_code == 200 results = json.loads(response.content.decode('utf-8')) assert len(results) == 1 retrieved_data = results[0] assert retrieved_data['username'] == self.STUDENT_USERNAME def test_results(self): response = self._search(self.STUDENT_USERNAME) assert response.status_code == 200 results = json.loads(response.content.decode('utf-8')) assert len(results) == 1 retrieved_cert = results[0] assert retrieved_cert['username'] == self.STUDENT_USERNAME assert retrieved_cert['course_key'] == str(self.CERT_COURSE_KEY) assert retrieved_cert['created'] == self.cert.created_date.isoformat() assert retrieved_cert['modified'] == self.cert.modified_date.isoformat( ) assert retrieved_cert['grade'] == str(self.CERT_GRADE) assert retrieved_cert['status'] == self.CERT_STATUS assert retrieved_cert['type'] == self.CERT_MODE assert retrieved_cert['download_url'] == self.CERT_DOWNLOAD_URL assert not retrieved_cert['regenerate'] @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_download_link(self): self.cert.course_id = self.course_key self.cert.download_url = '' self.cert.save() response = self._search(self.STUDENT_USERNAME) assert response.status_code == 200 results = json.loads(response.content.decode('utf-8')) assert len(results) == 1 retrieved_cert = results[0] assert retrieved_cert['download_url'] ==\ reverse('certificates:render_cert_by_uuid', kwargs={'certificate_uuid': self.cert.verify_uuid}) assert retrieved_cert['regenerate'] def _search(self, user_filter, course_filter=None): """Execute a search and return the response. """ url = reverse("certificates:search") + "?user=" + user_filter if course_filter: url += '&course_id=' + course_filter return self.client.get(url)
class CertificateDisplayTest(ModuleStoreTestCase): """Tests display of certificates on the student dashboard. """ USERNAME = "******" PASSWORD = "******" DOWNLOAD_URL = "http://www.example.com/certificate.pdf" def setUp(self): super(CertificateDisplayTest, self).setUp() self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD) result = self.client.login(username=self.USERNAME, password=self.PASSWORD) self.assertTrue(result, msg="Could not log in") self.course = CourseFactory() self.course.certificates_display_behavior = "early_with_info" self.update_course(self.course, self.user.username) @ddt.data('verified', 'professional') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate(self, enrollment_mode): self._create_certificate(enrollment_mode) self._check_can_download_certificate() @ddt.data('verified', 'honor') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_display_download_certificate_button(self, enrollment_mode): """ Tests if CERTIFICATES_HTML_VIEW is True and course has enabled web certificates via cert_html_view_enabled setting and no active certificate configuration available then any of the Download certificate button should not be visible. """ self.course.cert_html_view_enabled = True self.course.save() self.store.update_item(self.course, self.user.id) self._create_certificate(enrollment_mode) self._check_can_not_download_certificate() @ddt.data('verified') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_linked_student_to_web_view_credential(self, enrollment_mode): test_url = get_certificate_url(user_id=self.user.id, course_id=unicode(self.course.id), verify_uuid='abcdefg12345678') self._create_certificate(enrollment_mode) certificates = [{ 'id': 0, 'name': 'Test Name', 'description': 'Test Description', 'is_active': True, 'signatories': [], 'version': 1 }] self.course.certificates = {'certificates': certificates} self.course.cert_html_view_enabled = True self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) response = self.client.get(reverse('dashboard')) self.assertContains(response, u'View Test_Certificate') self.assertContains(response, test_url) def _create_certificate(self, enrollment_mode): """Simulate that the user has a generated certificate. """ CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id, mode=enrollment_mode) GeneratedCertificateFactory( user=self.user, course_id=self.course.id, mode=enrollment_mode, download_url=self.DOWNLOAD_URL, status="downloadable", grade=0.98, ) def _check_can_download_certificate(self): response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download Your ID Verified') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_not_download_certificate(self): """ Make sure response does not have any of the download certificate buttons """ response = self.client.get(reverse('dashboard')) self.assertNotContains(response, u'View Test_Certificate') self.assertNotContains(response, u'Download Your Test_Certificate (PDF)') self.assertNotContains(response, u'Download Test_Certificate (PDF)') self.assertNotContains(response, self.DOWNLOAD_URL)
class CertificateSearchTests(CertificateSupportTestCase): """ Tests for the certificate search end-point used by the support team. """ def setUp(self): """ Create a course """ super(CertificateSearchTests, self).setUp() self.course = CourseFactory( org=self.CERT_COURSE_KEY.org, course=self.CERT_COURSE_KEY.course, run=self.CERT_COURSE_KEY.run, ) self.course.cert_html_view_enabled = True #course certificate configurations certificates = [ { 'id': 1, 'name': 'Name 1', 'description': 'Description 1', 'course_title': 'course_title_1', 'signatories': [], 'version': 1, 'is_active': True } ] self.course.certificates = {'certificates': certificates} self.course.save() self.store.update_item(self.course, self.user.id) self.course_overview = CourseOverviewFactory( id=self.course.id, cert_html_view_enabled=True, ) @ddt.data( (GlobalStaff, True), (SupportStaffRole, True), (None, False), ) @ddt.unpack def test_access_control(self, role, has_access): # Create a user and log in user = UserFactory(username="******", password="******") success = self.client.login(username="******", password="******") self.assertTrue(success, msg="Could not log in") # Assign the user to the role if role is not None: role().add_users(user) # Retrieve the page response = self._search("foo") if has_access: self.assertContains(response, json.dumps([])) else: self.assertEqual(response.status_code, 403) @ddt.data( (CertificateSupportTestCase.STUDENT_USERNAME, True), (CertificateSupportTestCase.STUDENT_EMAIL, True), ("bar", False), ("*****@*****.**", False), ("", False), (CertificateSupportTestCase.STUDENT_USERNAME, False, 'invalid_key'), (CertificateSupportTestCase.STUDENT_USERNAME, False, six.text_type(CertificateSupportTestCase.COURSE_NOT_EXIST_KEY)), (CertificateSupportTestCase.STUDENT_USERNAME, True, six.text_type(CertificateSupportTestCase.EXISTED_COURSE_KEY_1)), ) @ddt.unpack def test_search(self, user_filter, expect_result, course_filter=None): response = self._search(user_filter, course_filter) if expect_result: self.assertEqual(response.status_code, 200) results = json.loads(response.content.decode('utf-8')) self.assertEqual(len(results), 1) else: self.assertEqual(response.status_code, 400) def test_search_with_plus_sign(self): """ Test that email address that contains '+' accepted by student support """ self.student.email = "*****@*****.**" self.student.save() response = self._search(self.student.email) self.assertEqual(response.status_code, 200) results = json.loads(response.content.decode('utf-8')) self.assertEqual(len(results), 1) retrieved_data = results[0] self.assertEqual(retrieved_data["username"], self.STUDENT_USERNAME) def test_results(self): response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content.decode('utf-8')) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual(retrieved_cert["username"], self.STUDENT_USERNAME) self.assertEqual(retrieved_cert["course_key"], six.text_type(self.CERT_COURSE_KEY)) self.assertEqual(retrieved_cert["created"], self.cert.created_date.isoformat()) self.assertEqual(retrieved_cert["modified"], self.cert.modified_date.isoformat()) self.assertEqual(retrieved_cert["grade"], six.text_type(self.CERT_GRADE)) self.assertEqual(retrieved_cert["status"], self.CERT_STATUS) self.assertEqual(retrieved_cert["type"], self.CERT_MODE) self.assertEqual(retrieved_cert["download_url"], self.CERT_DOWNLOAD_URL) self.assertFalse(retrieved_cert["regenerate"]) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_download_link(self): self.cert.course_id = self.course.id self.cert.download_url = '' self.cert.save() response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content.decode('utf-8')) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual( retrieved_cert["download_url"], reverse( 'certificates:html_view', kwargs={"user_id": self.student.id, "course_id": self.course.id} ) ) self.assertTrue(retrieved_cert["regenerate"]) def _search(self, user_filter, course_filter=None): """Execute a search and return the response. """ url = reverse("certificates:search") + "?user=" + user_filter if course_filter: url += '&course_id=' + course_filter return self.client.get(url)
class CertificateSearchTests(CertificateSupportTestCase): """ Tests for the certificate search end-point used by the support team. """ def setUp(self): """ Create a course """ super(CertificateSearchTests, self).setUp() self.course = CourseFactory() self.course.cert_html_view_enabled = True #course certificate configurations certificates = [ { 'id': 1, 'name': 'Name 1', 'description': 'Description 1', 'course_title': 'course_title_1', 'signatories': [], 'version': 1, 'is_active': True } ] self.course.certificates = {'certificates': certificates} self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) @ddt.data( (GlobalStaff, True), (SupportStaffRole, True), (None, False), ) @ddt.unpack def test_access_control(self, role, has_access): # Create a user and log in user = UserFactory(username="******", password="******") success = self.client.login(username="******", password="******") self.assertTrue(success, msg="Could not log in") # Assign the user to the role if role is not None: role().add_users(user) # Retrieve the page response = self._search("foo") if has_access: self.assertContains(response, json.dumps([])) else: self.assertEqual(response.status_code, 403) @ddt.data( (CertificateSupportTestCase.STUDENT_USERNAME, True), (CertificateSupportTestCase.STUDENT_EMAIL, True), ("bar", False), ("*****@*****.**", False), ("", False), (CertificateSupportTestCase.STUDENT_USERNAME, False, 'invalid_key'), (CertificateSupportTestCase.STUDENT_USERNAME, False, unicode(CertificateSupportTestCase.COURSE_NOT_EXIST_KEY)), (CertificateSupportTestCase.STUDENT_USERNAME, True, unicode(CertificateSupportTestCase.EXISTED_COURSE_KEY_1)), ) @ddt.unpack def test_search(self, user_filter, expect_result, course_filter=None): response = self._search(user_filter, course_filter) if expect_result: self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) else: self.assertEqual(response.status_code, 400) def test_search_with_plus_sign(self): """ Test that email address that contains '+' accepted by student support """ self.student.email = "*****@*****.**" self.student.save() # pylint: disable=no-member response = self._search(self.student.email) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_data = results[0] self.assertEqual(retrieved_data["username"], self.STUDENT_USERNAME) def test_results(self): response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual(retrieved_cert["username"], self.STUDENT_USERNAME) self.assertEqual(retrieved_cert["course_key"], unicode(self.CERT_COURSE_KEY)) self.assertEqual(retrieved_cert["created"], self.cert.created_date.isoformat()) self.assertEqual(retrieved_cert["modified"], self.cert.modified_date.isoformat()) self.assertEqual(retrieved_cert["grade"], unicode(self.CERT_GRADE)) self.assertEqual(retrieved_cert["status"], self.CERT_STATUS) self.assertEqual(retrieved_cert["type"], self.CERT_MODE) self.assertEqual(retrieved_cert["download_url"], self.CERT_DOWNLOAD_URL) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_download_link(self): self.cert.course_id = self.course.id # pylint: disable=no-member self.cert.download_url = '' self.cert.save() response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual( retrieved_cert["download_url"], reverse( 'certificates:html_view', kwargs={"user_id": self.student.id, "course_id": self.course.id} # pylint: disable=no-member ) ) def _search(self, user_filter, course_filter=None): """Execute a search and return the response. """ url = reverse("certificates:search") + "?user=" + user_filter if course_filter: url += '&course_id=' + course_filter return self.client.get(url)
class CertificateSearchTests(ModuleStoreTestCase, CertificateSupportTestCase): """ Tests for the certificate search end-point used by the support team. """ def setUp(self): """ Create a course """ super(CertificateSearchTests, self).setUp() self.course = CourseFactory() self.course.cert_html_view_enabled = True # course certificate configurations certificates = [ { "id": 1, "name": "Name 1", "description": "Description 1", "course_title": "course_title_1", "signatories": [], "version": 1, "is_active": True, } ] self.course.certificates = {"certificates": certificates} self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) @ddt.data((GlobalStaff, True), (SupportStaffRole, True), (None, False)) @ddt.unpack def test_access_control(self, role, has_access): # Create a user and log in user = UserFactory(username="******", password="******") success = self.client.login(username="******", password="******") self.assertTrue(success, msg="Could not log in") # Assign the user to the role if role is not None: role().add_users(user) # Retrieve the page response = self._search("foo") if has_access: self.assertContains(response, json.dumps([])) else: self.assertEqual(response.status_code, 403) @ddt.data( (CertificateSupportTestCase.STUDENT_USERNAME, True), (CertificateSupportTestCase.STUDENT_EMAIL, True), ("bar", False), ("*****@*****.**", False), ) @ddt.unpack def test_search(self, query, expect_result): response = self._search(query) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1 if expect_result else 0) def test_results(self): response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual(retrieved_cert["username"], self.STUDENT_USERNAME) self.assertEqual(retrieved_cert["course_key"], unicode(self.CERT_COURSE_KEY)) self.assertEqual(retrieved_cert["created"], self.cert.created_date.isoformat()) self.assertEqual(retrieved_cert["modified"], self.cert.modified_date.isoformat()) self.assertEqual(retrieved_cert["grade"], unicode(self.CERT_GRADE)) self.assertEqual(retrieved_cert["status"], self.CERT_STATUS) self.assertEqual(retrieved_cert["type"], self.CERT_MODE) self.assertEqual(retrieved_cert["download_url"], self.CERT_DOWNLOAD_URL) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_download_link(self): self.cert.course_id = self.course.id # pylint: disable=no-member self.cert.download_url = "" self.cert.save() response = self._search(self.STUDENT_USERNAME) self.assertEqual(response.status_code, 200) results = json.loads(response.content) self.assertEqual(len(results), 1) retrieved_cert = results[0] self.assertEqual( retrieved_cert["download_url"], reverse( "certificates:html_view", kwargs={"user_id": self.student.id, "course_id": self.course.id}, # pylint: disable=no-member ), ) def _search(self, query): """Execute a search and return the response. """ url = reverse("certificates:search") + "?query=" + query return self.client.get(url)
class CertificateDisplayTest(ModuleStoreTestCase): """Tests display of certificates on the student dashboard. """ USERNAME = "******" PASSWORD = "******" DOWNLOAD_URL = "http://www.example.com/certificate.pdf" def setUp(self): super(CertificateDisplayTest, self).setUp() self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD) result = self.client.login(username=self.USERNAME, password=self.PASSWORD) self.assertTrue(result, msg="Could not log in") self.course = CourseFactory() self.course.certificates_display_behavior = "early_with_info" self.update_course(self.course, self.user.username) @ddt.data("verified", "professional") @patch.dict("django.conf.settings.FEATURES", {"CERTIFICATES_HTML_VIEW": False}) def test_display_verified_certificate(self, enrollment_mode): self._create_certificate(enrollment_mode) self._check_can_download_certificate() @ddt.data("verified", "honor") @override_settings(CERT_NAME_SHORT="Test_Certificate") @patch.dict("django.conf.settings.FEATURES", {"CERTIFICATES_HTML_VIEW": True}) def test_display_download_certificate_button(self, enrollment_mode): """ Tests if CERTIFICATES_HTML_VIEW is True and course has enabled web certificates via cert_html_view_enabled setting and no active certificate configuration available then any of the Download certificate button should not be visible. """ self.course.cert_html_view_enabled = True self.course.save() self.store.update_item(self.course, self.user.id) self._create_certificate(enrollment_mode) self._check_can_not_download_certificate() @ddt.data("verified") @override_settings(CERT_NAME_SHORT="Test_Certificate") @patch.dict("django.conf.settings.FEATURES", {"CERTIFICATES_HTML_VIEW": True}) def test_linked_student_to_web_view_credential(self, enrollment_mode): test_url = get_certificate_url( user_id=self.user.id, course_id=unicode(self.course.id), verify_uuid="abcdefg12345678" ) self._create_certificate(enrollment_mode) certificates = [ { "id": 0, "name": "Test Name", "description": "Test Description", "is_active": True, "signatories": [], "version": 1, } ] self.course.certificates = {"certificates": certificates} self.course.cert_html_view_enabled = True self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) response = self.client.get(reverse("dashboard")) self.assertContains(response, u"View Test_Certificate") self.assertContains(response, test_url) def _create_certificate(self, enrollment_mode): """Simulate that the user has a generated certificate. """ CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id, mode=enrollment_mode) GeneratedCertificateFactory( user=self.user, course_id=self.course.id, mode=enrollment_mode, download_url=self.DOWNLOAD_URL, status="downloadable", grade=0.98, ) def _check_can_download_certificate(self): response = self.client.get(reverse("dashboard")) self.assertContains(response, u"Download Your ID Verified") self.assertContains(response, self.DOWNLOAD_URL) def _check_can_not_download_certificate(self): """ Make sure response does not have any of the download certificate buttons """ response = self.client.get(reverse("dashboard")) self.assertNotContains(response, u"View Test_Certificate") self.assertNotContains(response, u"Download Your Test_Certificate (PDF)") self.assertNotContains(response, u"Download Test_Certificate (PDF)") self.assertNotContains(response, self.DOWNLOAD_URL)
class CertificateDisplayTest(ModuleStoreTestCase): """Tests display of certificates on the student dashboard. """ USERNAME = "******" PASSWORD = "******" DOWNLOAD_URL = "http://www.example.com/certificate.pdf" def setUp(self): super(CertificateDisplayTest, self).setUp() self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD) result = self.client.login(username=self.USERNAME, password=self.PASSWORD) self.assertTrue(result, msg="Could not log in") self.course = CourseFactory() self.course.certificates_display_behavior = "early_with_info" self.update_course(self.course, self.user.username) @ddt.data('verified', 'professional') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate(self, enrollment_mode): self._create_certificate(enrollment_mode) self._check_can_download_certificate() @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate_no_id(self): """ Confirm that if we get a certificate with a no-id-professional mode we still can download our certificate """ self._create_certificate(CourseMode.NO_ID_PROFESSIONAL_MODE) self._check_can_download_certificate_no_id() @ddt.data('verified', 'honor') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_display_download_certificate_button(self, enrollment_mode): """ Tests if CERTIFICATES_HTML_VIEW is True and course has enabled web certificates via cert_html_view_enabled setting and no active certificate configuration available then any of the Download certificate button should not be visible. """ self.course.cert_html_view_enabled = True self.course.save() self.store.update_item(self.course, self.user.id) self._create_certificate(enrollment_mode) self._check_can_not_download_certificate() @ddt.data('verified') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_linked_student_to_web_view_credential(self, enrollment_mode): cert = self._create_certificate(enrollment_mode) test_url = get_certificate_url(uuid=cert.verify_uuid) certificates = [ { 'id': 0, 'name': 'Test Name', 'description': 'Test Description', 'is_active': True, 'signatories': [], 'version': 1 } ] self.course.certificates = {'certificates': certificates} self.course.cert_html_view_enabled = True self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) response = self.client.get(reverse('dashboard')) self.assertContains(response, u'View Test_Certificate') self.assertContains(response, test_url) def test_post_to_linkedin_invisibility(self): """ Verifies that the post certificate to linked button does not appear by default (when config is not set) """ self._create_certificate('honor') # until we set up the configuration, the LinkedIn action # button should not be visible self._check_linkedin_visibility(False) def test_post_to_linkedin_visibility(self): """ Verifies that the post certificate to linked button appears as expected """ self._create_certificate('honor') config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True ) config.save() # now we should see it self._check_linkedin_visibility(True) @mock.patch("microsite_configuration.microsite.is_request_in_microsite", _fake_is_request_in_microsite) def test_post_to_linkedin_microsite(self): """ Verifies behavior for microsites which disables the post to LinkedIn feature (for now) """ self._create_certificate('honor') config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True ) config.save() # now we should not see it because we are in a microsite self._check_linkedin_visibility(False) def _check_linkedin_visibility(self, is_visible): """ Performs assertions on the Dashboard """ response = self.client.get(reverse('dashboard')) if is_visible: self.assertContains(response, u'Add Certificate to LinkedIn Profile') else: self.assertNotContains(response, u'Add Certificate to LinkedIn Profile') def _create_certificate(self, enrollment_mode): """Simulate that the user has a generated certificate. """ CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id, mode=enrollment_mode) return GeneratedCertificateFactory( user=self.user, course_id=self.course.id, mode=enrollment_mode, download_url=self.DOWNLOAD_URL, status="downloadable", grade=0.98, ) def _check_can_download_certificate(self): response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download Your ID Verified') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_download_certificate_no_id(self): """ Inspects the dashboard to see if a certificate for a non verified course enrollment is present """ response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download') self.assertContains(response, u'(PDF)') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_not_download_certificate(self): """ Make sure response does not have any of the download certificate buttons """ response = self.client.get(reverse('dashboard')) self.assertNotContains(response, u'View Test_Certificate') self.assertNotContains(response, u'Download Your Test_Certificate (PDF)') self.assertNotContains(response, u'Download Test_Certificate (PDF)') self.assertNotContains(response, self.DOWNLOAD_URL)
class CertificateDisplayTest(ModuleStoreTestCase): """Tests display of certificates on the student dashboard. """ USERNAME = "******" PASSWORD = "******" DOWNLOAD_URL = "http://www.example.com/certificate.pdf" def setUp(self): super(CertificateDisplayTest, self).setUp() self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD) result = self.client.login(username=self.USERNAME, password=self.PASSWORD) self.assertTrue(result, msg="Could not log in") self.course = CourseFactory() self.course.certificates_display_behavior = "early_with_info" self.update_course(self.course, self.user.username) @ddt.data('verified', 'professional') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate(self, enrollment_mode): self._create_certificate(enrollment_mode) self._check_can_download_certificate() @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False}) def test_display_verified_certificate_no_id(self): """ Confirm that if we get a certificate with a no-id-professional mode we still can download our certificate """ self._create_certificate(CourseMode.NO_ID_PROFESSIONAL_MODE) self._check_can_download_certificate_no_id() @ddt.data('verified', 'honor') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_display_download_certificate_button(self, enrollment_mode): """ Tests if CERTIFICATES_HTML_VIEW is True and course has enabled web certificates via cert_html_view_enabled setting and no active certificate configuration available then any of the Download certificate button should not be visible. """ self.course.cert_html_view_enabled = True self.course.save() self.store.update_item(self.course, self.user.id) self._create_certificate(enrollment_mode) self._check_can_not_download_certificate() @ddt.data('verified') @override_settings(CERT_NAME_SHORT='Test_Certificate') @patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True}) def test_linked_student_to_web_view_credential(self, enrollment_mode): certificates = [{ 'id': 0, 'name': 'Test Name', 'description': 'Test Description', 'is_active': True, 'signatories': [], 'version': 1 }] self.course.certificates = {'certificates': certificates} self.course.cert_html_view_enabled = True self.course.save() # pylint: disable=no-member self.store.update_item(self.course, self.user.id) cert = self._create_certificate(enrollment_mode) test_url = get_certificate_url(course_id=self.course.id, uuid=cert.verify_uuid) response = self.client.get(reverse('dashboard')) self.assertContains(response, u'View Test_Certificate') self.assertContains(response, test_url) def test_post_to_linkedin_invisibility(self): """ Verifies that the post certificate to linked button does not appear by default (when config is not set) """ self._create_certificate('honor') # until we set up the configuration, the LinkedIn action # button should not be visible self._check_linkedin_visibility(False) def test_post_to_linkedin_visibility(self): """ Verifies that the post certificate to linked button appears as expected """ self._create_certificate('honor') config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True) config.save() # now we should see it self._check_linkedin_visibility(True) @mock.patch("microsite_configuration.microsite.is_request_in_microsite", _fake_is_request_in_microsite) def test_post_to_linkedin_microsite(self): """ Verifies behavior for microsites which disables the post to LinkedIn feature (for now) """ self._create_certificate('honor') config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True) config.save() # now we should not see it because we are in a microsite self._check_linkedin_visibility(False) def _check_linkedin_visibility(self, is_visible): """ Performs assertions on the Dashboard """ response = self.client.get(reverse('dashboard')) if is_visible: self.assertContains(response, u'Add Certificate to LinkedIn Profile') else: self.assertNotContains(response, u'Add Certificate to LinkedIn Profile') def _create_certificate(self, enrollment_mode): """Simulate that the user has a generated certificate. """ CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id, mode=enrollment_mode) return GeneratedCertificateFactory( user=self.user, course_id=self.course.id, mode=enrollment_mode, download_url=self.DOWNLOAD_URL, status="downloadable", grade=0.98, ) def _check_can_download_certificate(self): response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download Your ID Verified') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_download_certificate_no_id(self): """ Inspects the dashboard to see if a certificate for a non verified course enrollment is present """ response = self.client.get(reverse('dashboard')) self.assertContains(response, u'Download') self.assertContains(response, u'(PDF)') self.assertContains(response, self.DOWNLOAD_URL) def _check_can_not_download_certificate(self): """ Make sure response does not have any of the download certificate buttons """ response = self.client.get(reverse('dashboard')) self.assertNotContains(response, u'View Test_Certificate') self.assertNotContains(response, u'Download Your Test_Certificate (PDF)') self.assertNotContains(response, u'Download Test_Certificate (PDF)') self.assertNotContains(response, self.DOWNLOAD_URL)
class TestDiscussionEnabled(CourseTestCase): """ Test discussion enabled flags functionality in a Unit. """ def setUp(self): super().setUp() self.course = self.get_test_course() self.course_usage_key = self.course.id.make_usage_key("course", self.course.id.run) self.non_staff_authed_user_client, _ = self.create_non_staff_authed_user_client() def get_test_course(self): """ Create and return a test course """ self.course = CourseFactory( org="SHIELD", number="SH101", name="Introduction to Avengers", run="2020_T2", modulestore=self.store ) self.chapter = ItemFactory( parent_location=self.course.location, category="chapter", display_name="What is SHIELD?", modulestore=self.store ) self.sequential = ItemFactory( parent_location=self.chapter.location, category="sequential", display_name="HQ", modulestore=self.store ) self.vertical = ItemFactory( parent_location=self.sequential.location, category="vertical", display_name="Triskelion", modulestore=self.store ) self.vertical_1 = ItemFactory( parent_location=self.sequential.location, category="vertical", display_name="Helicarrier", modulestore=self.store ) self.course.save() return self.course def _get_discussion_enabled_status(self, usage_key, client=None): """ Issue a GET request to fetch value of discussion_enabled flag of xblock represented by param:usage_key """ client = client if client is not None else self.client url = reverse_usage_url("xblock_handler", usage_key) resp = client.get(url, HTTP_ACCEPT="application/json") return resp def get_discussion_enabled_status(self, xblock, client=None): """ Issue a GET request to fetch value of discussion_enabled flag of param:xblock's """ resp = self._get_discussion_enabled_status(xblock.location, client=client) content = json.loads(resp.content.decode("utf-8")) return content.get("discussion_enabled", None) def set_discussion_enabled_status(self, xblock, value, client=None): """ Issue a POST request to update value of discussion_enabled flag of param:xblock's """ client = client if client is not None else self.client xblock_location = xblock.location url = reverse_usage_url("xblock_handler", xblock_location) resp = client.post( url, HTTP_ACCEPT="application/json", data=json.dumps({"metadata": {"discussion_enabled": value}}), content_type="application/json", ) return resp def test_discussion_enabled_false_initially(self): """ Tests discussion_enabled flag is False initially for vertical """ self.assertFalse(self.get_discussion_enabled_status(self.vertical)) self.assertFalse(self.get_discussion_enabled_status(self.vertical_1)) def test_discussion_enabled_toggle(self): """ Tests discussion_enabled can be toggled. """ self.set_discussion_enabled_status(self.vertical, True) self.assertTrue(self.get_discussion_enabled_status(self.vertical)) self.assertFalse(self.get_discussion_enabled_status(self.vertical_1)) def test_non_course_author_cannot_get_or_set_discussion_enabled_flag(self): """ Test non course author cannot get/set discussion_enabled flag """ resp = self._get_discussion_enabled_status(self.course_usage_key, self.non_staff_authed_user_client) self.assertEqual(resp.status_code, 403) # Set call to the API with non authorised user should raise a 403 resp = self.set_discussion_enabled_status(self.vertical, True, self.non_staff_authed_user_client) self.assertEqual(resp.status_code, 403)