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.")}

    ${_("Resubmit Verification")}