Skip to content

Commit 4b827bf

Browse files
authored
feat: show error on courses with unknown proctoring providers (#35445)
1 parent 08bd8b3 commit 4b827bf

File tree

3 files changed

+63
-25
lines changed

3 files changed

+63
-25
lines changed

cms/djangoapps/contentstore/rest_api/v1/views/tests/test_proctoring.py

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,14 @@ def test_update_exam_settings_invalid_value(self):
277277

278278
# response is correct
279279
assert response.status_code == status.HTTP_400_BAD_REQUEST
280-
self.assertDictEqual(
281-
response.data,
280+
self.assertIn(
282281
{
283-
"detail": [
284-
{
285-
"proctoring_provider": (
286-
"The selected proctoring provider, notvalidprovider, is not a valid provider. "
287-
"Please select from one of ['test_proctoring_provider']."
288-
)
289-
}
290-
]
282+
"proctoring_provider": (
283+
"The selected proctoring provider, notvalidprovider, is not a valid provider. "
284+
"Please select from one of ['test_proctoring_provider']."
285+
)
291286
},
287+
response.data['detail'],
292288
)
293289

294290
# course settings have been updated
@@ -408,18 +404,14 @@ def test_400_for_disabled_lti(self):
408404

409405
# response is correct
410406
assert response.status_code == status.HTTP_400_BAD_REQUEST
411-
self.assertDictEqual(
412-
response.data,
407+
self.assertIn(
413408
{
414-
"detail": [
415-
{
416-
"proctoring_provider": (
417-
"The selected proctoring provider, lti_external, is not a valid provider. "
418-
"Please select from one of ['null']."
419-
)
420-
}
421-
]
409+
"proctoring_provider": (
410+
"The selected proctoring provider, lti_external, is not a valid provider. "
411+
"Please select from one of ['null']."
412+
)
422413
},
414+
response.data['detail'],
423415
)
424416

425417
# course settings have been updated

cms/djangoapps/contentstore/views/tests/test_exam_settings_view.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,39 @@ def test_exam_settings_alert_with_exam_settings_disabled(self, page_handler):
162162
else:
163163
assert 'To update these settings go to the Advanced Settings page.' in alert_text
164164

165+
@override_settings(
166+
PROCTORING_BACKENDS={
167+
'DEFAULT': 'test_proctoring_provider',
168+
'proctortrack': {},
169+
'test_proctoring_provider': {},
170+
},
171+
FEATURES=FEATURES_WITH_EXAM_SETTINGS_ENABLED,
172+
)
173+
@ddt.data(
174+
"advanced_settings_handler",
175+
"course_handler",
176+
)
177+
def test_invalid_provider_alert(self, page_handler):
178+
"""
179+
An alert should appear if the course has a proctoring provider that is not valid.
180+
"""
181+
# create an error by setting an invalid proctoring provider
182+
self.course.proctoring_provider = 'invalid_provider'
183+
self.course.enable_proctored_exams = True
184+
self.save_course()
185+
186+
url = reverse_course_url(page_handler, self.course.id)
187+
resp = self.client.get(url, HTTP_ACCEPT='text/html')
188+
alert_text = self._get_exam_settings_alert_text(resp.content)
189+
assert (
190+
'This course has proctored exam settings that are incomplete or invalid.'
191+
in alert_text
192+
)
193+
assert (
194+
'The proctoring provider configured for this course, \'invalid_provider\', is not valid.'
195+
in alert_text
196+
)
197+
165198
@ddt.data(
166199
"advanced_settings_handler",
167200
"course_handler",

cms/djangoapps/models/settings/course_metadata.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,18 +490,31 @@ def validate_proctoring_settings(cls, block, settings_dict, user):
490490
enable_proctoring = block.enable_proctored_exams
491491

492492
if enable_proctoring:
493+
494+
if proctoring_provider_model:
495+
proctoring_provider = proctoring_provider_model.get('value')
496+
else:
497+
proctoring_provider = block.proctoring_provider
498+
499+
# If the proctoring provider stored in the course block no longer
500+
# matches the available providers for this instance, show an error
501+
if proctoring_provider not in available_providers:
502+
message = (
503+
f'The proctoring provider configured for this course, \'{proctoring_provider}\', is not valid.'
504+
)
505+
errors.append({
506+
'key': 'proctoring_provider',
507+
'message': message,
508+
'model': proctoring_provider_model
509+
})
510+
493511
# Require a valid escalation email if Proctortrack is chosen as the proctoring provider
494512
escalation_email_model = settings_dict.get('proctoring_escalation_email')
495513
if escalation_email_model:
496514
escalation_email = escalation_email_model.get('value')
497515
else:
498516
escalation_email = block.proctoring_escalation_email
499517

500-
if proctoring_provider_model:
501-
proctoring_provider = proctoring_provider_model.get('value')
502-
else:
503-
proctoring_provider = block.proctoring_provider
504-
505518
missing_escalation_email_msg = 'Provider \'{provider}\' requires an exam escalation contact.'
506519
if proctoring_provider_model and proctoring_provider == 'proctortrack':
507520
if not escalation_email:

0 commit comments

Comments
 (0)