feat: implement HTMX support for exam question navigation and flagging functionality

This commit is contained in:
Ross
2026-07-06 11:34:58 +01:00
parent 94b08c5c21
commit b13261c302
7 changed files with 564 additions and 107 deletions
+42 -5
View File
@@ -117,6 +117,8 @@ def test_exams(db, client):
},
)
# Request the full page which now loads the fragment via HTMX;
# fetch the fragment endpoint directly to get the form and CSRF token.
cid_take_res = client.get(question_url)
if cid_user in exam_tester.invalid_users:
@@ -125,12 +127,47 @@ def test_exams(db, client):
else:
assert cid_take_res.status_code == HTTPStatus.OK
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
# The full page should include the HTMX container which will load
# the fragment client-side. Assert the container exists and has an
# hx-get attribute pointing to a fragment endpoint.
main_soup = BeautifulSoup(cid_take_res.content, "html.parser")
container = main_soup.find("div", attrs={"id": "question-fragment"})
assert container is not None, "Missing #question-fragment container"
hxget = container.get("hx-get") or container.get("data-hx-get")
assert hxget and "take_fragment" in hxget, f"Container hx-get not pointing to fragment: {hxget}"
# Extract csrftoken
csrftoken = cid_take_soup.find(
"input", attrs={"name": "csrfmiddlewaretoken"}
)["value"]
# Build fragment URL and fetch it to obtain CSRF token and controls
if exam_tester.testing_cid_user:
frag_url = reverse(
f"{APP_NAME}:exam_take_fragment",
kwargs={
"pk": exam.pk,
"sk": n,
"cid": exam_tester.current_user.cid,
"passcode": exam_tester.current_user.passcode,
},
)
else:
frag_url = reverse(
f"{APP_NAME}:exam_take_fragment_user",
kwargs={
"pk": exam.pk,
"sk": n,
},
)
frag_res = client.get(frag_url)
assert frag_res.status_code == HTTPStatus.OK
cid_take_soup = BeautifulSoup(frag_res.content, "html.parser")
# Extract csrftoken from fragment
csrftoken = cid_take_soup.find("input", attrs={"name": "csrfmiddlewaretoken"})["value"]
# Ensure fragment contains the question stem and answer list
assert "test question stem" in frag_res.text
# check answer choices exist with data-ans attributes
assert cid_take_soup.find("li", attrs={"data-ans": "a"}), "Missing answer choice a in fragment"
assert "question a text" in frag_res.text
# Send answers (all TRUE)
post_json = {
"csrfmiddlewaretoken": csrftoken,