235 lines
6.8 KiB
Python
235 lines
6.8 KiB
Python
from http import HTTPStatus
|
|
import json
|
|
import os
|
|
from re import A
|
|
from django.conf import settings
|
|
import pytest
|
|
|
|
import tempfile
|
|
|
|
# from django.contrib.auth.models import User
|
|
from django.urls import reverse
|
|
|
|
from rich.pretty import pprint
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
from physics.views import GenericExamViews as PhysicsExamViews
|
|
|
|
from physics.models import Category, UserAnswer, Exam, Question
|
|
|
|
from generic.models import CidUser, CidUserGroup, UserUserGroup
|
|
from rad.test_helpers import AssertNotFound, ExamTester, create_cid_user_and_groups, create_exam
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
|
|
APP_NAME = "physics"
|
|
|
|
|
|
|
|
def create_category(db):
|
|
category = Category.objects.create(category="test category")
|
|
category.save()
|
|
category = Category.objects.create(category="test category 2")
|
|
category.save()
|
|
|
|
|
|
def create_question(exam, answer=None):
|
|
# Just assign random stuff
|
|
|
|
if answer is None:
|
|
answers = {
|
|
"a_answer": True,
|
|
"b_answer": False,
|
|
"c_answer": True,
|
|
"d_answer": False,
|
|
"e_answer": True,
|
|
}
|
|
else:
|
|
answers = {
|
|
"a_answer": answer[0],
|
|
"b_answer": answer[1],
|
|
"c_answer": answer[2],
|
|
"d_answer": answer[3],
|
|
"e_answer": answer[4],
|
|
}
|
|
|
|
question: Question = Question.objects.create(
|
|
stem="test question stem",
|
|
a="question a text",
|
|
a_feedback="question a feedback",
|
|
b="question b text",
|
|
b_feedback="question b feedback",
|
|
c="question c text",
|
|
c_feedback="question c feedback",
|
|
d="question d text",
|
|
d_feedback="question d feedback",
|
|
e="question e text",
|
|
e_feedback="question e feedback",
|
|
**answers,
|
|
)
|
|
question.exams.set([exam])
|
|
|
|
return question
|
|
|
|
|
|
def test_exams(db, client):
|
|
create_category(db)
|
|
|
|
exam_tester = ExamTester(db, client, APP_NAME, PhysicsExamViews)
|
|
|
|
exam_tester.create_questions(create_question)
|
|
|
|
users_tested = 1
|
|
|
|
# for cid_user in [cid_user_1001, cid_user_1000, user1, user2]:
|
|
for cid_user in exam_tester.all_users:
|
|
|
|
exam_tester.load_user(cid_user)
|
|
exam = exam_tester.exam
|
|
exam.active = False
|
|
exam.save()
|
|
|
|
exam_tester.check_active_exams(0)
|
|
|
|
|
|
exam.active = True
|
|
exam.publish_results = False
|
|
exam.save()
|
|
|
|
exam_tester.check_onsite_start_page()
|
|
|
|
#check_onsite_start_page
|
|
|
|
exam_tester.check_take_page()
|
|
|
|
exam_tester.check_take_overview(answered=0, total=3)
|
|
|
|
|
|
# Loop through questions again to test submissions
|
|
# All physics questions have 5 parts (and require a csrf token)
|
|
questions_len = len(exam_tester.generated_questions) - 1
|
|
for n, question in enumerate(exam_tester.generated_questions):
|
|
if exam_tester.testing_cid_user:
|
|
question_url = reverse(
|
|
f"{APP_NAME}:exam_take",
|
|
kwargs={
|
|
"pk": exam.pk,
|
|
"sk": n,
|
|
"cid": exam_tester.current_user.cid,
|
|
"passcode": exam_tester.current_user.passcode,
|
|
},
|
|
)
|
|
else:
|
|
question_url = reverse(
|
|
f"{APP_NAME}:exam_take_user",
|
|
kwargs={
|
|
"pk": exam.pk,
|
|
"sk": n,
|
|
},
|
|
)
|
|
|
|
cid_take_res = client.get(question_url)
|
|
|
|
if cid_user in exam_tester.invalid_users:
|
|
assert cid_take_res.status_code == HTTPStatus.NOT_FOUND
|
|
continue
|
|
else:
|
|
assert cid_take_res.status_code == HTTPStatus.OK
|
|
|
|
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
|
|
|
|
# Extract csrftoken
|
|
csrftoken = cid_take_soup.find(
|
|
"input", attrs={"name": "csrfmiddlewaretoken"}
|
|
)["value"]
|
|
# Send answers (all TRUE)
|
|
post_json = {
|
|
"csrfmiddlewaretoken": csrftoken,
|
|
"a": "on",
|
|
"b": "on",
|
|
"c": "on",
|
|
"d": "on",
|
|
"e": "on",
|
|
"next": "",
|
|
}
|
|
res = client.post(question_url, data=post_json)
|
|
|
|
next_button = cid_take_soup.find("button", attrs={"name": "next"})
|
|
|
|
# Our final question will trigger a bad request (it shouldn't show a next button)
|
|
# We currently do still save the form though....
|
|
if questions_len == n:
|
|
assert next_button == None
|
|
assert res.status_code == HTTPStatus.BAD_REQUEST
|
|
else:
|
|
assert next_button
|
|
assert res.status_code == HTTPStatus.FOUND
|
|
|
|
overview_button = cid_take_soup.find("button", attrs={"name": "finish"})
|
|
assert overview_button
|
|
|
|
previous_button = cid_take_soup.find("button", attrs={"name": "previous"})
|
|
|
|
if n > 0:
|
|
assert previous_button
|
|
else:
|
|
assert not previous_button
|
|
|
|
# Filter answer to the question we just submitted to
|
|
cid_user_answers = question.cid_user_answers.all()
|
|
|
|
assert len(cid_user_answers) == users_tested
|
|
|
|
if exam_tester.testing_cid_user:
|
|
cid_user_answer = cid_user_answers.filter(cid=exam_tester.current_user.cid)[0]
|
|
else:
|
|
cid_user_answer = cid_user_answers.filter(user=exam_tester.current_user)[0]
|
|
|
|
assert all(cid_user_answer.get_answers())
|
|
|
|
# Recheck the overview page (now that we have submitted answers)
|
|
exam_tester.check_take_overview(3, 3)
|
|
|
|
|
|
exam_tester.check_cid_scores_page()
|
|
|
|
|
|
exam_tester.check_cid_scores_user_page()
|
|
|
|
# The rest of the tests are for valid users
|
|
if exam_tester.current_user in exam_tester.invalid_users:
|
|
continue
|
|
|
|
# answer the final question
|
|
extra_question = exam_tester.generated_questions[-1]
|
|
if exam_tester.testing_cid_user:
|
|
cid_user_answer = UserAnswer(
|
|
question=extra_question,
|
|
a=True,
|
|
b=False,
|
|
c=True,
|
|
d=False,
|
|
e=True,
|
|
cid=cid_user.cid,
|
|
exam=exam,
|
|
)
|
|
else:
|
|
cid_user_answer = UserAnswer(
|
|
question=extra_question,
|
|
a=True,
|
|
b=False,
|
|
c=True,
|
|
d=False,
|
|
e=True,
|
|
user=exam_tester.current_user,
|
|
exam=exam,
|
|
)
|
|
cid_user_answer.save()
|
|
|
|
exam_tester.check_cid_scores_user_page2()
|
|
|
|
|
|
users_tested = users_tested + 1
|