Commit f39833c7 by Ari Rizzitano

expand proctored exam report to include violation summary

EDUCATOR-411

hit new report endpoint
EDUCATOR-411

bad syntax

python join != js join

csv headings list too long for task

fix string formatting

fix wrong set of keys

bump edx-proctoring to 1.2.0
parent f79e9da0
......@@ -1457,20 +1457,9 @@ def get_proctored_exam_results(request, course_id):
"""
get the proctored exam resultsreport for the particular course.
"""
query_features = [
'user_email',
'exam_name',
'attempt_code',
'allowed_time_limit_mins',
'is_sample_attempt',
'started_at',
'completed_at',
'status',
]
course_key = CourseKey.from_string(course_id)
report_type = _('proctored exam results')
lms.djangoapps.instructor_task.api.submit_proctored_exam_results_report(request, course_key, query_features)
lms.djangoapps.instructor_task.api.submit_proctored_exam_results_report(request, course_key)
success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type)
return JsonResponse({"status": success_status})
......
......@@ -12,7 +12,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.core.serializers.json import DjangoJSONEncoder
from django.core.urlresolvers import reverse
from django.db.models import Count, Q
from edx_proctoring.api import get_all_exam_attempts
from edx_proctoring.api import get_exam_violation_report
from opaque_keys.edx.keys import UsageKey
import xmodule.graders as xmgraders
......@@ -326,20 +326,30 @@ def get_proctored_exam_results(course_key, features):
"""
Return info about proctored exam results in a course as a dict.
"""
def extract_student(exam_attempt, features):
comment_statuses = ['Rules Violation', 'Suspicious']
def extract_details(exam_attempt, features):
"""
Build dict containing information about a single student exam_attempt.
"""
proctored_exam = dict(
(feature, exam_attempt.get(feature)) for feature in features if feature in exam_attempt
)
proctored_exam.update({'exam_name': exam_attempt.get('proctored_exam').get('exam_name')})
proctored_exam.update({'user_email': exam_attempt.get('user').get('email')})
for status in comment_statuses:
comment_list = exam_attempt.get(
'{status} Comments'.format(status=status),
[]
)
proctored_exam.update({
'{status} Count'.format(status=status): len(comment_list),
'{status} Comments'.format(status=status): '; '.join(comment_list),
})
return proctored_exam
exam_attempts = get_all_exam_attempts(course_key)
return [extract_student(exam_attempt, features) for exam_attempt in exam_attempts]
exam_attempts = get_exam_violation_report(course_key)
return [extract_details(exam_attempt, features) for exam_attempt in exam_attempts]
def coupon_codes_features(features, coupons_list, course_id):
......
......@@ -238,13 +238,17 @@ class TestAnalyticsBasic(ModuleStoreTestCase):
def test_get_student_exam_attempt_features(self):
query_features = [
'user_email',
'email',
'exam_name',
'allowed_time_limit_mins',
'is_sample_attempt',
'started_at',
'completed_at',
'status',
'Suspicious Count',
'Suspicious Comments',
'Rules Violation Count',
'Rules Violation Comments',
]
proctored_exam_id = create_exam(self.course_key, 'Test Content', 'Test Exam', 1)
......
......@@ -431,7 +431,7 @@ def submit_course_survey_report(request, course_key):
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
def submit_proctored_exam_results_report(request, course_key, features): # pylint: disable=invalid-name
def submit_proctored_exam_results_report(request, course_key): # pylint: disable=invalid-name
"""
Submits a task to generate a HTML File containing the executive summary report.
......@@ -439,7 +439,7 @@ def submit_proctored_exam_results_report(request, course_key, features): # pyli
"""
task_type = 'proctored_exam_results_report'
task_class = proctored_exam_results_csv
task_input = {'features': features}
task_input = {}
task_key = ""
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
......
......@@ -100,7 +100,23 @@ def upload_proctored_exam_results_report(_xmodule_instance_args, _entry_id, cour
task_progress.update_task_state(extra_meta=current_step)
# Compute result table and format it
query_features = _task_input.get('features')
query_features = [
'course_id',
'exam_name',
'username',
'email',
'attempt_code',
'allowed_time_limit_mins',
'is_sample_attempt',
'started_at',
'completed_at',
'status',
'review_status',
'Suspicious Count',
'Suspicious Comments',
'Rules Violation Count',
'Rules Violation Comments'
]
student_data = get_proctored_exam_results(course_id, query_features)
header, rows = format_dictlist(student_data, query_features)
......
......@@ -96,7 +96,7 @@ git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5
-e git+https://github.com/edx-solutions/xblock-google-drive.git@138e6fa0bf3a2013e904a085b9fed77dab7f3f21#egg=xblock-google-drive
git+https://github.com/edx/edx-user-state-client.git@1.0.1#egg=edx-user-state-client==1.0.1
git+https://github.com/edx/xblock-lti-consumer.git@v1.1.5#egg=lti_consumer-xblock==1.1.5
git+https://github.com/edx/edx-proctoring.git@1.1.0#egg=edx-proctoring==1.1.0
git+https://github.com/edx/edx-proctoring.git@1.2.0#egg=edx-proctoring==1.2.0
# Third Party XBlocks
git+https://github.com/open-craft/xblock-poll@7ba819b968fe8faddb78bb22e1fe7637005eb414#egg=xblock-poll==1.2.7
......
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