Introduce id verification step for proctored exams
TNL-5083
This commit is contained in:
@@ -137,10 +137,11 @@ class ProctoringFields(object):
|
||||
|
||||
|
||||
@XBlock.wants('proctoring')
|
||||
@XBlock.wants('verification')
|
||||
@XBlock.wants('milestones')
|
||||
@XBlock.wants('credit')
|
||||
@XBlock.needs("user")
|
||||
@XBlock.needs("bookmarks")
|
||||
@XBlock.needs('user')
|
||||
@XBlock.needs('bookmarks')
|
||||
class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
"""
|
||||
Layout module which lays out content in a temporal sequence
|
||||
@@ -433,6 +434,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
|
||||
proctoring_service = self.runtime.service(self, 'proctoring')
|
||||
credit_service = self.runtime.service(self, 'credit')
|
||||
verification_service = self.runtime.service(self, 'verification')
|
||||
|
||||
# Is this sequence designated as a Timed Examination, which includes
|
||||
# Proctored Exams
|
||||
@@ -465,6 +467,14 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
'credit_state': credit_state
|
||||
})
|
||||
|
||||
# inject verification status
|
||||
if verification_service:
|
||||
verification_status, __ = verification_service.get_status(user_id)
|
||||
context.update({
|
||||
'verification_status': verification_status,
|
||||
'reverify_url': verification_service.reverify_url(),
|
||||
})
|
||||
|
||||
# See if the edx-proctoring subsystem wants to present
|
||||
# a special view to the student rather
|
||||
# than the actual sequence content
|
||||
|
||||
@@ -161,3 +161,37 @@ class FakePaymentPage(PageObject):
|
||||
self.q(css="input[value='Submit']").click()
|
||||
|
||||
return PaymentAndVerificationFlow(self.browser, self._course_id, entry_point='payment-confirmation').wait_for_page()
|
||||
|
||||
|
||||
class FakeSoftwareSecureVerificationPage(PageObject):
|
||||
"""
|
||||
This page is a page used for testing that allows the user to change the status of their most recent
|
||||
verification.
|
||||
"""
|
||||
|
||||
url = BASE_URL + '/verify_student/software-secure-fake-response'
|
||||
|
||||
def __init__(self, browser):
|
||||
super(FakeSoftwareSecureVerificationPage, self).__init__(browser)
|
||||
|
||||
def is_browser_on_page(self):
|
||||
""" Determine if browser is on the page. """
|
||||
message = self.q(css='BODY').text[0]
|
||||
match = re.search('Fake Software Secure page', message)
|
||||
return True if match else False
|
||||
|
||||
def mark_approved(self):
|
||||
""" Mark the latest verification attempt as passing. """
|
||||
self.q(css='#btn_pass').click()
|
||||
|
||||
def mark_denied(self):
|
||||
""" Mark the latest verification attempt as denied. """
|
||||
self.q(css='#btn_denied').click()
|
||||
|
||||
def mark_error(self):
|
||||
""" Mark the latest verification attempt as an error. """
|
||||
self.q(css='#btn_error').click()
|
||||
|
||||
def mark_unkown_error(self):
|
||||
""" Mark the latest verification attempt as an unknown error. """
|
||||
self.q(css='#btn_unkonwn_error').click()
|
||||
|
||||
@@ -17,7 +17,7 @@ from ...pages.lms.course_nav import CourseNavPage
|
||||
from ...pages.lms.courseware import CoursewarePage, CoursewareSequentialTabPage
|
||||
from ...pages.lms.create_mode import ModeCreationPage
|
||||
from ...pages.lms.dashboard import DashboardPage
|
||||
from ...pages.lms.pay_and_verify import PaymentAndVerificationFlow, FakePaymentPage
|
||||
from ...pages.lms.pay_and_verify import PaymentAndVerificationFlow, FakePaymentPage, FakeSoftwareSecureVerificationPage
|
||||
from ...pages.lms.problem import ProblemPage
|
||||
from ...pages.lms.progress import ProgressPage
|
||||
from ...pages.lms.staff_view import StaffPage
|
||||
@@ -201,6 +201,28 @@ class ProctoredExamTest(UniqueCourseTest):
|
||||
# Submit payment
|
||||
self.fake_payment_page.submit_payment()
|
||||
|
||||
def _verify_user(self):
|
||||
"""
|
||||
Takes user through the verification flow and then marks the verification as 'approved'.
|
||||
"""
|
||||
# Immediately verify the user
|
||||
self.immediate_verification_page.immediate_verification()
|
||||
|
||||
# Take face photo and proceed to the ID photo step
|
||||
self.payment_and_verification_flow.webcam_capture()
|
||||
self.payment_and_verification_flow.next_verification_step(self.immediate_verification_page)
|
||||
|
||||
# Take ID photo and proceed to the review photos step
|
||||
self.payment_and_verification_flow.webcam_capture()
|
||||
self.payment_and_verification_flow.next_verification_step(self.immediate_verification_page)
|
||||
|
||||
# Submit photos and proceed to the enrollment confirmation step
|
||||
self.payment_and_verification_flow.next_verification_step(self.immediate_verification_page)
|
||||
|
||||
# Mark the verification as passing.
|
||||
verification = FakeSoftwareSecureVerificationPage(self.browser).visit()
|
||||
verification.mark_approved()
|
||||
|
||||
def test_can_create_proctored_exam_in_studio(self):
|
||||
"""
|
||||
Given that I am a staff member
|
||||
@@ -221,6 +243,7 @@ class ProctoredExamTest(UniqueCourseTest):
|
||||
select advanced settings tab
|
||||
When I Make the exam proctored.
|
||||
And I login as a verified student.
|
||||
And I verify the user's ID.
|
||||
And visit the courseware as a verified student.
|
||||
Then I can see an option to take the exam as a proctored exam.
|
||||
"""
|
||||
@@ -235,6 +258,8 @@ class ProctoredExamTest(UniqueCourseTest):
|
||||
LogoutPage(self.browser).visit()
|
||||
self._login_as_a_verified_user()
|
||||
|
||||
self._verify_user()
|
||||
|
||||
self.courseware_page.visit()
|
||||
self.assertTrue(self.courseware_page.can_start_proctored_exam)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user