Show verification expiration message on learner dashboard and allow them to reverify if expiration is X days away.

ECOM-2979
This commit is contained in:
Tasawer
2016-09-27 15:47:00 +05:00
committed by tasawernawaz
parent 6e23a2ca95
commit 1ac94921c3
9 changed files with 149 additions and 40 deletions

View File

@@ -2,6 +2,7 @@
from datetime import datetime
import urllib
from pytz import UTC
from django.core.urlresolvers import reverse, NoReverseMatch
from oauth2_provider.models import (
AccessToken as dot_access_token,
@@ -11,7 +12,6 @@ from provider.oauth2.models import (
AccessToken as dop_access_token,
RefreshToken as dop_refresh_token
)
from pytz import UTC
import third_party_auth
from lms.djangoapps.verify_student.models import VerificationDeadline, SoftwareSecurePhotoVerification
@@ -22,6 +22,7 @@ from course_modes.models import CourseMode
# we display on the student dashboard.
VERIFY_STATUS_NEED_TO_VERIFY = "verify_need_to_verify"
VERIFY_STATUS_SUBMITTED = "verify_submitted"
VERIFY_STATUS_RESUBMITTED = "re_verify_submitted"
VERIFY_STATUS_APPROVED = "verify_approved"
VERIFY_STATUS_MISSED_DEADLINE = "verify_missed_deadline"
VERIFY_STATUS_NEED_TO_REVERIFY = "verify_need_to_reverify"
@@ -40,6 +41,8 @@ def check_verify_status_by_course(user, course_enrollments):
* VERIFY_STATUS_NEED_TO_VERIFY: The student has not yet submitted photos for verification.
* VERIFY_STATUS_SUBMITTED: The student has submitted photos for verification,
but has have not yet been approved.
* VERIFY_STATUS_RESUBMITTED: The student has re-submitted photos for re-verification while
they still have an active but expiring ID verification
* VERIFY_STATUS_APPROVED: The student has been successfully verified.
* VERIFY_STATUS_MISSED_DEADLINE: The student did not submit photos within the course's deadline.
* VERIFY_STATUS_NEED_TO_REVERIFY: The student has an active verification, but it is
@@ -80,6 +83,11 @@ def check_verify_status_by_course(user, course_enrollments):
user, queryset=verifications
)
# Retrieve expiration_datetime of most recent approved verification
# To avoid another database hit, we re-use the queryset we have already retrieved.
expiration_datetime = SoftwareSecurePhotoVerification.get_expiration_datetime(user, verifications)
verification_expiring_soon = SoftwareSecurePhotoVerification.is_verification_expiring_soon(expiration_datetime)
# Retrieve verification deadlines for the enrolled courses
enrolled_course_keys = [enrollment.course_id for enrollment in course_enrollments]
course_deadlines = VerificationDeadline.deadlines_for_courses(enrolled_course_keys)
@@ -112,9 +120,15 @@ def check_verify_status_by_course(user, course_enrollments):
# Check whether the user was approved or is awaiting approval
if relevant_verification is not None:
if relevant_verification.status == "approved":
status = VERIFY_STATUS_APPROVED
if verification_expiring_soon:
status = VERIFY_STATUS_NEED_TO_REVERIFY
else:
status = VERIFY_STATUS_APPROVED
elif relevant_verification.status == "submitted":
status = VERIFY_STATUS_SUBMITTED
if verification_expiring_soon:
status = VERIFY_STATUS_RESUBMITTED
else:
status = VERIFY_STATUS_SUBMITTED
# If the user didn't submit at all, then tell them they need to verify
# If the deadline has already passed, then tell them they missed it.
@@ -127,11 +141,12 @@ def check_verify_status_by_course(user, course_enrollments):
)
if status is None and not submitted:
if deadline is None or deadline > datetime.now(UTC):
if has_active_or_pending:
# The user has an active verification, but the verification
# is set to expire before the deadline. Tell the student
# to reverify.
status = VERIFY_STATUS_NEED_TO_REVERIFY
if SoftwareSecurePhotoVerification.user_is_verified(user):
if verification_expiring_soon:
# The user has an active verification, but the verification
# is set to expire within "EXPIRING_SOON_WINDOW" days (default is 4 weeks).
# Tell the student to reverify.
status = VERIFY_STATUS_NEED_TO_REVERIFY
else:
status = VERIFY_STATUS_NEED_TO_VERIFY
else:

View File

@@ -8,10 +8,12 @@ from nose.plugins.attrib import attr
from pytz import UTC
from django.core.urlresolvers import reverse
from django.conf import settings
from django.test import override_settings
from student.helpers import (
VERIFY_STATUS_NEED_TO_VERIFY,
VERIFY_STATUS_SUBMITTED,
VERIFY_STATUS_RESUBMITTED,
VERIFY_STATUS_APPROVED,
VERIFY_STATUS_MISSED_DEADLINE,
VERIFY_STATUS_NEED_TO_REVERIFY
@@ -192,6 +194,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
# messaging relating to verification
self._assert_course_verification_status(None)
@override_settings(VERIFY_STUDENT={"DAYS_GOOD_FOR": 5, "EXPIRING_SOON_WINDOW": 10})
def test_verification_will_expire_by_deadline(self):
# Expiration date in the future
self._setup_mode_and_enrollment(self.FUTURE, "verified")
@@ -202,16 +205,36 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
attempt = SoftwareSecurePhotoVerification.objects.create(user=self.user)
attempt.mark_ready()
attempt.submit()
# This attempt will expire tomorrow, before the course deadline
attempt.created_at = attempt.created_at - timedelta(days=364)
attempt.approve()
attempt.save()
# Expect that the "verify now" message is hidden
# (since the user isn't allowed to submit another attempt while
# a verification is active).
# Verify that learner can submit photos if verification is set to expire soon.
self._assert_course_verification_status(VERIFY_STATUS_NEED_TO_REVERIFY)
@override_settings(VERIFY_STUDENT={"DAYS_GOOD_FOR": 5, "EXPIRING_SOON_WINDOW": 10})
def test_reverification_submitted_with_current_approved_verificaiton(self):
# Expiration date in the future
self._setup_mode_and_enrollment(self.FUTURE, "verified")
# Create a verification attempt that is approved but expiring soon
attempt = SoftwareSecurePhotoVerification.objects.create(user=self.user)
attempt.mark_ready()
attempt.submit()
attempt.approve()
attempt.save()
# Verify that learner can submit photos if verification is set to expire soon.
self._assert_course_verification_status(VERIFY_STATUS_NEED_TO_REVERIFY)
# Submit photos for reverification
attempt = SoftwareSecurePhotoVerification.objects.create(user=self.user)
attempt.mark_ready()
attempt.submit()
# Expect that learner has submitted photos for reverfication and his/her
# previous verification is set to expired soon.
self._assert_course_verification_status(VERIFY_STATUS_RESUBMITTED)
def test_verification_occurred_after_deadline(self):
# Expiration date in the past
self._setup_mode_and_enrollment(self.PAST, "verified")
@@ -304,9 +327,10 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
"You still need to verify for this course.",
"Verification not yet complete"
],
VERIFY_STATUS_SUBMITTED: ["Thanks for your patience as we process your request."],
VERIFY_STATUS_APPROVED: ["You have already verified your ID!"],
VERIFY_STATUS_NEED_TO_REVERIFY: ["Your verification will expire soon!"]
VERIFY_STATUS_SUBMITTED: ["You have submitted your verification information."],
VERIFY_STATUS_RESUBMITTED: ["You have submitted your reverification information."],
VERIFY_STATUS_APPROVED: ["You have successfully verified your ID with edX"],
VERIFY_STATUS_NEED_TO_REVERIFY: ["Your current verification will expire soon."]
}
MODE_CLASSES = {
@@ -315,7 +339,8 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
VERIFY_STATUS_SUBMITTED: "verified",
VERIFY_STATUS_APPROVED: "verified",
VERIFY_STATUS_MISSED_DEADLINE: "audit",
VERIFY_STATUS_NEED_TO_REVERIFY: "audit"
VERIFY_STATUS_NEED_TO_REVERIFY: "audit",
VERIFY_STATUS_RESUBMITTED: "audit"
}
def _assert_course_verification_status(self, status):