fix: enrollment should still display if IDV is disabled (#29819)

MST-1317. The enrollment mode of a learner should still display on the course listing, even if IDV is disabled. Right now, all enrollment messaging is disabled if IDV is turned off, as we are no longer returning the verifications status for a learner in that case. We should still return the enrollment mode if IDV is disabled, but exclude any IDV messaging.
This commit is contained in:
alangsto
2022-01-26 10:14:33 -05:00
committed by GitHub
parent 4f58ed4f25
commit 0e7534d730
3 changed files with 69 additions and 46 deletions

View File

@@ -11,6 +11,7 @@ from slumber.exceptions import SlumberBaseException
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student.helpers import VERIFY_STATUS_APPROVED, VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED # lint-amnesty, pylint: disable=line-too-long
from openedx.core.djangoapps.agreements.toggles import is_integrity_signature_enabled
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
DISPLAY_VERIFIED = "verified"
@@ -41,16 +42,16 @@ def enrollment_mode_display(mode, verification_status, course_id):
display_mode = _enrollment_mode_display(mode, verification_status, course_id)
if display_mode == DISPLAY_VERIFIED:
if verification_status in [VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED]:
enrollment_title = _("Your verification is pending")
enrollment_value = _("Verified: Pending Verification")
show_image = True
image_alt = _("ID verification pending")
elif verification_status == VERIFY_STATUS_APPROVED:
if is_integrity_signature_enabled(course_id) or verification_status == VERIFY_STATUS_APPROVED:
enrollment_title = _("You're enrolled as a verified student")
enrollment_value = _("Verified")
show_image = True
image_alt = _("ID Verified Ribbon/Badge")
elif verification_status in [VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED]:
enrollment_title = _("Your verification is pending")
enrollment_value = _("Verified: Pending Verification")
show_image = True
image_alt = _("ID verification pending")
elif display_mode == DISPLAY_HONOR:
enrollment_title = _("You're enrolled as an honor code student")
enrollment_value = _("Honor Code")
@@ -63,7 +64,7 @@ def enrollment_mode_display(mode, verification_status, course_id):
'enrollment_value': str(enrollment_value),
'show_image': show_image,
'image_alt': str(image_alt),
'display_mode': _enrollment_mode_display(mode, verification_status, course_id)
'display_mode': display_mode
}
@@ -79,7 +80,10 @@ def _enrollment_mode_display(enrollment_mode, verification_status, course_id):
course_mode_slugs = [mode.slug for mode in CourseMode.modes_for_course(course_id)]
if enrollment_mode == CourseMode.VERIFIED:
if verification_status in [VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED, VERIFY_STATUS_APPROVED]:
if (
is_integrity_signature_enabled(course_id)
or verification_status in [VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED, VERIFY_STATUS_APPROVED]
):
display_mode = DISPLAY_VERIFIED
elif DISPLAY_HONOR in course_mode_slugs:
display_mode = DISPLAY_HONOR

View File

