Skip to content

Commit

Permalink
test: staff unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Zacharis278 committed Aug 15, 2023
1 parent 55cc889 commit 951ff73
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
64 changes: 53 additions & 11 deletions edx_exams/apps/api/v1/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from edx_exams.apps.api.test_utils import ExamsAPITestCase
from edx_exams.apps.core.exam_types import get_exam_type
from edx_exams.apps.core.exceptions import ExamAttemptOnPastDueExam, ExamIllegalStatusTransition
from edx_exams.apps.core.models import CourseExamConfiguration, Exam, ExamAttempt, ProctoringProvider
from edx_exams.apps.core.models import CourseExamConfiguration, CourseStaffRole, Exam, ExamAttempt, ProctoringProvider
from edx_exams.apps.core.statuses import ExamAttemptStatus
from edx_exams.apps.core.test_utils.factories import (
AssessmentControlResultFactory,
Expand Down Expand Up @@ -100,6 +100,14 @@ def test_auth_failures(self):
random_user = UserFactory()
self.get_response(random_user, [], 403)

def test_course_staff_access(self):
"""
Verify course staff can access endpoint
"""
course_staff_user = UserFactory()
CourseStaffRole.objects.create(user=course_staff_user, course_id=self.course_id)
self.get_response(course_staff_user, [], 200)

def test_exam_empty_exam_list(self):
"""
Test that exams not included in request are marked as inactive
Expand Down Expand Up @@ -342,6 +350,17 @@ def test_patch_auth_failures(self):
response = self.patch_api(random_user, {})
self.assertEqual(403, response.status_code)

def test_course_staff_write_access(self):
"""
Verify course staff have write access
"""
course_staff_user = UserFactory()
CourseStaffRole.objects.create(user=course_staff_user, course_id=self.course_id)
response = self.patch_api(course_staff_user, {
'provider': None,
})
self.assertEqual(204, response.status_code)

def test_patch_invalid_data(self):
"""
Assert that endpoint returns 400 if provider is missing
Expand Down Expand Up @@ -1083,7 +1102,8 @@ def setUp(self):
)

self.non_staff_user = UserFactory()
self.staff_user = UserFactory(is_staff=True)
self.course_staff_user = UserFactory()
CourseStaffRole.objects.create(user=self.course_staff_user, course_id=self.exam.course_id)

def delete_api(self, user, attempt_id):
"""
Expand Down Expand Up @@ -1181,13 +1201,14 @@ def test_put_staff_update_exam_attempt(self, action, expected_status, mock_updat

mock_update_attempt_status.return_value = attempt.id

response = self.put_api(self.staff_user, attempt.id, {'action': action})
response = self.put_api(self.course_staff_user, attempt.id, {'action': action})
self.assertEqual(response.status_code, 200)
mock_update_attempt_status.assert_called_once_with(attempt.id, expected_status)

def test_put_learner_verify(self):
"""
Test that a learner account cannot verify an attempt
but course staff can
"""
# create exam attempt for user
attempt = ExamAttemptFactory(
Expand All @@ -1198,6 +1219,9 @@ def test_put_learner_verify(self):
response = self.put_api(self.non_staff_user, attempt.id, {'action': 'verify'})
self.assertEqual(response.status_code, 400)

response = self.put_api(self.course_staff_user, attempt.id, {'action': 'verify'})
self.assertEqual(response.status_code, 200)

@patch('edx_exams.apps.api.v1.views.update_attempt_status')
def test_put_exception_raised(self, mock_update_attempt_status):
"""
Expand Down Expand Up @@ -1309,7 +1333,7 @@ def test_staff_delete_attempt(self):
exam=self.exam,
)

response = self.delete_api(self.staff_user, attempt.id)
response = self.delete_api(self.course_staff_user, attempt.id)
self.assertEqual(response.status_code, 204)
with self.assertRaises(ExamAttempt.DoesNotExist):
attempt.refresh_from_db()
Expand All @@ -1318,7 +1342,7 @@ def test_delete_attempt_with_bad_attempt_id(self):
"""
Test that a bad attempt ID returns 400
"""
response = self.delete_api(self.staff_user, 9999999)
response = self.delete_api(self.course_staff_user, 9999999)
self.assertEqual(response.status_code, 400)


Expand All @@ -1329,7 +1353,8 @@ class ExamAttemptListViewTests(ExamsAPITestCase):
def setUp(self):
super().setUp()

CourseExamConfigurationFactory.create()
config = CourseExamConfigurationFactory.create()
self.course_id = config.course_id

