Unverified Commit a9aeb462 by Rabia Iftikhar Committed by GitHub

Merge pull request #391 from edx/ri/EDUCATOR-1648

EDUCATOR-1648 give proctored exams access to course staff
parents 580c32ad 4ca93ade
......@@ -353,12 +353,12 @@ def add_allowance_for_user(exam_id, user_info, key, value):
emit_event(exam, 'allowance.{action}'.format(action=action), override_data=data)
def get_allowances_for_course(course_id, timed_exams_only=False):
def get_allowances_for_course(course_id):
"""
Get all the allowances for the course.
"""
student_allowances = ProctoredExamStudentAllowance.get_allowances_for_course(
course_id, timed_exams_only=timed_exams_only
course_id
)
return [ProctoredExamStudentAllowanceSerializer(allowance).data for allowance in student_allowances]
......
......@@ -394,27 +394,20 @@ class ProctoredExamStudentAttemptManager(models.Manager):
exam_attempt_obj = None
return exam_attempt_obj
def get_all_exam_attempts(self, course_id, timed_exams_only=False):
def get_all_exam_attempts(self, course_id):
"""
Returns the Student Exam Attempts for the given course_id.
"""
filtered_query = Q(proctored_exam__course_id=course_id)
if timed_exams_only:
filtered_query = filtered_query & Q(proctored_exam__is_proctored=False)
return self.filter(filtered_query).order_by('-created')
def get_filtered_exam_attempts(self, course_id, search_by, timed_exams_only=False):
def get_filtered_exam_attempts(self, course_id, search_by):
"""
Returns the Student Exam Attempts for the given course_id filtered by search_by.
"""
filtered_query = Q(proctored_exam__course_id=course_id) & (
Q(user__username__contains=search_by) | Q(user__email__contains=search_by)
)
if timed_exams_only:
filtered_query = filtered_query & Q(proctored_exam__is_proctored=False)
return self.filter(filtered_query).order_by('-created') # pylint: disable=no-member
def get_proctored_exam_attempts(self, course_id, username):
......@@ -720,14 +713,11 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
verbose_name = 'proctored allowance'
@classmethod
def get_allowances_for_course(cls, course_id, timed_exams_only=False):
def get_allowances_for_course(cls, course_id):
"""
Returns all the allowances for a course.
"""
filtered_query = Q(proctored_exam__course_id=course_id)
if timed_exams_only:
filtered_query = filtered_query & Q(proctored_exam__is_proctored=False)
return cls.objects.filter(filtered_query)
@classmethod
......
......@@ -409,7 +409,7 @@ class ProctoredExamApiTests(ProctoredExamTestCase):
Test to get all the allowances for a course.
"""
allowance = self._add_allowance_for_user()
course_allowances = get_allowances_for_course(self.course_id, False)
course_allowances = get_allowances_for_course(self.course_id)
self.assertEqual(len(course_allowances), 1)
self.assertEqual(course_allowances[0]['proctored_exam']['course_id'], allowance.proctored_exam.course_id)
......
......@@ -1190,11 +1190,10 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
response_data = json.loads(response.content)
self.assertEqual(len(response_data['proctored_exam_attempts']), 1)
def test_exam_attempts_not_staff(self):
def test_exam_attempts_not_global_staff(self):
"""
Test to get the exam attempts in a course as a not
staff user but still we get the timed exams attempts
but not the proctored exam attempts
Test to get both timed and proctored exam attempts
in a course as a course staff
"""
# Create an timed_exam.
timed_exam = ProctoredExam.objects.create(
......@@ -1241,11 +1240,15 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
# we should only get the timed exam attempt in this case
# so the len should be 1
self.assertEqual(len(response_data['proctored_exam_attempts']), 1)
# assert that both timed and proctored exam attempts are in response data
# so the len should be 2
self.assertEqual(len(response_data['proctored_exam_attempts']), 2)
self.assertEqual(
response_data['proctored_exam_attempts'][0]['proctored_exam']['is_proctored'],
proctored_exam.is_proctored
)
self.assertEqual(
response_data['proctored_exam_attempts'][1]['proctored_exam']['is_proctored'],
timed_exam.is_proctored
)
......@@ -2317,9 +2320,9 @@ class TestExamAllowanceView(LoggedInTestCase):
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
# we should only get the timed exam allowance
# We are not logged in as a global user
self.assertEqual(len(response_data), 1)
# assert that both timed and proctored exams allowance are in response data
# so the len should be 2
self.assertEqual(len(response_data), 2)
self.assertEqual(response_data[0]['proctored_exam']['course_id'], timed_exam.course_id)
self.assertEqual(response_data[0]['proctored_exam']['content_id'], timed_exam.content_id)
self.assertEqual(response_data[0]['key'], allowance_data['key'])
......
......@@ -611,18 +611,16 @@ class StudentProctoredExamAttemptsByCourse(AuthenticatedAPIView):
def get(self, request, course_id, search_by=None): # pylint: disable=unused-argument
"""
HTTP GET Handler. Returns the status of the exam attempt.
Course and Global staff can view both timed and proctored exam attempts.
"""
# course staff only views attempts of timed exams. edx staff can view both timed and proctored attempts.
time_exams_only = not request.user.is_staff
if search_by is not None:
exam_attempts = ProctoredExamStudentAttempt.objects.get_filtered_exam_attempts(
course_id, search_by, time_exams_only
course_id, search_by
)
attempt_url = reverse('edx_proctoring.proctored_exam.attempts.search', args=[course_id, search_by])
else:
exam_attempts = ProctoredExamStudentAttempt.objects.get_all_exam_attempts(
course_id, time_exams_only
course_id
)
attempt_url = reverse('edx_proctoring.proctored_exam.attempts.course', args=[course_id])
......@@ -701,13 +699,10 @@ class ExamAllowanceView(AuthenticatedAPIView):
def get(self, request, course_id): # pylint: disable=unused-argument
"""
HTTP GET handler. Get all allowances for a course.
Course and Global staff can view both timed and proctored exam allowances.
"""
# course staff only views attempts of timed exams. edx staff can view both timed and proctored attempts.
time_exams_only = not request.user.is_staff
result_set = get_allowances_for_course(
course_id=course_id,
timed_exams_only=time_exams_only
course_id=course_id
)
return Response(result_set)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment