Separate verification deadline from upgrade deadline

* Add verification deadline model.
* Populate verification deadlines from course modes table.
* Update student dashboard to use verification deadlines.
* Update pay-and-verify view to use verification deadlines.
* Simplify Django admin for course modes and add validation.
* Add verification deadline to Django admin for course modes.
* Add UI for when the upgrade deadline is missed in the pay-and-verify flow.
This commit is contained in:
Will Daly
2015-07-09 13:18:36 -07:00
parent 80cf4d6ecb
commit 25fa2ffc2d
15 changed files with 1181 additions and 195 deletions

View File

@@ -6,7 +6,7 @@ from pytz import UTC
from django.core.urlresolvers import reverse, NoReverseMatch
import third_party_auth
from verify_student.models import SoftwareSecurePhotoVerification # pylint: disable=import-error
from verify_student.models import VerificationDeadline, SoftwareSecurePhotoVerification # pylint: disable=import-error
from course_modes.models import CourseMode
@@ -19,7 +19,7 @@ VERIFY_STATUS_MISSED_DEADLINE = "verify_missed_deadline"
VERIFY_STATUS_NEED_TO_REVERIFY = "verify_need_to_reverify"
def check_verify_status_by_course(user, course_enrollments, all_course_modes):
def check_verify_status_by_course(user, course_enrollments):
"""
Determine the per-course verification statuses for a given user.
@@ -44,8 +44,6 @@ def check_verify_status_by_course(user, course_enrollments, all_course_modes):
Arguments:
user (User): The currently logged-in user.
course_enrollments (list[CourseEnrollment]): The courses the user is enrolled in.
all_course_modes (list): List of all course modes for the student's enrolled courses,
including modes that have expired.
Returns:
dict: Mapping of course keys verification status dictionaries.
@@ -69,24 +67,21 @@ def check_verify_status_by_course(user, course_enrollments, all_course_modes):
user, queryset=verifications
)
# 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)
recent_verification_datetime = None
for enrollment in course_enrollments:
# Get the verified mode (if any) for this course
# We pass in the course modes we have already loaded to avoid
# another database hit, as well as to ensure that expired
# course modes are included in the search.
verified_mode = CourseMode.verified_mode_for_course(
enrollment.course_id,
modes=all_course_modes[enrollment.course_id]
)
# If the user hasn't enrolled as verified, then the course
# won't display state related to its verification status.
if enrollment.mode in CourseMode.VERIFIED_MODES:
# If no verified mode has ever been offered, or the user hasn't enrolled
# as verified, then the course won't display state related to its
# verification status.
if verified_mode is not None and enrollment.mode in CourseMode.VERIFIED_MODES:
deadline = verified_mode.expiration_datetime
# Retrieve the verification deadline associated with the course.
# This could be None if the course doesn't have a deadline.
deadline = course_deadlines.get(enrollment.course_id)
relevant_verification = SoftwareSecurePhotoVerification.verification_for_datetime(deadline, verifications)

View File

@@ -20,7 +20,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from student.tests.factories import UserFactory, CourseEnrollmentFactory
from course_modes.tests.factories import CourseModeFactory
from verify_student.models import SoftwareSecurePhotoVerification # pylint: disable=import-error
from verify_student.models import VerificationDeadline, SoftwareSecurePhotoVerification # pylint: disable=import-error
from util.testing import UrlResetMixin
@@ -61,9 +61,11 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
mode="verified"
)
# The default course has no verified mode,
# so no verification status should be displayed
self._assert_course_verification_status(None)
# Continue to show the student as needing to verify.
# The student is enrolled as verified, so we might as well let them
# complete verification. We'd need to change their enrollment mode
# anyway to ensure that the student is issued the correct kind of certificate.
self._assert_course_verification_status(VERIFY_STATUS_NEED_TO_VERIFY)
def test_need_to_verify_no_expiration(self):
self._setup_mode_and_enrollment(None, "verified")
@@ -285,6 +287,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
user=self.user,
mode=enrollment_mode
)
VerificationDeadline.set_deadline(self.course.id, deadline)
BANNER_ALT_MESSAGES = {
None: "Honor",

View File

@@ -533,7 +533,7 @@ def dashboard(request):
# Retrieve the course modes for each course
enrolled_course_ids = [enrollment.course_id for enrollment in course_enrollments]
all_course_modes, unexpired_course_modes = CourseMode.all_and_unexpired_modes_for_courses(enrolled_course_ids)
__, unexpired_course_modes = CourseMode.all_and_unexpired_modes_for_courses(enrolled_course_ids)
course_modes_by_course = {
course_id: {
mode.slug: mode
@@ -596,11 +596,7 @@ def dashboard(request):
#
# If a course is not included in this dictionary,
# there is no verification messaging to display.
verify_status_by_course = check_verify_status_by_course(
user,
course_enrollments,
all_course_modes
)
verify_status_by_course = check_verify_status_by_course(user, course_enrollments)
cert_statuses = {
enrollment.course_id: cert_info(request.user, enrollment.course_overview, enrollment.mode)
for enrollment in course_enrollments