self.exam_1 = ExamFactory.create()
self.exam_2 = ExamFactory.create()
Expand All @@ -1341,19 +1366,29 @@ def get_api(self, exam_id, user=None, page_limit=20):
user = user or self.user
headers = self.build_jwt_headers(user)
url = reverse(
'api:v1:instructor-attempts-list'
'api:v1:instructor-attempts-list',
kwargs={'course_id': self.course_id}
)

return self.client.get(f'{url}?exam_id={exam_id}&limit={page_limit}', **headers)

def test_requires_staff_user(self):
"""
Test that only staff users can access this endpoint
Users that are neither staff nor course staff access this endpoint
"""
non_staff_user = UserFactory.create()
response = self.get_api(self.exam_1.id, user=non_staff_user)
self.assertEqual(response.status_code, 403)

def test_course_staff_access(self):
"""
Course staff can access this endpoint
"""
course_staff_user = UserFactory.create()
CourseStaffRole.objects.create(user=course_staff_user, course_id=self.course_id)
response = self.get_api(self.exam_1.id, user=course_staff_user)
self.assertEqual(response.status_code, 200)

def test_get_attempt_list_response_data(self):
"""
Test that a list of attempts includes the expected fields
Expand Down Expand Up @@ -1426,17 +1461,24 @@ def test_get_attempt_list_response_pagination(self):

response = self.get_api(self.exam_1.id, page_limit=5)
next_url = response.data.get('next')
self.assertEqual(next_url, 'http://testserver/api/v1/instructor_view/attempts?exam_id=1&limit=5&offset=5')
self.assertEqual(
next_url,
f'http://testserver/api/v1/instructor_view/course_id/{self.course_id}/attempts?exam_id=1&limit=5&offset=5',
)
self.assertEqual(response.data.get('count'), 12)
self.assertEqual(len(response.data.get('results')), 5)

headers = self.build_jwt_headers(self.user)
response = self.client.get(next_url, **headers)

next_url = response.data.get('next')
self.assertEqual(next_url, 'http://testserver/api/v1/instructor_view/attempts?exam_id=1&limit=5&offset=10')
self.assertEqual(
response.data.get('previous'), 'http://testserver/api/v1/instructor_view/attempts?exam_id=1&limit=5'
next_url,
f'http://testserver/api/v1/instructor_view/course_id/{self.course_id}/attempts?exam_id=1&limit=5&offset=10',
)
self.assertEqual(
response.data.get('previous'),
f'http://testserver/api/v1/instructor_view/course_id/{self.course_id}/attempts?exam_id=1&limit=5',
)
self.assertEqual(response.data.get('count'), 12)
self.assertEqual(len(response.data.get('results')), 5)
Expand Down
13 changes: 9 additions & 4 deletions edx_exams/apps/lti/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from lti_consumer.models import LtiConfiguration, LtiProctoringConsumer

from edx_exams.apps.api.test_utils import ExamsAPITestCase, UserFactory
from edx_exams.apps.core.models import AssessmentControlResult
from edx_exams.apps.core.models import AssessmentControlResult, CourseStaffRole
from edx_exams.apps.core.statuses import ExamAttemptStatus
from edx_exams.apps.core.test_utils.factories import (
CourseExamConfigurationFactory,
Expand Down Expand Up @@ -609,6 +609,11 @@ def setUp(self):
lti_configuration_id=self.lti_configuration.id
),
)
self.course_staff_user = UserFactory()
CourseStaffRole.objects.create(
user=self.course_staff_user,
course_id=self.exam.course_id,
)

def _get_launch_url(self, exam_id):
return reverse('lti:instructor_tool', kwargs={'exam_id': exam_id})
Expand All @@ -617,16 +622,16 @@ def test_lti_launch(self, mock_create_launch_url):
"""
Test that the view calls get_lti_1p3_launch_start_url with the correct data.
"""
headers = self.build_jwt_headers(self.user)
headers = self.build_jwt_headers(self.course_staff_user)
response = self.client.get(self._get_launch_url(self.exam.id), **headers)

mock_create_launch_url.assert_called_with(
Lti1p3LaunchData(
user_id=self.user.id,
user_id=self.course_staff_user.id,
user_role='instructor',
config_id=self.lti_configuration.config_id,
resource_link_id=self.exam.resource_id,
external_user_id=str(self.user.anonymous_user_id),
external_user_id=str(self.course_staff_user.anonymous_user_id),
context_id=self.exam.course_id,
)
)
Expand Down

0 comments on commit 951ff73

Please sign in to comment.