Files
penracourses/shorts/tests/test_url_smoke.py
T
2026-06-10 22:05:12 +01:00

152 lines
6.4 KiB
Python

import pytest
import tempfile
from django.urls import reverse
from django.contrib.auth.models import Group, User
from django.test import Client
SAFE_STATUS_CODES = {200, 301, 302, 303, 403, 404, 405}
@pytest.fixture
def candidate_client(db):
user = User.objects.create_user(username="candidate", password="password", email="candidate@test.com")
client = Client()
client.force_login(user)
return client
@pytest.fixture
def superuser_client(db):
user = User.objects.create_superuser(username="superuser", password="password", email="superuser@test.com")
for group_name in ["shorts_checker", "cid_user_manager"]:
g, _ = Group.objects.get_or_create(name=group_name)
user.groups.add(g)
client = Client()
client.force_login(user)
return client
@pytest.fixture
def anonymous_client(db):
return Client()
@pytest.fixture
def smoke_data(db, settings, tmp_path):
from shorts.models import Question, QuestionImage, Exam, UserAnswer, QuestionFinding
from rapids.models import Examination
settings.MEDIA_ROOT = str(tmp_path)
create_user = User.objects.create_user(username="smoke_user", email="smoke_user@test.com")
exm_name, _ = Examination.objects.get_or_create(examination="Test Examination")
question = Question.objects.create(
history="Test History",
marking_guidance="Test Guidance",
)
question.examination.add(exm_name)
# Mocking image
image = tempfile.NamedTemporaryFile(
dir=settings.MEDIA_ROOT, suffix=".jpg", delete=False
)
image.flush()
image._committed = True
image.write(b"12345ABCD")
image.seek(0)
q_image = QuestionImage(image=image.name, question=question)
q_image.save()
exam = Exam.objects.create(
name="Test Shorts Exam",
exam_mode=True,
active=True
)
exam.author.add(create_user)
from shorts.models import ExamQuestionDetail
ExamQuestionDetail.objects.create(exam=exam, question=question, sort_order=1)
user_answer = UserAnswer.objects.create(
user=create_user,
exam=exam,
question=question,
answer="testanswer",
score=2,
)
finding = QuestionFinding.objects.create(
question=question,
description="Test Finding",
)
return {
"question": question,
"exam": exam,
"user_answer": user_answer,
"finding": finding,
}
URL_SPECS = [
("shorts:question_viewer", None),
("shorts:question_view", None),
("shorts:question_json", lambda d: {"pk": d["question"].pk}),
("shorts:question_json_unbased", lambda d: {"pk": d["question"].pk}),
("shorts:question_save_annotation", lambda d: {"pk": d["question"].pk}),
("shorts:question_split", lambda d: {"pk": d["question"].pk}),
("shorts:question_clone", lambda d: {"pk": d["question"].pk}),
("shorts:question_delete", lambda d: {"pk": d["question"].pk}),
("shorts:question_anonymise_dicom", lambda d: {"pk": d["question"].pk}),
("shorts:question_add_exam", lambda d: {"question_id": d["question"].pk}),
("shorts:combine_images_side_by_side", lambda d: {"question_id": d["question"].pk}),
("shorts:mark_answer", lambda d: {"exam_id": d["exam"].pk, "question_number": 0, "answer_id": d["user_answer"].pk}),
("shorts:mark_answer_override", lambda d: {"exam_id": d["exam"].pk, "question_number": 0, "answer_id": d["user_answer"].pk}),
("shorts:mark", lambda d: {"exam_pk": d["exam"].pk, "sk": 0}),
("shorts:mark_all", lambda d: {"exam_pk": d["exam"].pk, "sk": 0}),
("shorts:mark_review", lambda d: {"exam_pk": d["exam"].pk, "sk": 0}),
("shorts:exam_markers", lambda d: {"pk": d["exam"].pk}),
("shorts:exam_groups_edit", lambda d: {"pk": d["exam"].pk}),
("shorts:exam_authors", lambda d: {"pk": d["exam"].pk}),
("shorts:exam_create", None),
("shorts:exam_clone", lambda d: {"exam_id": d["exam"].pk}),
("shorts:exam_update", lambda d: {"pk": d["exam"].pk}),
("shorts:exam_delete", lambda d: {"pk": d["exam"].pk}),
("shorts:question_create", None),
("shorts:question_create_exam", lambda d: {"pk": d["exam"].pk}),
("shorts:question_update", lambda d: {"pk": d["question"].pk}),
("shorts:question_sample_answers", lambda d: {"pk": d["question"].pk}),
("shorts:user_answer_table_view", None),
("shorts:user_answer_view", lambda d: {"pk": d["user_answer"].pk}),
("shorts:user_answer_delete", lambda d: {"pk": d["user_answer"].pk}),
("shorts:question_findings", lambda d: {"question_id": d["question"].pk}),
("shorts:add_finding", None),
("shorts:delete_finding", lambda d: {"pk": d["finding"].pk}),
("shorts:question_edit_finding", lambda d: {"question_id": d["question"].pk, "finding_pk": d["finding"].pk}),
("shorts:index", None),
("shorts:help", None),
]
@pytest.mark.django_db
@pytest.mark.parametrize("url_name, kwargs_lambda", URL_SPECS)
def test_url_smoke_anonymous(anonymous_client, smoke_data, url_name, kwargs_lambda):
kwargs = kwargs_lambda(smoke_data) if kwargs_lambda else None
url = reverse(url_name, kwargs=kwargs)
response = anonymous_client.get(url, follow=False)
assert response.status_code != 500, f"500 Server Error on {url_name} ({url}) for Anonymous"
assert response.status_code in {200, 302, 400, 403, 404, 405}, f"Unexpected status code {response.status_code} on {url_name} for Anonymous"
@pytest.mark.django_db
@pytest.mark.parametrize("url_name, kwargs_lambda", URL_SPECS)
def test_url_smoke_candidate(candidate_client, smoke_data, url_name, kwargs_lambda):
kwargs = kwargs_lambda(smoke_data) if kwargs_lambda else None
url = reverse(url_name, kwargs=kwargs)
response = candidate_client.get(url, follow=False)
assert response.status_code != 500, f"500 Server Error on {url_name} ({url}) for Candidate"
assert response.status_code in SAFE_STATUS_CODES or response.status_code == 400, f"Unexpected status code {response.status_code} on {url_name} for Candidate"
@pytest.mark.django_db
@pytest.mark.parametrize("url_name, kwargs_lambda", URL_SPECS)
def test_url_smoke_superuser(superuser_client, smoke_data, url_name, kwargs_lambda):
kwargs = kwargs_lambda(smoke_data) if kwargs_lambda else None
url = reverse(url_name, kwargs=kwargs)
response = superuser_client.get(url, follow=False)
assert response.status_code != 500, f"500 Server Error on {url_name} ({url}) for Superuser"
assert response.status_code in {200, 301, 302, 303, 400, 403, 404, 405}, f"Unexpected status code {response.status_code} on {url_name} for Superuser"