@@ -14,6 +14,7 @@ import ddt
from django.core.exceptions import ValidationError
from django.test import TestCase, override_settings
from django.utils.timezone import now
from edx_toggles.toggles.testutils import override_waffle_flag
from opaque_keys.edx.locator import CourseLocator
from common.djangoapps.course_modes.helpers import enrollment_mode_display
@@ -24,6 +25,7 @@ from common.djangoapps.course_modes.models import (
invalidate_course_mode_cache
)
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from openedx.core.djangoapps.agreements.toggles import ENABLE_INTEGRITY_SIGNATURE
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
@@ -341,36 +343,49 @@ class CourseModeModelTest(TestCase):
assert exc.messages == ['Professional education modes are not allowed to have expiration_datetime set.']
@ddt.data(
("verified", "verify_need_to_verify"),
("verified", "verify_submitted"),
("verified", "verify_approved"),
("verified", 'dummy'),
("verified", None),
('honor', None),
('honor', 'dummy'),
('audit', None),
('professional', None),
('no-id-professional', None),
('no-id-professional', 'dummy')
("verified", "verify_need_to_verify", True),
("verified", "verify_submitted", True),
("verified", "verify_approved", True),
("verified", 'dummy', True),
("verified", None, True),
('honor', None, True),
('honor', 'dummy', True),
('audit', None, True),
('professional', None, True),
('no-id-professional', None, True),
('no-id-professional', 'dummy', True),
("verified", "verify_need_to_verify", False),
("verified", "verify_submitted", False),
("verified", "verify_approved", False),
("verified", 'dummy', False),
("verified", None, False),
('honor', None, False),
('honor', 'dummy', False),
('audit', None, False),
('professional', None, False),
('no-id-professional', None, False),
('no-id-professional', 'dummy', False)
)
@ddt.unpack
def test_enrollment_mode_display(self, mode, verification_status):
if mode == "verified":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(verification_status)
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(verification_status)
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(verification_status)
elif mode == "honor":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode)
elif mode == "audit":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode)
elif mode == "professional":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode)
def test_enrollment_mode_display(self, mode, verification_status, enable_flag):
with override_waffle_flag(ENABLE_INTEGRITY_SIGNATURE, active=enable_flag):
if mode == "verified":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, verification_status, enable_flag)
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, verification_status, enable_flag)
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, verification_status, enable_flag)
elif mode == "honor":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, mode, enable_flag)
elif mode == "audit":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, mode, enable_flag)
elif mode == "professional":
assert enrollment_mode_display(mode, verification_status, self.course_key) ==\
self._enrollment_display_modes_dicts(mode, mode, enable_flag)
@ddt.data(
(['honor', 'verified', 'credit'], ['honor', 'verified']),
@@ -394,7 +409,7 @@ class CourseModeModelTest(TestCase):
all_modes = CourseMode.modes_for_course_dict(self.course_key, only_selectable=False)
self.assertCountEqual(list(all_modes.keys()), available_modes)
def _enrollment_display_modes_dicts(self, dict_type):
def _enrollment_display_modes_dicts(self, mode, dict_type, enable_flag):
"""
Helper function to generate the enrollment display mode dict.
"""
@@ -410,7 +425,9 @@ class CourseModeModelTest(TestCase):
"professional": ["You're enrolled as a professional education student", "Professional Ed", False, '',
'professional']
}
if dict_type in ['verify_need_to_verify', 'verify_submitted']:
if mode == 'verified' and enable_flag:
return dict(list(zip(dict_keys, display_values.get('verify_approved'))))
elif dict_type in ['verify_need_to_verify', 'verify_submitted']:
return dict(list(zip(dict_keys, display_values.get('verify_need_to_verify'))))
elif dict_type is None or dict_type == 'dummy':
return dict(list(zip(dict_keys, display_values.get('verify_none'))))

View File

@@ -332,19 +332,19 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
else:
self._setup_mode_and_enrollment(None, "verified")
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
attempt = SoftwareSecurePhotoVerification.objects.create(user=self.user)
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
attempt.mark_ready()
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
attempt.submit()
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
attempt.approve()
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
attempt.expiration_date = self.DATES[self.PAST] - timedelta(days=900)
attempt.save()
self._assert_course_verification_status(None)
self._assert_course_verification_status(None, "verified")
@ddt.data(True, False)
def test_integrity_disables_sidebar(self, integrity_flag):
@@ -416,7 +416,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
VERIFY_STATUS_RESUBMITTED: "audit"
}
def _assert_course_verification_status(self, status):
def _assert_course_verification_status(self, status, enrollment_mode=None):
"""Check whether the specified verification status is shown on the dashboard.
Arguments:
@@ -437,10 +437,12 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
if alt_text:
self.assertContains(response, alt_text)
mode = enrollment_mode if enrollment_mode else self.MODE_CLASSES[status]
# Verify that the correct banner color is rendered
self.assertContains(
response,
f"<article class=\"course {self.MODE_CLASSES[status]}\""
f"<article class=\"course {mode}\""
)
# Verify that the correct copy is rendered on the dashboard