From 386e05d3b1e3a8e7cbbe6ac59de0839ae8b960c8 Mon Sep 17 00:00:00 2001 From: uzairr Date: Tue, 22 Oct 2019 18:04:36 +0500 Subject: [PATCH] Add warning to the bottom of verification status card on dashboard. Learners are not allowed to make an attempt of the procotored exam if they verify their identity near to proctored exam date.To make them, aware about their expiry date, modification are done to the status card so that user experience will be improved. PROD-769 --- .../student/tests/test_verification_status.py | 2 +- common/djangoapps/student/views/dashboard.py | 1 + lms/djangoapps/courseware/tests/test_views.py | 1 - lms/djangoapps/verify_student/services.py | 3 +++ .../verify_student/tests/test_services.py | 20 +++++++++++++------ .../_dashboard_status_verification.html | 4 ++++ 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/common/djangoapps/student/tests/test_verification_status.py b/common/djangoapps/student/tests/test_verification_status.py index 426b9ffa01..9c2f0f66b8 100644 --- a/common/djangoapps/student/tests/test_verification_status.py +++ b/common/djangoapps/student/tests/test_verification_status.py @@ -299,7 +299,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase): self._assert_course_verification_status(VERIFY_STATUS_APPROVED) response2 = self.client.get(self.dashboard_url) self.assertContains(response2, attempt2.expiration_datetime.strftime("%m/%d/%Y")) - self.assertContains(response2, attempt2.expiration_datetime.strftime("%m/%d/%Y"), count=2) + self.assertContains(response2, attempt2.expiration_datetime.strftime("%m/%d/%Y"), count=3) def _setup_mode_and_enrollment(self, deadline, enrollment_mode): """Create a course mode and enrollment. diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py index 92bb26c3c4..8b8ebcded8 100644 --- a/common/djangoapps/student/views/dashboard.py +++ b/common/djangoapps/student/views/dashboard.py @@ -857,6 +857,7 @@ def student_dashboard(request): 'reverifications': reverifications, 'verification_display': verification_status['should_display'], 'verification_status': verification_status['status'], + 'verification_expiry': verification_status['verification_expiry'], 'verification_status_by_course': verify_status_by_course, 'verification_errors': verification_errors, 'block_courses': block_courses, diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 8a1e699d6f..17cd089b58 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -1291,7 +1291,6 @@ class ProgressPageTests(ProgressPageBaseTests): """ # Create a new course, a user which will not be enrolled in course, admin user for staff access course = CourseFactory.create(default_store=default_store) - not_enrolled_user = UserFactory.create() admin = AdminFactory.create() self.assertTrue(self.client.login(username=admin.username, password='test')) diff --git a/lms/djangoapps/verify_student/services.py b/lms/djangoapps/verify_student/services.py index abf2c6a224..e79fc86a18 100644 --- a/lms/djangoapps/verify_student/services.py +++ b/lms/djangoapps/verify_student/services.py @@ -171,6 +171,7 @@ class IDVerificationService(object): 'status': 'none', 'error': '', 'should_display': True, + 'verification_expiry': '', } # We need to check the user's most recent attempt. @@ -212,6 +213,8 @@ class IDVerificationService(object): elif attempt.status == 'approved': user_status['status'] = 'approved' + if getattr(attempt, 'expiry_date', None): + user_status['verification_expiry'] = attempt.expiry_date.date().strftime("%m/%d/%Y") elif attempt.status in ['submitted', 'approved', 'must_retry']: # user_has_valid_or_pending does include 'approved', but if we are diff --git a/lms/djangoapps/verify_student/tests/test_services.py b/lms/djangoapps/verify_student/tests/test_services.py index 7f80dea0f3..ea8527d848 100644 --- a/lms/djangoapps/verify_student/tests/test_services.py +++ b/lms/djangoapps/verify_student/tests/test_services.py @@ -71,12 +71,14 @@ class TestIDVerificationService(MockS3Mixin, ModuleStoreTestCase): # test for correct status when no error returned user = UserFactory.create() status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'none', 'error': '', 'should_display': True}) + expected_status = {'status': 'none', 'error': '', 'should_display': True, 'verification_expiry': ''} + self.assertDictEqual(status, expected_status) # test for when photo verification has been created SoftwareSecurePhotoVerification.objects.create(user=user, status='approved') status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'approved', 'error': '', 'should_display': True}) + expected_status = {'status': 'approved', 'error': '', 'should_display': True, 'verification_expiry': ''} + self.assertDictEqual(status, expected_status) # create another photo verification for the same user, make sure the denial # is handled properly @@ -84,23 +86,29 @@ class TestIDVerificationService(MockS3Mixin, ModuleStoreTestCase): user=user, status='denied', error_msg='[{"photoIdReasons": ["Not provided"]}]' ) status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'must_reverify', 'error': ['id_image_missing'], 'should_display': True}) + expected_status = { + 'status': 'must_reverify', 'error': ['id_image_missing'], 'should_display': True, 'verification_expiry': '' + } + self.assertDictEqual(status, expected_status) # test for when sso verification has been created SSOVerification.objects.create(user=user, status='approved') status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'approved', 'error': '', 'should_display': False}) + expected_status = {'status': 'approved', 'error': '', 'should_display': False, 'verification_expiry': ''} + self.assertDictEqual(status, expected_status) # create another sso verification for the same user, make sure the denial # is handled properly SSOVerification.objects.create(user=user, status='denied') status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'must_reverify', 'error': '', 'should_display': False}) + expected_status = {'status': 'must_reverify', 'error': '', 'should_display': False, 'verification_expiry': ''} + self.assertDictEqual(status, expected_status) # test for when manual verification has been created ManualVerification.objects.create(user=user, status='approved') status = IDVerificationService.user_status(user) - self.assertDictEqual(status, {'status': 'approved', 'error': '', 'should_display': False}) + expected_status = {'status': 'approved', 'error': '', 'should_display': False, 'verification_expiry': ''} + self.assertDictEqual(status, expected_status) @ddt.unpack @ddt.data( diff --git a/lms/templates/dashboard/_dashboard_status_verification.html b/lms/templates/dashboard/_dashboard_status_verification.html index fa7e09c567..30cb78df13 100644 --- a/lms/templates/dashboard/_dashboard_status_verification.html +++ b/lms/templates/dashboard/_dashboard_status_verification.html @@ -10,6 +10,9 @@ from django.utils.translation import ugettext as _
  • ${_("Current Verification Status: Approved")}

    ${_("Your edX verification has been approved. Your verification is effective for one year after submission.")}

    + %if verification_expiry: +

    ${_("Warning")}: ${_("Your photo verification expires on {verification_expiry}.Approved verification photos are required to earn a certificate and to take a proctored exam. It can take up to 3 days to re-verify, so please re-verify at least a week before any proctored events.").format(verification_expiry=verification_expiry)}

    + %endif
  • %elif verification_status == 'pending':
  • @@ -40,6 +43,7 @@ from django.utils.translation import ugettext as _
  • ${_("Current Verification Status: Expired")}

    ${_("Your verification has expired. To receive a verified certificate, you must submit a new photo of yourself and your government-issued photo ID before the verification deadline for your course.")}

    +

    ${_("Warning")}: ${_("Approved verification photos are required to earn a certificate and to take a proctored exam. It can take up to 3 days to re-verify, so please re-verify at least a week before any proctored events.")}