Skip to content

Commit

Permalink
Moved the enrollment mode check to a user permission, which should be…
Browse files Browse the repository at this point in the history
… defined in edx-platform.
  • Loading branch information
Dave St.Germain committed Feb 25, 2019
1 parent b888dd9 commit 89dda35
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 91 deletions.
2 changes: 1 addition & 1 deletion edx_proctoring/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
from __future__ import absolute_import

# Be sure to update the version number in edx_proctoring/package.json
__version__ = '1.5.14'
__version__ = '1.5.15'

default_app_config = 'edx_proctoring.apps.EdxProctoringConfig' # pylint: disable=invalid-name
46 changes: 9 additions & 37 deletions edx_proctoring/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1305,19 +1305,6 @@ def get_active_exams_for_user(user_id, course_id=None):
return result


def _check_eligibility_of_enrollment_mode(credit_state):
"""
Inspects that the enrollment mode of the user
is valid for proctoring
"""

# Allow only the verified students to take the exam as a proctored exam
# Also make an exception for the honor students to take the "practice exam" as a proctored exam.
# For the rest of the enrollment modes, None is returned which shows the exam content
# to the student rather than the proctoring prompt.
return credit_state and credit_state['enrollment_mode'] == 'verified'


def _get_ordered_prerequisites(prerequisites_statuses, filter_out_namespaces=None):
"""
Apply filter and ordering of requirements status in our credit_state dictionary. This will
Expand Down Expand Up @@ -1571,13 +1558,15 @@ def get_attempt_status_summary(user_id, course_id, content_id):
# eligibility
if credit_service and not exam['is_practice_exam']:
credit_state = credit_service.get_credit_state(user_id, six.text_type(course_id), return_course_info=True)
if not _check_eligibility_of_enrollment_mode(credit_state):
user = User.objects.get(id=user_id)
if not user.has_perm('edx_proctoring.can_take_proctored_exam', exam):
return None

attempt = get_exam_attempt(exam['id'], user_id)
if attempt:
status = attempt['status']
elif not exam['is_practice_exam'] and has_due_date_passed(credit_state.get('course_end_date', None)):
elif not exam['is_practice_exam'] \
and credit_state and has_due_date_passed(credit_state.get('course_end_date', None)):
status = ProctoredExamStudentAttemptStatus.expired
else:
status = ProctoredExamStudentAttemptStatus.eligible
Expand Down Expand Up @@ -1863,20 +1852,10 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id):
"""
student_view_template = None

credit_state = context.get('credit_state')

# see if only 'verified' track students should see this *except* if it is a practice exam
check_mode = (
settings.PROCTORING_SETTINGS.get('MUST_BE_VERIFIED_TRACK', True) and
credit_state
)
user = User.objects.get(id=user_id)

if check_mode:
has_mode = _check_eligibility_of_enrollment_mode(credit_state)
if not has_mode:
# user does not have the required enrollment mode
# so do not override view this is a quick exit
return None
if not user.has_perm('edx_proctoring.can_take_proctored_exam', exam):
return None

attempt = get_exam_attempt(exam_id, user_id)

Expand All @@ -1899,10 +1878,7 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id):

# get information about prerequisites

credit_requirement_status = (
credit_state.get('credit_requirement_status')
if credit_state else []
)
credit_requirement_status = context.get('credit_state', {}).get('credit_requirement_status', [])

