MST-542 Roll out Accounts MFE IDV workflow (#25613)
* MST-542 remove the IDV redirect to Account MFE waffle flag to permanently redirect learners to new IDV workflow. This completes the rollout process on edx-platform
This commit is contained in:
@@ -20,6 +20,7 @@ from common.djangoapps.course_modes.models import CourseMode, Mode
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
from lms.djangoapps.commerce.tests import test_utils as ecomm_test_utils
|
||||
from lms.djangoapps.commerce.tests.mocks import mock_payment_processors
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
|
||||
from openedx.core.djangoapps.embargo.test_utils import restrict_course
|
||||
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
|
||||
@@ -116,11 +117,10 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
|
||||
# Configure whether we're upgrading or not
|
||||
url = reverse('course_modes_choose', args=[six.text_type(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
|
||||
start_flow_url = IDVerificationService.get_verify_location(course_id=self.course.id)
|
||||
# Check whether we were correctly redirected
|
||||
purchase_workflow = "?purchase_workflow=single"
|
||||
start_flow_url = reverse('verify_student_start_flow', args=[six.text_type(self.course.id)]) + purchase_workflow
|
||||
with mock_payment_processors():
|
||||
self.assertRedirects(response, start_flow_url)
|
||||
self.assertRedirects(response, start_flow_url, fetch_redirect_response=False)
|
||||
|
||||
def test_no_id_redirect_otto(self):
|
||||
# Create the course modes
|
||||
@@ -266,10 +266,8 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
|
||||
|
||||
# Since the only available track is professional ed, expect that
|
||||
# we're redirected immediately to the start of the payment flow.
|
||||
purchase_workflow = "?purchase_workflow=single"
|
||||
start_flow_url = reverse('verify_student_start_flow', args=[six.text_type(self.course.id)]) + purchase_workflow
|
||||
with mock_payment_processors():
|
||||
self.assertRedirects(response, start_flow_url)
|
||||
start_flow_url = IDVerificationService.get_verify_location(course_id=self.course.id)
|
||||
self.assertRedirects(response, start_flow_url, fetch_redirect_response=False)
|
||||
|
||||
# Now enroll in the course
|
||||
CourseEnrollmentFactory(
|
||||
@@ -312,15 +310,12 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest
|
||||
if expected_redirect == 'dashboard':
|
||||
redirect_url = reverse('dashboard')
|
||||
elif expected_redirect == 'start-flow':
|
||||
redirect_url = reverse(
|
||||
'verify_student_start_flow',
|
||||
kwargs={'course_id': six.text_type(self.course.id)}
|
||||
)
|
||||
redirect_url = IDVerificationService.get_verify_location(course_id=self.course.id)
|
||||
else:
|
||||
self.fail("Must provide a valid redirect URL name")
|
||||
|
||||
with mock_payment_processors(expect_called=None):
|
||||
self.assertRedirects(response, redirect_url)
|
||||
self.assertRedirects(response, redirect_url, fetch_redirect_response=False,)
|
||||
|
||||
def test_choose_mode_audit_enroll_on_post(self):
|
||||
audit_mode = 'audit'
|
||||
|
||||
@@ -112,8 +112,7 @@ class ChooseModeView(View):
|
||||
has_enrolled_professional = (CourseMode.is_professional_slug(enrollment_mode) and is_active)
|
||||
if CourseMode.has_professional_mode(modes) and not has_enrolled_professional:
|
||||
purchase_workflow = request.GET.get("purchase_workflow", "single")
|
||||
verify_url = IDVerificationService.get_verify_location('verify_student_start_flow', course_id=course_key)
|
||||
redirect_url = "{url}?purchase_workflow={workflow}".format(url=verify_url, workflow=purchase_workflow)
|
||||
redirect_url = IDVerificationService.get_verify_location(course_id=course_key)
|
||||
if ecommerce_service.is_enabled(request.user):
|
||||
professional_mode = modes.get(CourseMode.NO_ID_PROFESSIONAL_MODE) or modes.get(CourseMode.PROFESSIONAL)
|
||||
if purchase_workflow == "single" and professional_mode.sku:
|
||||
@@ -311,7 +310,7 @@ class ChooseModeView(View):
|
||||
donation_for_course[six.text_type(course_key)] = amount_value
|
||||
request.session["donation_for_course"] = donation_for_course
|
||||
|
||||
verify_url = IDVerificationService.get_verify_location('verify_student_start_flow', course_id=course_key)
|
||||
verify_url = IDVerificationService.get_verify_location(course_id=course_key)
|
||||
return redirect(verify_url)
|
||||
|
||||
def _get_requested_mode(self, request_dict):
|
||||
|
||||
@@ -127,11 +127,9 @@ class ProgressTabView(RetrieveAPIView):
|
||||
verification_status = IDVerificationService.user_status(request.user)
|
||||
verification_link = None
|
||||
if verification_status['status'] is None or verification_status['status'] == 'expired':
|
||||
verification_link = IDVerificationService.get_verify_location('verify_student_verify_now',
|
||||
course_id=course_key)
|
||||
verification_link = IDVerificationService.get_verify_location(course_id=course_key)
|
||||
elif verification_status['status'] == 'must_reverify':
|
||||
verification_link = IDVerificationService.get_verify_location('verify_student_reverify',
|
||||
course_id=course_key)
|
||||
verification_link = IDVerificationService.get_verify_location(course_id=course_key)
|
||||
verification_data = {
|
||||
'link': verification_link,
|
||||
'status': verification_status['status'],
|
||||
|
||||
@@ -664,11 +664,11 @@ class VerificationDeadlineDate(DateSummary):
|
||||
'verification-deadline-passed': (_('Learn More'), ''),
|
||||
'verification-deadline-retry': (
|
||||
_('Retry Verification'),
|
||||
IDVerificationService.get_verify_location('verify_student_reverify'),
|
||||
IDVerificationService.get_verify_location(),
|
||||
),
|
||||
'verification-deadline-upcoming': (
|
||||
_('Verify My Identity'),
|
||||
IDVerificationService.get_verify_location('verify_student_verify_now', self.course_id),
|
||||
IDVerificationService.get_verify_location(self.course_id),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ from lms.djangoapps.courseware.models import (
|
||||
)
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from lms.djangoapps.verify_student.models import VerificationDeadline
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.schedules.signals import CREATE_SCHEDULE_WAFFLE_FLAG
|
||||
@@ -679,7 +680,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'You must successfully complete verification before this date to qualify for a Verified Certificate.'
|
||||
)
|
||||
self.assertEqual(block.link_text, 'Verify My Identity')
|
||||
self.assertEqual(block.link, reverse('verify_student_verify_now', args=(course.id,)))
|
||||
self.assertEqual(block.link, IDVerificationService.get_verify_location(course.id))
|
||||
|
||||
def test_verification_deadline_date_retry(self):
|
||||
with freeze_time('2015-01-02'):
|
||||
@@ -696,7 +697,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'You must successfully complete verification before this date to qualify for a Verified Certificate.'
|
||||
)
|
||||
self.assertEqual(block.link_text, 'Retry Verification')
|
||||
self.assertEqual(block.link, reverse('verify_student_reverify'))
|
||||
self.assertEqual(block.link, IDVerificationService.get_verify_location())
|
||||
|
||||
def test_verification_deadline_date_denied(self):
|
||||
with freeze_time('2015-01-02'):
|
||||
|
||||
@@ -17,7 +17,6 @@ from openedx.core.djangoapps.site_configuration import helpers as configuration_
|
||||
from common.djangoapps.student.models import User
|
||||
|
||||
from .models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification
|
||||
from .toggles import redirect_to_idv_microfrontend
|
||||
from .utils import earliest_allowed_verification_date, most_recent_verification, active_verifications
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -49,7 +48,7 @@ class XBlockVerificationService(object):
|
||||
"""
|
||||
Returns the URL for a user to verify themselves.
|
||||
"""
|
||||
return IDVerificationService.get_verify_location('verify_student_reverify')
|
||||
return IDVerificationService.get_verify_location()
|
||||
|
||||
|
||||
class IDVerificationService(object):
|
||||
@@ -232,24 +231,12 @@ class IDVerificationService(object):
|
||||
return 'ID Verified'
|
||||
|
||||
@classmethod
|
||||
def get_verify_location(cls, url_name, course_id=None):
|
||||
def get_verify_location(cls, course_id=None):
|
||||
"""
|
||||
url_name is one of:
|
||||
'verify_student_verify_now'
|
||||
'verify_student_reverify'
|
||||
|
||||
Returns a string:
|
||||
If waffle flag is active, returns URL for IDV microfrontend.
|
||||
Else, returns URL for corresponding view.
|
||||
Returns URL for IDV on Account Microfrontend
|
||||
"""
|
||||
location = ''
|
||||
if redirect_to_idv_microfrontend():
|
||||
location = '{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL)
|
||||
if course_id:
|
||||
location = location + '?{}'.format(str(course_id))
|
||||
else:
|
||||
if course_id:
|
||||
location = reverse(url_name, args=[str(course_id)])
|
||||
else:
|
||||
location = reverse(url_name)
|
||||
location = '{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL)
|
||||
if course_id:
|
||||
location = location + '?{}'.format(str(course_id))
|
||||
return location
|
||||
|
||||
@@ -6,12 +6,13 @@ import six
|
||||
from django.urls import reverse
|
||||
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
from lms.djangoapps.commerce.tests.mocks import mock_payment_processors
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
from ..services import IDVerificationService
|
||||
|
||||
|
||||
class TestProfEdVerification(ModuleStoreTestCase):
|
||||
"""
|
||||
@@ -34,31 +35,26 @@ class TestProfEdVerification(ModuleStoreTestCase):
|
||||
min_price=self.MIN_PRICE,
|
||||
suggested_prices=''
|
||||
)
|
||||
purchase_workflow = "?purchase_workflow=single"
|
||||
self.urls = {
|
||||
'course_modes_choose': reverse(
|
||||
'course_modes_choose',
|
||||
args=[six.text_type(self.course_key)]
|
||||
),
|
||||
|
||||
'verify_student_start_flow': reverse(
|
||||
'verify_student_start_flow',
|
||||
args=[six.text_type(self.course_key)]
|
||||
) + purchase_workflow,
|
||||
'verify_student_start_flow': IDVerificationService.get_verify_location(self.course_key),
|
||||
}
|
||||
|
||||
def test_start_flow(self):
|
||||
# Go to the course mode page, expecting a redirect to the intro step of the
|
||||
# payment flow (since this is a professional ed course). Otherwise, the student
|
||||
# would have the option to choose their track.
|
||||
with mock_payment_processors():
|
||||
resp = self.client.get(self.urls['course_modes_choose'], follow=True)
|
||||
self.assertRedirects(resp, self.urls['verify_student_start_flow'])
|
||||
resp = self.client.get(self.urls['course_modes_choose'])
|
||||
self.assertRedirects(
|
||||
resp,
|
||||
self.urls['verify_student_start_flow'],
|
||||
fetch_redirect_response=False,
|
||||
)
|
||||
|
||||
# For professional ed courses, expect that the student is NOT enrolled
|
||||
# automatically in the course.
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
|
||||
|
||||
# On the first page of the flow, verify that there's a button allowing the user
|
||||
# to proceed to the payment processor; this is the only action the user is allowed to take.
|
||||
self.assertContains(resp, 'payment-button')
|
||||
|
||||
@@ -32,6 +32,7 @@ from lms.djangoapps.commerce.tests import TEST_API_URL, TEST_PAYMENT_DATA, TEST_
|
||||
from lms.djangoapps.commerce.tests.mocks import mock_payment_processors
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from lms.djangoapps.verify_student.views import PayAndVerifyView, checkout_with_ecommerce_service, render_to_response
|
||||
from openedx.core.djangoapps.embargo.test_utils import restrict_course
|
||||
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
|
||||
@@ -959,9 +960,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin, Tes
|
||||
|
||||
def _assert_redirects_to_verify_start(self, response, course_id, status_code=302):
|
||||
"""Check that the page redirects to the "verify later" part of the flow. """
|
||||
url = reverse('verify_student_verify_now', kwargs={'course_id': six.text_type(course_id)})
|
||||
with mock_payment_processors():
|
||||
self.assertRedirects(response, url, status_code)
|
||||
url = IDVerificationService.get_verify_location(course_id=course_id)
|
||||
self.assertRedirects(response, url, status_code, fetch_redirect_response=False)
|
||||
|
||||
def _assert_redirects_to_upgrade(self, response, course_id):
|
||||
"""Check that the page redirects to the "upgrade" part of the flow. """
|
||||
@@ -1713,13 +1713,13 @@ class TestReverifyView(TestVerificationBase):
|
||||
"""
|
||||
Test that a User can use re-verify link for initial verification.
|
||||
"""
|
||||
self._assert_can_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
def test_reverify_view_can_reverify_denied(self):
|
||||
# User has a denied attempt, so can re-verify
|
||||
attempt = self.create_and_submit_attempt_for_user(self.user)
|
||||
attempt.deny("error")
|
||||
self._assert_can_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
def test_reverify_view_can_reverify_expired(self):
|
||||
# User has a verification attempt, but it's expired
|
||||
@@ -1731,7 +1731,7 @@ class TestReverifyView(TestVerificationBase):
|
||||
attempt.save()
|
||||
|
||||
# Allow the student to re-verify
|
||||
self._assert_can_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
def test_reverify_view_can_reverify_pending(self):
|
||||
""" Test that the user can still re-verify even if the previous photo
|
||||
@@ -1746,7 +1746,7 @@ class TestReverifyView(TestVerificationBase):
|
||||
self.create_and_submit_attempt_for_user(self.user)
|
||||
|
||||
# Can re-verify because an attempt has already been submitted.
|
||||
self._assert_can_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
def test_reverify_view_cannot_reverify_approved(self):
|
||||
# Submitted attempt has been approved
|
||||
@@ -1754,7 +1754,7 @@ class TestReverifyView(TestVerificationBase):
|
||||
attempt.approve()
|
||||
|
||||
# Cannot re-verify because the user is already verified.
|
||||
self._assert_cannot_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
@override_settings(VERIFY_STUDENT={"DAYS_GOOD_FOR": 5, "EXPIRING_SOON_WINDOW": 10})
|
||||
def test_reverify_view_can_reverify_approved_expired_soon(self):
|
||||
@@ -1768,25 +1768,10 @@ class TestReverifyView(TestVerificationBase):
|
||||
attempt.approve()
|
||||
|
||||
# Can re-verify because verification is set to expired soon.
|
||||
self._assert_can_reverify()
|
||||
self._assert_reverify()
|
||||
|
||||
def _get_reverify_page(self):
|
||||
"""
|
||||
Retrieve the re-verification page and return the response.
|
||||
"""
|
||||
def _assert_reverify(self):
|
||||
url = reverse("verify_student_reverify")
|
||||
return self.client.get(url)
|
||||
|
||||
def _assert_can_reverify(self):
|
||||
"""
|
||||
Check that the re-verification flow is rendered.
|
||||
"""
|
||||
response = self._get_reverify_page()
|
||||
self.assertContains(response, "reverify-container")
|
||||
|
||||
def _assert_cannot_reverify(self):
|
||||
"""
|
||||
Check that the user is blocked from re-verifying.
|
||||
"""
|
||||
response = self._get_reverify_page()
|
||||
self.assertContains(response, "reverify-blocked")
|
||||
response = self.client.get(url)
|
||||
verification_start_url = IDVerificationService.get_verify_location()
|
||||
self.assertRedirects(response, verification_start_url, fetch_redirect_response=False)
|
||||
|
||||
@@ -27,24 +27,3 @@ USE_NEW_EMAIL_TEMPLATES = WaffleFlag(
|
||||
|
||||
def use_new_templates_for_id_verification_emails():
|
||||
return USE_NEW_EMAIL_TEMPLATES.is_enabled()
|
||||
|
||||
|
||||
# Waffle flag to redirect to the new IDV flow on the account microfrontend
|
||||
# .. toggle_name: verify_student.redirect_to_idv_microfrontend
|
||||
# .. toggle_implementation: WaffleFlag
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Supports staged rollout to students for the new IDV flow.
|
||||
# .. toggle_use_cases: temporary, open_edx
|
||||
# .. toggle_creation_date: 2020-07-09
|
||||
# .. toggle_target_removal_date: None
|
||||
# .. toggle_warnings: This temporary feature toggle does not have a target removal date.
|
||||
# .. toggle_tickets: MST-318
|
||||
REDIRECT_TO_IDV_MICROFRONTEND = WaffleFlag(
|
||||
waffle_namespace=WAFFLE_FLAG_NAMESPACE,
|
||||
flag_name='redirect_to_idv_microfrontend',
|
||||
module_name=__name__,
|
||||
)
|
||||
|
||||
|
||||
def redirect_to_idv_microfrontend():
|
||||
return REDIRECT_TO_IDV_MICROFRONTEND.is_enabled()
|
||||
|
||||
@@ -52,7 +52,6 @@ from common.djangoapps.util.json_request import JsonResponse
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from .services import IDVerificationService
|
||||
from .toggles import redirect_to_idv_microfrontend
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -499,10 +498,7 @@ class PayAndVerifyView(View):
|
||||
if is_enrolled:
|
||||
if already_paid:
|
||||
# If the student has paid, but not verified, redirect to the verification flow.
|
||||
url = IDVerificationService.get_verify_location(
|
||||
'verify_student_verify_now',
|
||||
six.text_type(course_key)
|
||||
)
|
||||
url = IDVerificationService.get_verify_location(six.text_type(course_key))
|
||||
else:
|
||||
url = reverse('verify_student_start_flow', kwargs=course_kwargs)
|
||||
|
||||
@@ -1216,19 +1212,5 @@ class ReverifyView(View):
|
||||
Most of the work is done client-side by composing the same
|
||||
Backbone views used in the initial verification flow.
|
||||
"""
|
||||
verification_status = IDVerificationService.user_status(request.user)
|
||||
expiration_datetime = IDVerificationService.get_expiration_datetime(request.user, ['approved'])
|
||||
if can_verify_now(verification_status, expiration_datetime):
|
||||
if redirect_to_idv_microfrontend():
|
||||
return redirect('{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL))
|
||||
context = {
|
||||
"user_full_name": request.user.profile.name,
|
||||
"platform_name": configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
|
||||
"capture_sound": staticfiles_storage.url("audio/camera_capture.wav"),
|
||||
}
|
||||
return render_to_response("verify_student/reverify.html", context)
|
||||
else:
|
||||
context = {
|
||||
"status": verification_status['status']
|
||||
}
|
||||
return render_to_response("verify_student/reverify_not_allowed.html", context)
|
||||
IDV_workflow = IDVerificationService.get_verify_location()
|
||||
return redirect(IDV_workflow)
|
||||
|
||||
@@ -570,7 +570,7 @@ PDF_RECEIPT_TAX_ID_LABEL = 'Tax ID'
|
||||
|
||||
PROFILE_MICROFRONTEND_URL = "http://profile-mfe/abc/"
|
||||
ORDER_HISTORY_MICROFRONTEND_URL = "http://order-history-mfe/"
|
||||
ACCOUNT_MICROFRONTEND_URL = "http://account-mfe/"
|
||||
ACCOUNT_MICROFRONTEND_URL = "http://account-mfe"
|
||||
LOGISTRATION_MICROFRONTEND_URL = "http://logistation-mfe"
|
||||
LOGISTRATION_MICROFRONTEND_DOMAIN = "logistation-mfe"
|
||||
LEARNING_MICROFRONTEND_URL = "http://learning-mfe"
|
||||
|
||||
@@ -29,7 +29,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
%>
|
||||
|
||||
<%
|
||||
reverify_link = IDVerificationService.get_verify_location('verify_student_reverify')
|
||||
reverify_link = IDVerificationService.get_verify_location()
|
||||
cert_name_short = course_overview.cert_name_short
|
||||
if cert_name_short == "":
|
||||
cert_name_short = settings.CERT_NAME_SHORT
|
||||
@@ -370,7 +370,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
% endif
|
||||
</div>
|
||||
<div class="verification-cta">
|
||||
<a href="${IDVerificationService.get_verify_location('verify_student_verify_now', course_overview.id)}" class="btn" data-course-id="${course_overview.id}">${_('Verify Now')}</a>
|
||||
<a href="${IDVerificationService.get_verify_location(course_overview.id)}" class="btn" data-course-id="${course_overview.id}">${_('Verify Now')}</a>
|
||||
</div>
|
||||
% elif verification_status['status'] == VERIFY_STATUS_SUBMITTED:
|
||||
<h4 class="message-title">${_('You have submitted your verification information.')}</h4>
|
||||
@@ -388,7 +388,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
## Translators: start_link and end_link will be replaced with HTML tags;
|
||||
## please do not translate these.
|
||||
<p class="message-copy">${Text(_('Your current verification will expire in {days} days. {start_link}Re-verify your identity now{end_link} using a webcam and a government-issued photo ID.')).format(
|
||||
start_link=HTML('<a href="{href}">').format(href=IDVerificationService.get_verify_location('verify_student_reverify')),
|
||||
start_link=HTML('<a href="{href}">').format(href=IDVerificationService.get_verify_location()),
|
||||
end_link=HTML('</a>'),
|
||||
days=settings.VERIFY_STUDENT.get("EXPIRING_SOON_WINDOW")
|
||||
)}
|
||||
@@ -420,7 +420,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
% if use_ecommerce_payment_flow and course_mode_info['verified_sku']:
|
||||
<a class="action action-upgrade track_course_dashboard_green_button" href="${ecommerce_payment_page}?sku=${course_mode_info['verified_sku']}">
|
||||
% else:
|
||||
<a class="action action-upgrade track_course_dashboard_green_button" href="${IDVerificationService.get_verify_location('verify_student_upgrade_and_verify', course_id=course_overview.id)}" data-course-id="${course_overview.id}" data-user="${user.username}">
|
||||
<a class="action action-upgrade track_course_dashboard_green_button" href="${IDVerificationService.get_verify_location(course_id=course_overview.id)}" data-course-id="${course_overview.id}" data-user="${user.username}">
|
||||
% endif
|
||||
<span class="action-upgrade-icon" aria-hidden="true"></span>
|
||||
<span class="wrapper-copy">
|
||||
|
||||
@@ -14,7 +14,7 @@ from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
%if verification_expiry:
|
||||
<p class="status-note"><span><b>${_("Warning")}: </b></span><i>${_("Your photo verification expires on {verification_expiry}. Please be aware photo verification can take up to three days once initiated and you will not be able to earn a certificate or take a proctored exam until approved.").format(verification_expiry=verification_expiry)}</i></p>
|
||||
<div class="btn-reverify">
|
||||
<a href="${IDVerificationService.get_verify_location('verify_student_reverify')}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
<a href="${IDVerificationService.get_verify_location()}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
</div>
|
||||
%endif
|
||||
</li>
|
||||
@@ -40,7 +40,7 @@ from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
%endif
|
||||
</p>
|
||||
<div class="btn-reverify">
|
||||
<a href="${IDVerificationService.get_verify_location('verify_student_reverify')}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
<a href="${IDVerificationService.get_verify_location()}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
</div>
|
||||
</li>
|
||||
%elif verification_status == 'expired':
|
||||
@@ -49,7 +49,7 @@ from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
<p class="status-note">${_("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.")}</p>
|
||||
<p class="status-note"><span><b>${_("Warning")}: </b></span><i>${_(" Please be aware photo verification can take up to three days once initiated and you will not be able to earn a certificate or take a proctored exam until approved.")}</i></p>
|
||||
<div class="btn-reverify">
|
||||
<a href="${IDVerificationService.get_verify_location('verify_student_reverify')}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
<a href="${IDVerificationService.get_verify_location()}" class="action action-reverify">${_("Resubmit Verification")}</a>
|
||||
</div>
|
||||
</li>
|
||||
%endif
|
||||
|
||||
@@ -19,6 +19,7 @@ from lms.djangoapps.certificates.tests.factories import (
|
||||
from lms.djangoapps.courseware.access_utils import ACCESS_DENIED, ACCESS_GRANTED
|
||||
from lms.djangoapps.courseware.tabs import ExternalLinkCourseTab
|
||||
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentCelebration
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentCelebrationFactory, UserFactory
|
||||
from xmodule.modulestore.django import modulestore
|
||||
@@ -133,7 +134,9 @@ class CourseApiTestViews(BaseCoursewareTests):
|
||||
assert response.data['linkedin_add_to_profile_url'] is None
|
||||
else:
|
||||
assert response.data['certificate_data']['cert_status'] == 'earned_but_not_available'
|
||||
expected_verify_identity_url = reverse('verify_student_verify_now', args=[self.course.id])
|
||||
expected_verify_identity_url = IDVerificationService.get_verify_location(
|
||||
course_id=self.course.id
|
||||
)
|
||||
# The response contains an absolute URL so this is only checking the path of the final
|
||||
assert expected_verify_identity_url in response.data['verify_identity_url']
|
||||
|
||||
|
||||
@@ -253,9 +253,9 @@ class CoursewareMeta:
|
||||
if self.enrollment_object and self.enrollment_object.mode in CourseMode.VERIFIED_MODES:
|
||||
verification_status = IDVerificationService.user_status(self.effective_user)['status']
|
||||
if verification_status == 'must_reverify':
|
||||
return IDVerificationService.get_verify_location('verify_student_reverify')
|
||||
return IDVerificationService.get_verify_location()
|
||||
else:
|
||||
return IDVerificationService.get_verify_location('verify_student_verify_now', self.course_key)
|
||||
return IDVerificationService.get_verify_location(self.course_key)
|
||||
|
||||
@property
|
||||
def linkedin_add_to_profile_url(self):
|
||||
|
||||
Reference in New Issue
Block a user