feat: enhance exam user status handling and add autosave verification in tests

This commit is contained in:
Ross
2026-06-29 11:49:43 +01:00
parent 12014fbb23
commit 077c858024
3 changed files with 30 additions and 3 deletions
@@ -37,7 +37,13 @@
<td class="text-nowrap small {% if user_data.in_exam %}text-muted{% else %}text-dark{% endif %}">{{ user_data.end_time }}</td>
<td class="text-end">
<div class="btn-group" role="group">
<button class="btn btn-sm btn-outline-secondary" title="View details" hx-get="{% url exam.get_app_name|add:':exam_user_status' exam.id %}?cid={{ user_data.cid_user }}" hx-target="#history-modal .modal-body" data-bs-toggle="modal" data-bs-target="#history-modal"><i class="bi bi-eye"></i></button>
{% if user_data.cid_user %}
<button class="btn btn-sm btn-outline-secondary" title="View details" hx-get="{% url exam.get_app_name|add:':exam_user_status' exam.id %}?cid={{ user_data.cid_user.cid }}" hx-target="#history-modal .modal-body" data-bs-toggle="modal" data-bs-target="#history-modal"><i class="bi bi-eye"></i></button>
<a class="btn btn-sm btn-outline-success" href="{% url exam.get_app_name|add:':exam_scores_cid_user_admin' exam.id user_data.cid_user.cid %}" target="_blank" rel="noopener" title="View candidate answers"><i class="bi bi-file-earmark-text"></i></a>
{% else %}
<button class="btn btn-sm btn-outline-secondary" title="View details" hx-get="{% url exam.get_app_name|add:':exam_user_status' exam.id %}?user_id={{ user_data.user_user.id }}" hx-target="#history-modal .modal-body" data-bs-toggle="modal" data-bs-target="#history-modal"><i class="bi bi-eye"></i></button>
<a class="btn btn-sm btn-outline-success" href="{% url exam.get_app_name|add:':exam_scores_user_admin' exam.id user_data.user_user.id %}" target="_blank" rel="noopener" title="View candidate answers"><i class="bi bi-file-earmark-text"></i></a>
{% endif %}
{% if request.user.is_superuser or request.user.is_staff %}
<a class="btn btn-sm btn-outline-primary" href="{% url 'admin:generic_ciduserexam_change' user_data.pk %}" target="_blank" rel="noopener" title="Edit submission in admin"><i class="bi bi-pencil-square"></i></a>
{% endif %}
+22 -2
View File
@@ -2639,13 +2639,27 @@ class ExamViews(View, LoginRequiredMixin):
return self.exam_user_status(request, pk, user_id=user_id)
def exam_user_status(self, request, pk, cid=None, user_id=None):
# TODO: add filtering by user / cid
exam = get_object_or_404(self.Exam, pk=pk)
# Restrict just to exam authors
if request.user not in exam.author.all():
raise PermissionDenied
# Robustly parse parameters from GET query string
get_cid = request.GET.get("cid")
get_user_id = request.GET.get("user_id")
if get_cid not in (None, "", "None"):
try:
cid = int(get_cid)
except ValueError:
pass
if get_user_id not in (None, "", "None"):
try:
user_id = int(get_user_id)
except ValueError:
pass
if cid is not None:
statuses = exam.exam_user_status.filter(cid_user_exam__cid_user__cid=cid)
elif user_id is not None:
@@ -3477,7 +3491,13 @@ class ExamViews(View, LoginRequiredMixin):
cid_user=c, start_time=t
)
in_progress = request.POST.get("in_progress") == "true"
if not in_progress:
if in_progress:
exam.exam_user_status.create(
cid_user_exam=cid_user_exam,
status="autosaved",
extra="autosaved {} answers".format(n),
)
else:
exam.exam_user_status.create(
cid_user_exam=cid_user_exam,
status="submitted",
+1
View File
@@ -73,6 +73,7 @@ def test_autosubmit_in_progress(client, test_setup):
assert cid_user_exam.end_time is None
assert cid_user_exam.completed is False
assert not ExamUserStatus.objects.filter(cid_user_exam=cid_user_exam, status="submitted").exists()
assert ExamUserStatus.objects.filter(cid_user_exam=cid_user_exam, status="autosaved").exists()
def test_final_submit(client, test_setup):
exam = test_setup["exam"]