prerequisite_status = _are_prerequirements_satisfied(
credit_requirement_status,
Expand Down Expand Up @@ -2020,11 +1996,7 @@ def get_student_view(user_id, course_id, content_id,
if user_role != 'student':
return None

credit_service = get_runtime_service('credit')

# call service to get course end date.
credit_state = credit_service.get_credit_state(user_id, course_id, return_course_info=True)
course_end_date = credit_state.get('course_end_date') if credit_state else None
course_end_date = context.get('credit_state', {}).get('course_end_date', None)

exam_id = None
try:
Expand Down
4 changes: 4 additions & 0 deletions edx_proctoring/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def setup_test_perms():
rules.add_perm('accounts.can_retire_user', rules.is_staff)
except KeyError:
pass
try:
rules.add_perm('edx_proctoring.can_take_proctored_exam', rules.is_authenticated)
except KeyError:
pass


setup_test_backends()
Expand Down
35 changes: 0 additions & 35 deletions edx_proctoring/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1618,26 +1618,6 @@ def test_practice_no_attempt(self):
)
self.assertIn(summary, [expected])

@ddt.data(
'honor', 'staff'
)
def test_status_summary_honor(self, enrollment_mode):
"""
Make sure status summary is None for a non-verified person
"""

set_runtime_service('credit', MockCreditService(enrollment_mode=enrollment_mode))

exam_attempt = self._create_started_exam_attempt()

summary = get_attempt_status_summary(
self.user.id,
exam_attempt.proctored_exam.course_id,
exam_attempt.proctored_exam.content_id
)

self.assertIsNone(summary)

def test_status_summary_bad(self):
"""
Make sure we get back a None when getting summary for content that does not
Expand Down Expand Up @@ -1776,21 +1756,6 @@ def test_declined_prerequisites(self, content_id,
self.assertEqual(len(results['pending_prerequisites']), expected_len_pending_prerequisites)
self.assertEqual(len(results['declined_prerequisites']), expected_len_declined_prerequisites)

def test_summary_without_credit_state(self):
"""
Test that attempt status summary is None for users who are not enrolled.
"""
exam_id = self._create_exam_with_due_time()
set_runtime_service('credit', MockCreditServiceNone())

timed_exam = get_exam_by_id(exam_id)
summary = get_attempt_status_summary(
self.user.id,
timed_exam['course_id'],
timed_exam['content_id']
)
self.assertIsNone(summary)

def test_get_exam_violation_report(self):
"""
Test to get all the exam attempts.
Expand Down
20 changes: 4 additions & 16 deletions edx_proctoring/tests/test_student_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,6 @@ def test_get_honor_view_with_practice_exam(self):
})
self.assertIsNotNone(rendered_response)

def test_get_honor_view(self):
"""
Test for get_student_view prompting when the student is enrolled in non-verified
track, this should return None
"""
rendered_response = self.render_proctored_exam({
'credit_state': {
'enrollment_mode': 'honor'
},
})
self.assertIsNone(rendered_response)

@ddt.data(
(None, 'Make sure you are on a computer with a webcam, and that you have valid photo identification'),
('pending', 'Your verification is pending'),
Expand Down Expand Up @@ -334,8 +322,7 @@ def test_proctored_exam_passed_end_date(self):
Verify that we get a None back on a proctored exam
if the course end date is passed
"""

set_runtime_service('credit', MockCreditServiceWithCourseEndDate())
credit_state = MockCreditServiceWithCourseEndDate().get_credit_state(self.user_id, 'foo', True)

rendered_response = get_student_view(
user_id=self.user_id,
Expand All @@ -348,6 +335,7 @@ def test_proctored_exam_passed_end_date(self):
'default_time_limit_mins': 90,
'due_date': None,
'hide_after_due': False,
'credit_state': credit_state,
},
user_role='student'
)
Expand All @@ -358,8 +346,7 @@ def test_practice_exam_passed_end_date(self):
Verify that we get a None back on a practice exam
if the course end date is passed
"""

set_runtime_service('credit', MockCreditServiceWithCourseEndDate())
credit_state = MockCreditServiceWithCourseEndDate().get_credit_state(self.user_id, 'foo', True)

rendered_response = get_student_view(
user_id=self.user_id,
Expand All @@ -372,6 +359,7 @@ def test_practice_exam_passed_end_date(self):
'default_time_limit_mins': 90,
'due_date': None,
'hide_after_due': False,
'credit_state': credit_state,
},
user_role='student'
)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@edx/edx-proctoring",
"//": "Be sure to update the version number in edx_proctoring/__init__.py",
"//": "Note that the version format is slightly different than that of the Python version when using prereleases.",
"version": "1.5.14",
"version": "1.5.15",
"main": "edx_proctoring/static/index.js",
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
}

PROCTORING_SETTINGS = {
'MUST_BE_VERIFIED_TRACK': True,
'MUST_COMPLETE_ICRV': True,
'LINK_URLS': {
'online_proctoring_rules': '',
Expand Down

0 comments on commit 89dda35

Please sign in to comment.