improve test
This commit is contained in:
@@ -19,7 +19,7 @@ from physics.views import GenericExamViews as PhysicsExamViews
|
|||||||
from physics.models import Category, UserAnswer, Exam, Question
|
from physics.models import Category, UserAnswer, Exam, Question
|
||||||
|
|
||||||
from generic.models import CidUser, CidUserGroup, UserUserGroup
|
from generic.models import CidUser, CidUserGroup, UserUserGroup
|
||||||
from rad.test_helpers import AssertNotFound, create_cid_user_and_groups
|
from rad.test_helpers import AssertNotFound, ExamTester, create_cid_user_and_groups, create_exam
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
@@ -27,27 +27,6 @@ from django.contrib.auth.models import User
|
|||||||
APP_NAME = "physics"
|
APP_NAME = "physics"
|
||||||
|
|
||||||
|
|
||||||
def create_exam(db):
|
|
||||||
exam: Exam = PhysicsExamViews.Exam.objects.create(
|
|
||||||
name="Cid Exam", exam_mode=True, active=True
|
|
||||||
)
|
|
||||||
|
|
||||||
group1: CidUserGroup = CidUserGroup.objects.get(name="Group1")
|
|
||||||
usergroup1: UserUserGroup = UserUserGroup.objects.get(name="Group1")
|
|
||||||
|
|
||||||
exam.cid_user_groups.add(group1)
|
|
||||||
|
|
||||||
exam.valid_cid_users.add(*group1.ciduser_set.all())
|
|
||||||
|
|
||||||
# exam.valid_user_users.add(user1)
|
|
||||||
exam.valid_user_users.add(*usergroup1.users.all())
|
|
||||||
|
|
||||||
assert exam in group1.physics_cid_user_groups.all()
|
|
||||||
|
|
||||||
assert exam
|
|
||||||
|
|
||||||
return exam
|
|
||||||
|
|
||||||
|
|
||||||
def create_category(db):
|
def create_category(db):
|
||||||
category = Category.objects.create(category="test category")
|
category = Category.objects.create(category="test category")
|
||||||
@@ -96,193 +75,55 @@ def create_question(exam, answer=None):
|
|||||||
|
|
||||||
|
|
||||||
def test_exams(db, client):
|
def test_exams(db, client):
|
||||||
create_cid_user_and_groups(db)
|
|
||||||
exam = create_exam(db)
|
|
||||||
|
|
||||||
create_category(db)
|
create_category(db)
|
||||||
|
|
||||||
generated_questions = [
|
exam_tester = ExamTester(db, client, APP_NAME, PhysicsExamViews)
|
||||||
create_question(exam),
|
|
||||||
create_question(exam),
|
|
||||||
create_question(exam),
|
|
||||||
]
|
|
||||||
|
|
||||||
active_exams = client.get(reverse(f"{APP_NAME}:active_exams"))
|
exam_tester.create_questions(create_question)
|
||||||
assert active_exams.status_code == 200
|
|
||||||
assert len(json.loads(active_exams.content)["exams"]) == 0
|
|
||||||
|
|
||||||
cid_user_1001 = CidUser.objects.get(cid=1001)
|
|
||||||
cid_user_1000 = CidUser.objects.get(cid=1000)
|
|
||||||
cid_user_2001 = CidUser.objects.get(cid=2001)
|
|
||||||
|
|
||||||
user1 = User.objects.get(username="user1")
|
|
||||||
user2 = User.objects.get(username="user2")
|
|
||||||
|
|
||||||
users_tested = 1
|
users_tested = 1
|
||||||
|
|
||||||
# for cid_user in [cid_user_1001, cid_user_1000, user1, user2]:
|
# for cid_user in [cid_user_1001, cid_user_1000, user1, user2]:
|
||||||
for cid_user in [cid_user_1001, cid_user_1000, user1, user2]:
|
for cid_user in exam_tester.all_users:
|
||||||
if isinstance(cid_user, CidUser):
|
|
||||||
testing_cid_user = True
|
exam_tester.load_user(cid_user)
|
||||||
else:
|
exam = exam_tester.exam
|
||||||
testing_cid_user = False
|
exam.active = False
|
||||||
current_user = cid_user
|
exam.save()
|
||||||
client.force_login(cid_user)
|
|
||||||
|
exam_tester.check_active_exams(0)
|
||||||
|
|
||||||
|
|
||||||
exam.active = True
|
exam.active = True
|
||||||
exam.publish_results = False
|
exam.publish_results = False
|
||||||
exam.save()
|
exam.save()
|
||||||
start_page_res = client.get(
|
|
||||||
reverse(f"physics:exam_start", kwargs={"pk": exam.pk})
|
|
||||||
)
|
|
||||||
|
|
||||||
print(cid_user)
|
exam_tester.check_onsite_start_page()
|
||||||
|
|
||||||
# Check user access to the start page
|
#check_onsite_start_page
|
||||||
assert start_page_res.status_code == HTTPStatus.OK
|
|
||||||
start_page_soup = BeautifulSoup(start_page_res.content, "html.parser")
|
|
||||||
print(start_page_soup)
|
|
||||||
if testing_cid_user or cid_user in [user2]:
|
|
||||||
assert "Enter your CID and passcode" in str(start_page_soup)
|
|
||||||
else:
|
|
||||||
assert "Start Exam" in str(start_page_soup)
|
|
||||||
|
|
||||||
for n, question in enumerate(generated_questions):
|
exam_tester.check_take_page()
|
||||||
if testing_cid_user:
|
|
||||||
take_url = reverse(
|
|
||||||
f"physics:exam_take",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"sk": n,
|
|
||||||
"cid": cid_user.cid,
|
|
||||||
"passcode": cid_user.passcode,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
take_url = reverse(
|
|
||||||
f"physics:exam_take_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"sk": n,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
cid_take_res = client.get(take_url)
|
exam_tester.check_take_overview(answered=0, total=3)
|
||||||
|
|
||||||
# Check that users that have not been added cannot access the take pages
|
|
||||||
if cid_user in [user2]:
|
|
||||||
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")
|
|
||||||
|
|
||||||
# Check correct user is displayed
|
|
||||||
if testing_cid_user:
|
|
||||||
display_user = str(cid_user.cid)
|
|
||||||
else:
|
|
||||||
display_user = current_user.username
|
|
||||||
assert display_user in cid_take_soup.find("span", {"id": "user-id"}).string
|
|
||||||
|
|
||||||
# Check review mode alert not visible
|
|
||||||
assert cid_take_soup.find("div", {"class": "review-mode-alert"}) is None
|
|
||||||
|
|
||||||
# Check that relevant buttons are being displayed
|
|
||||||
assert cid_take_soup.find("button", {"name": "finish"}) is not None
|
|
||||||
|
|
||||||
if n < len(generated_questions) - 1:
|
|
||||||
assert cid_take_soup.find("button", {"name": "next"}) is not None
|
|
||||||
|
|
||||||
if n > 0:
|
|
||||||
assert cid_take_soup.find("button", {"name": "previous"}) is not None
|
|
||||||
|
|
||||||
assert cid_take_soup.find("span", {"id": "question-number"}).string == str(
|
|
||||||
n + 1
|
|
||||||
) # + 1 for 0 offset
|
|
||||||
assert cid_take_soup.find("span", {"id": "exam-length"}).string == str(
|
|
||||||
len(generated_questions)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check that stem text is displayed
|
|
||||||
assert (
|
|
||||||
cid_take_soup.find("span", {"id": "question-stem"}).string
|
|
||||||
== question.stem
|
|
||||||
)
|
|
||||||
|
|
||||||
assert cid_take_soup.find("label", {"for": "id_a"}).string == question.a
|
|
||||||
assert cid_take_soup.find("label", {"for": "id_b"}).string == question.b
|
|
||||||
assert cid_take_soup.find("label", {"for": "id_c"}).string == question.c
|
|
||||||
assert cid_take_soup.find("label", {"for": "id_d"}).string == question.d
|
|
||||||
assert cid_take_soup.find("label", {"for": "id_e"}).string == question.e
|
|
||||||
|
|
||||||
# As we haven't submitted any answers they should all be blank
|
|
||||||
assert (
|
|
||||||
cid_take_soup.find("input", {"type": "checkbox", "checked": True})
|
|
||||||
is None
|
|
||||||
)
|
|
||||||
|
|
||||||
if testing_cid_user:
|
|
||||||
take_overview_url = reverse(
|
|
||||||
f"physics:exam_take_overview",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"cid": cid_user.cid,
|
|
||||||
"passcode": cid_user.passcode,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
take_overview_url = reverse(
|
|
||||||
f"physics:exam_take_overview_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
cid_take_overview_res = client.get(take_overview_url)
|
|
||||||
|
|
||||||
# Check that users that have not been added cannot access the take pages
|
|
||||||
if cid_user in [user2]:
|
|
||||||
assert cid_take_overview_res.status_code == HTTPStatus.NOT_FOUND
|
|
||||||
else:
|
|
||||||
assert cid_take_overview_res.status_code == HTTPStatus.OK
|
|
||||||
|
|
||||||
cid_take_overview_soup = BeautifulSoup(
|
|
||||||
cid_take_overview_res.content, "html.parser"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
"0 out of 3 questions answered"
|
|
||||||
in cid_take_overview_soup.find(
|
|
||||||
"div", attrs={"class": "overview-text"}
|
|
||||||
).string
|
|
||||||
)
|
|
||||||
|
|
||||||
assert (
|
|
||||||
len(
|
|
||||||
cid_take_overview_soup.find_all(
|
|
||||||
"button", attrs={"class": "unanswered"}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
== 3
|
|
||||||
)
|
|
||||||
|
|
||||||
# Loop through questions again to test submissions
|
# Loop through questions again to test submissions
|
||||||
# All physics questions have 5 parts (and require a csrf token)
|
# All physics questions have 5 parts (and require a csrf token)
|
||||||
questions_len = len(generated_questions) - 1
|
questions_len = len(exam_tester.generated_questions) - 1
|
||||||
for n, question in enumerate(generated_questions):
|
for n, question in enumerate(exam_tester.generated_questions):
|
||||||
if testing_cid_user:
|
if exam_tester.testing_cid_user:
|
||||||
question_url = reverse(
|
question_url = reverse(
|
||||||
f"physics:exam_take",
|
f"{APP_NAME}:exam_take",
|
||||||
kwargs={
|
kwargs={
|
||||||
"pk": exam.pk,
|
"pk": exam.pk,
|
||||||
"sk": n,
|
"sk": n,
|
||||||
"cid": cid_user.cid,
|
"cid": exam_tester.current_user.cid,
|
||||||
"passcode": cid_user.passcode,
|
"passcode": exam_tester.current_user.passcode,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
question_url = reverse(
|
question_url = reverse(
|
||||||
f"physics:exam_take_user",
|
f"{APP_NAME}:exam_take_user",
|
||||||
kwargs={
|
kwargs={
|
||||||
"pk": exam.pk,
|
"pk": exam.pk,
|
||||||
"sk": n,
|
"sk": n,
|
||||||
@@ -291,7 +132,7 @@ def test_exams(db, client):
|
|||||||
|
|
||||||
cid_take_res = client.get(question_url)
|
cid_take_res = client.get(question_url)
|
||||||
|
|
||||||
if cid_user in [user2]:
|
if cid_user in exam_tester.invalid_users:
|
||||||
assert cid_take_res.status_code == HTTPStatus.NOT_FOUND
|
assert cid_take_res.status_code == HTTPStatus.NOT_FOUND
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -341,255 +182,29 @@ def test_exams(db, client):
|
|||||||
|
|
||||||
assert len(cid_user_answers) == users_tested
|
assert len(cid_user_answers) == users_tested
|
||||||
|
|
||||||
if testing_cid_user:
|
if exam_tester.testing_cid_user:
|
||||||
cid_user_answer = cid_user_answers.filter(cid=cid_user.cid)[0]
|
cid_user_answer = cid_user_answers.filter(cid=exam_tester.current_user.cid)[0]
|
||||||
else:
|
else:
|
||||||
cid_user_answer = cid_user_answers.filter(user=current_user)[0]
|
cid_user_answer = cid_user_answers.filter(user=exam_tester.current_user)[0]
|
||||||
|
|
||||||
assert all(cid_user_answer.get_answers())
|
assert all(cid_user_answer.get_answers())
|
||||||
|
|
||||||
# Recheck the overview page (now that we have submitted answers)
|
# Recheck the overview page (now that we have submitted answers)
|
||||||
if testing_cid_user:
|
exam_tester.check_take_overview(3, 3)
|
||||||
take_overview_url = reverse(
|
|
||||||
f"physics:exam_take_overview",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"cid": cid_user.cid,
|
|
||||||
"passcode": cid_user.passcode,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
take_overview_url = reverse(
|
|
||||||
f"physics:exam_take_overview_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
cid_take_overview_res = client.get(take_overview_url)
|
|
||||||
|
|
||||||
if cid_user in [user2]:
|
exam_tester.check_cid_scores_page()
|
||||||
assert cid_take_overview_res.status_code == HTTPStatus.NOT_FOUND
|
|
||||||
else:
|
|
||||||
assert cid_take_overview_res.status_code == HTTPStatus.OK
|
|
||||||
|
|
||||||
cid_take_overview_soup = BeautifulSoup(
|
|
||||||
cid_take_overview_res.content, "html.parser"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
"3 out of 3 questions answered"
|
|
||||||
in cid_take_overview_soup.find(
|
|
||||||
"div", attrs={"class": "overview-text"}
|
|
||||||
).string
|
|
||||||
)
|
|
||||||
|
|
||||||
assert (
|
exam_tester.check_cid_scores_user_page()
|
||||||
len(
|
|
||||||
cid_take_overview_soup.find_all(
|
|
||||||
"button", attrs={"class": "unanswered"}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
== 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if testing_cid_user:
|
# The rest of the tests are for valid users
|
||||||
# Get overview scores page (invalid passcode)
|
if exam_tester.current_user in exam_tester.invalid_users:
|
||||||
AssertNotFound(
|
|
||||||
client,
|
|
||||||
reverse(
|
|
||||||
f"cid_scores", kwargs={"cid": cid_user.cid, "passcode": "AAAA"}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
cid_scores_url = reverse(
|
|
||||||
f"cid_scores",
|
|
||||||
kwargs={"cid": cid_user.cid, "passcode": cid_user.passcode},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cid_scores_url = reverse(f"user_scores")
|
|
||||||
|
|
||||||
# Get overview scores page
|
|
||||||
cid_scores_res = client.get(cid_scores_url)
|
|
||||||
|
|
||||||
assert cid_scores_res.status_code == HTTPStatus.OK
|
|
||||||
|
|
||||||
cid_scores_soup = BeautifulSoup(cid_scores_res.content, "html.parser")
|
|
||||||
|
|
||||||
if cid_user in [user2]:
|
|
||||||
# page should load but we shouldn't be able to find the exam
|
|
||||||
with pytest.raises(AttributeError):
|
|
||||||
search_exam = (
|
|
||||||
cid_scores_soup.find("div", {"id": "exam-assigned"})
|
|
||||||
.find("ul", {"class": exam.app_name.lower()})
|
|
||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
search_exam = (
|
|
||||||
cid_scores_soup.find("div", {"id": "exam-assigned"})
|
|
||||||
.find("ul", {"class": exam.app_name.lower()})
|
|
||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
|
||||||
)
|
|
||||||
assert search_exam
|
|
||||||
assert exam.name in str(search_exam)
|
|
||||||
assert "Active" in str(search_exam)
|
|
||||||
# assert "Active" in assigned_exams # check it is active
|
|
||||||
|
|
||||||
invalid_exam = cid_scores_soup.find_all(
|
|
||||||
"li", attrs={"data-exam-id": exam.pk + 5}
|
|
||||||
)
|
|
||||||
assert not invalid_exam # Check we can't find an invalid exam
|
|
||||||
|
|
||||||
# Check that we have a results link
|
|
||||||
results_exam = (
|
|
||||||
cid_scores_soup.find("div", {"id": "exam-results"})
|
|
||||||
.find("ul", {"class": exam.app_name})
|
|
||||||
.find_all("li", attrs={"data-exam-id": exam.pk})
|
|
||||||
)
|
|
||||||
assert results_exam
|
|
||||||
assert exam.name in str(results_exam)
|
|
||||||
assert exam.name + " test" not in str(results_exam)
|
|
||||||
assert "Results Published" not in str(
|
|
||||||
results_exam
|
|
||||||
) # It should not be published yet
|
|
||||||
|
|
||||||
if testing_cid_user:
|
|
||||||
AssertNotFound(
|
|
||||||
client,
|
|
||||||
reverse(
|
|
||||||
f"{exam.app_name}:exam_scores_cid_user",
|
|
||||||
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": "AAAA"},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
AssertNotFound(
|
|
||||||
client,
|
|
||||||
reverse(
|
|
||||||
f"{exam.app_name}:exam_scores_cid_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"cid": cid_user_2001.cid,
|
|
||||||
"passcode": cid_user_2001.passcode,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
exam_scores_url = reverse(
|
|
||||||
f"{exam.app_name}:exam_scores_cid_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"cid": cid_user.cid,
|
|
||||||
"passcode": cid_user.passcode,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
exam_scores_url = reverse(
|
|
||||||
f"{exam.app_name}:exam_scores_user",
|
|
||||||
kwargs={"pk": exam.pk},
|
|
||||||
)
|
|
||||||
|
|
||||||
# Load the exam results page
|
|
||||||
cid_exam_scores_res = client.get(exam_scores_url)
|
|
||||||
|
|
||||||
if cid_user in [user2]:
|
|
||||||
assert cid_exam_scores_res.status_code == HTTPStatus.NOT_FOUND
|
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
assert cid_exam_scores_res.status_code == HTTPStatus.OK
|
|
||||||
|
|
||||||
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
|
||||||
|
|
||||||
# Check that we have an alert that exams are not published
|
|
||||||
alert = cid_exam_scores_soup.find("div", {"class": "alert"})
|
|
||||||
assert "Results are not currently published." in str(alert)
|
|
||||||
|
|
||||||
# Check that we are showing enough questions / answers
|
|
||||||
answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"})
|
|
||||||
assert len(answer_lis) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
submitted_answers = cid_exam_scores_soup.find_all(
|
|
||||||
"span", {"class": "submitted-user-answer"}
|
|
||||||
)
|
|
||||||
assert len(submitted_answers) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
for ans in submitted_answers:
|
|
||||||
assert ans.text.strip() == "True"
|
|
||||||
|
|
||||||
# Check no correct answers are shown
|
|
||||||
assert not cid_exam_scores_soup.find_all("span", {"class": "correct-answer"})
|
|
||||||
|
|
||||||
# Add another question to the exam
|
|
||||||
extra_question = create_question(exam)
|
|
||||||
generated_questions.append(extra_question)
|
|
||||||
|
|
||||||
# Load the exam results page (again)
|
|
||||||
cid_exam_scores_res = client.get(exam_scores_url)
|
|
||||||
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
|
||||||
|
|
||||||
answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"})
|
|
||||||
assert len(answer_lis) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
submitted_answers = cid_exam_scores_soup.find_all(
|
|
||||||
"span", {"class": "submitted-user-answer"}
|
|
||||||
)
|
|
||||||
assert len(submitted_answers) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
for ans in submitted_answers[:-5]:
|
|
||||||
assert ans.text.strip() == "True"
|
|
||||||
|
|
||||||
# The new question will not have any answers
|
|
||||||
for ans in submitted_answers[-5:]:
|
|
||||||
assert ans.text.strip() == ""
|
|
||||||
|
|
||||||
# Publish the results!
|
|
||||||
exam.publish_results = True
|
|
||||||
exam.save()
|
|
||||||
|
|
||||||
# Load the exam results page (again)
|
|
||||||
cid_exam_scores_res = client.get(exam_scores_url)
|
|
||||||
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
|
||||||
|
|
||||||
assert (
|
|
||||||
cid_exam_scores_soup.find("div", {"class": "alert"}) is None
|
|
||||||
) # Check our warning banner is gone
|
|
||||||
|
|
||||||
# Check that we are displaying the correct answers (correctly)
|
|
||||||
correct_answers = cid_exam_scores_soup.find_all(
|
|
||||||
"span", {"class": "correct-answer"}
|
|
||||||
)
|
|
||||||
assert len(correct_answers) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
n = 0
|
|
||||||
for question in generated_questions:
|
|
||||||
for ans in question.get_answers():
|
|
||||||
assert correct_answers[n].text.strip() == f"Correct answer: {ans}"
|
|
||||||
n = n + 1
|
|
||||||
|
|
||||||
submitted_answers = cid_exam_scores_soup.find_all(
|
|
||||||
"span", {"class": "submitted-user-answer"}
|
|
||||||
)
|
|
||||||
assert len(submitted_answers) == 5 * len(generated_questions)
|
|
||||||
|
|
||||||
for ans in submitted_answers[:-5]:
|
|
||||||
assert ans.text.strip() == "True"
|
|
||||||
|
|
||||||
# The new question will not have any answers
|
|
||||||
for ans in submitted_answers[-5:]:
|
|
||||||
assert ans.text.strip() == ""
|
|
||||||
|
|
||||||
assert (
|
|
||||||
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
|
||||||
.find("span", {"id": "total-score"})
|
|
||||||
.string
|
|
||||||
== "9"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
|
||||||
.find("span", {"id": "max-score"})
|
|
||||||
.string
|
|
||||||
== "20"
|
|
||||||
)
|
|
||||||
|
|
||||||
# answer the final question
|
# answer the final question
|
||||||
if testing_cid_user:
|
extra_question = exam_tester.generated_questions[-1]
|
||||||
|
if exam_tester.testing_cid_user:
|
||||||
cid_user_answer = UserAnswer(
|
cid_user_answer = UserAnswer(
|
||||||
question=extra_question,
|
question=extra_question,
|
||||||
a=True,
|
a=True,
|
||||||
@@ -608,54 +223,12 @@ def test_exams(db, client):
|
|||||||
c=True,
|
c=True,
|
||||||
d=False,
|
d=False,
|
||||||
e=True,
|
e=True,
|
||||||
user=current_user,
|
user=exam_tester.current_user,
|
||||||
exam=exam,
|
exam=exam,
|
||||||
)
|
)
|
||||||
cid_user_answer.save()
|
cid_user_answer.save()
|
||||||
|
|
||||||
cid_exam_scores_res = client.get(exam_scores_url)
|
exam_tester.check_cid_scores_user_page2()
|
||||||
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
|
||||||
|
|
||||||
# As we have answered correctly the new score should be increased by 5
|
|
||||||
assert (
|
|
||||||
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
|
||||||
.find("span", {"id": "total-score"})
|
|
||||||
.string
|
|
||||||
== "14"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check what happens when exam is not active
|
|
||||||
exam.active = False
|
|
||||||
exam.save()
|
|
||||||
|
|
||||||
start_page_res = client.get(
|
|
||||||
reverse(f"physics:exam_start", kwargs={"pk": exam.pk})
|
|
||||||
)
|
|
||||||
start_page_soup = BeautifulSoup(start_page_res.content, "html.parser")
|
|
||||||
|
|
||||||
assert "Exam is currently inactive" in start_page_soup.text
|
|
||||||
|
|
||||||
if testing_cid_user:
|
|
||||||
cid_take_url = reverse(
|
|
||||||
f"physics:exam_take",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"sk": 0,
|
|
||||||
"cid": cid_user.cid,
|
|
||||||
"passcode": cid_user.passcode,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cid_take_url = reverse(
|
|
||||||
f"physics:exam_take_user",
|
|
||||||
kwargs={
|
|
||||||
"pk": exam.pk,
|
|
||||||
"sk": 0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
cid_take_res = client.get(cid_take_url)
|
|
||||||
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
|
|
||||||
assert "Exam is currently inactive" in cid_take_soup.text
|
|
||||||
|
|
||||||
generated_questions.pop(-1).delete()
|
|
||||||
users_tested = users_tested + 1
|
users_tested = users_tested + 1
|
||||||
|
|||||||
+497
-4
@@ -1,12 +1,22 @@
|
|||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
import json
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
from generic.models import CidUser, CidUserGroup, UserUserGroup
|
from bs4 import BeautifulSoup
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from generic.models import CidUser, CidUserGroup, UserUserGroup, ExamBase
|
||||||
|
from generic.views import ExamViews
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
def AssertNotFound(client, url):
|
def AssertNotFound(client, url):
|
||||||
"""Helper to quickly test for urls that should return a 404 (NOT FOUND) error"""
|
"""Helper to quickly test for urls that should return a 404 (NOT FOUND) error"""
|
||||||
response = client.get(url)
|
response = client.get(url)
|
||||||
assert response.status_code == HTTPStatus.NOT_FOUND, f"Response content: {response.content}"
|
assert (
|
||||||
|
response.status_code == HTTPStatus.NOT_FOUND
|
||||||
|
), f"Response content: {response.content}"
|
||||||
|
|
||||||
|
|
||||||
def create_cid_user_and_groups(db):
|
def create_cid_user_and_groups(db):
|
||||||
@@ -21,9 +31,492 @@ def create_cid_user_and_groups(db):
|
|||||||
assert cid_user_1001.cid == 1001
|
assert cid_user_1001.cid == 1001
|
||||||
|
|
||||||
# Create UserUsers
|
# Create UserUsers
|
||||||
user1 = User.objects.create_user(username="user1", email="test@email.com", password="test1234")
|
user1 = User.objects.create_user(
|
||||||
user2 = User.objects.create_user(username="user2", email="test2@email.com", password="test1234")
|
username="user1", email="test@email.com", password="test1234"
|
||||||
|
)
|
||||||
|
user2 = User.objects.create_user(
|
||||||
|
username="user2", email="test2@email.com", password="test1234"
|
||||||
|
)
|
||||||
usergroup1 = UserUserGroup.objects.create(name="Group1")
|
usergroup1 = UserUserGroup.objects.create(name="Group1")
|
||||||
usergroup1.users.add(user1)
|
usergroup1.users.add(user1)
|
||||||
usergroup2 = UserUserGroup.objects.create(name="Group2")
|
usergroup2 = UserUserGroup.objects.create(name="Group2")
|
||||||
usergroup2.users.add(user2)
|
usergroup2.users.add(user2)
|
||||||
|
|
||||||
|
|
||||||
|
def create_exam(db, ExamViews: ExamViews):
|
||||||
|
exam: ExamBase = ExamViews.Exam.objects.create(
|
||||||
|
name="Cid Exam", exam_mode=True, active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
cidgroup1: CidUserGroup = CidUserGroup.objects.get(name="Group1")
|
||||||
|
usergroup1: UserUserGroup = UserUserGroup.objects.get(name="Group1")
|
||||||
|
|
||||||
|
exam.cid_user_groups.add(cidgroup1)
|
||||||
|
|
||||||
|
exam.valid_cid_users.add(*cidgroup1.ciduser_set.all())
|
||||||
|
|
||||||
|
# exam.valid_user_users.add(user1)
|
||||||
|
exam.valid_user_users.add(*usergroup1.users.all())
|
||||||
|
|
||||||
|
assert exam
|
||||||
|
|
||||||
|
return exam
|
||||||
|
|
||||||
|
|
||||||
|
class ExamTester:
|
||||||
|
def __init__(self, db, client, app_name, ExamViews) -> None:
|
||||||
|
self.db = db
|
||||||
|
self.client = client
|
||||||
|
self.app_name = app_name
|
||||||
|
|
||||||
|
create_cid_user_and_groups(db)
|
||||||
|
self.exam = exam = create_exam(db, ExamViews)
|
||||||
|
|
||||||
|
cidgroup1: CidUserGroup = CidUserGroup.objects.get(name="Group1")
|
||||||
|
assert exam in cidgroup1.physics_cid_user_groups.all()
|
||||||
|
|
||||||
|
cid_user_1001 = CidUser.objects.get(cid=1001)
|
||||||
|
cid_user_1000 = CidUser.objects.get(cid=1000)
|
||||||
|
self.cid_user_2001 = cid_user_2001 = CidUser.objects.get(cid=2001)
|
||||||
|
|
||||||
|
user1 = User.objects.get(username="user1")
|
||||||
|
user2 = User.objects.get(username="user2")
|
||||||
|
|
||||||
|
self.all_users = [cid_user_1000, cid_user_1001, cid_user_2001, user1, user2]
|
||||||
|
|
||||||
|
self.cid_users = [cid_user_1000, cid_user_1001, cid_user_2001]
|
||||||
|
|
||||||
|
self.invalid_users = [cid_user_2001, user2]
|
||||||
|
|
||||||
|
self.current_user = None
|
||||||
|
self.generated_questions = []
|
||||||
|
|
||||||
|
def load_user(self, user):
|
||||||
|
self.client.logout()
|
||||||
|
|
||||||
|
self.current_user = user
|
||||||
|
|
||||||
|
if isinstance(self.current_user, CidUser):
|
||||||
|
self.testing_cid_user = True
|
||||||
|
else:
|
||||||
|
self.testing_cid_user = False
|
||||||
|
|
||||||
|
self.client.force_login(user)
|
||||||
|
|
||||||
|
def create_questions(self, create_question_func: Callable):
|
||||||
|
self.create_question_func = create_question_func
|
||||||
|
|
||||||
|
self.generated_questions = [
|
||||||
|
create_question_func(self.exam),
|
||||||
|
create_question_func(self.exam),
|
||||||
|
create_question_func(self.exam),
|
||||||
|
]
|
||||||
|
|
||||||
|
def add_question(self):
|
||||||
|
self.generated_questions.append(self.create_question_func(self.exam))
|
||||||
|
|
||||||
|
def check_active_exams(self, n):
|
||||||
|
active_exams = self.client.get(reverse(f"{self.app_name}:active_exams"))
|
||||||
|
assert active_exams.status_code == 200
|
||||||
|
assert len(json.loads(active_exams.content)["exams"]) == n, f"Current user: {self.current_user}"
|
||||||
|
|
||||||
|
def check_onsite_start_page(self):
|
||||||
|
start_page_res = self.client.get(
|
||||||
|
reverse(f"{self.app_name}:exam_start", kwargs={"pk": self.exam.pk})
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check user access to the start page
|
||||||
|
assert start_page_res.status_code == HTTPStatus.OK
|
||||||
|
start_page_soup = BeautifulSoup(start_page_res.content, "html.parser")
|
||||||
|
if (
|
||||||
|
self.current_user in self.cid_users
|
||||||
|
or self.current_user in self.invalid_users
|
||||||
|
):
|
||||||
|
assert "Enter your CID and passcode" in str(start_page_soup)
|
||||||
|
else:
|
||||||
|
assert "Start Exam" in str(start_page_soup)
|
||||||
|
|
||||||
|
def check_take_page(self):
|
||||||
|
for n, question in enumerate(self.generated_questions):
|
||||||
|
if self.testing_cid_user:
|
||||||
|
take_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"sk": n,
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": self.current_user.passcode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
take_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"sk": n,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
cid_take_res = self.client.get(take_url)
|
||||||
|
|
||||||
|
# Check that users that have not been added cannot access the take pages
|
||||||
|
if self.current_user in self.invalid_users:
|
||||||
|
assert cid_take_res.status_code == HTTPStatus.NOT_FOUND
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
assert cid_take_res.status_code == HTTPStatus.OK, f"Current user: {self.current_user}"
|
||||||
|
|
||||||
|
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
|
||||||
|
|
||||||
|
# Check correct user is displayed
|
||||||
|
if self.testing_cid_user:
|
||||||
|
display_user = str(self.current_user.cid)
|
||||||
|
else:
|
||||||
|
display_user = self.current_user.username
|
||||||
|
assert display_user in cid_take_soup.find("span", {"id": "user-id"}).string
|
||||||
|
|
||||||
|
# Check review mode alert not visible
|
||||||
|
assert cid_take_soup.find("div", {"class": "review-mode-alert"}) is None
|
||||||
|
|
||||||
|
# Check that relevant buttons are being displayed
|
||||||
|
assert cid_take_soup.find("button", {"name": "finish"}) is not None
|
||||||
|
|
||||||
|
if n < len(self.generated_questions) - 1:
|
||||||
|
assert cid_take_soup.find("button", {"name": "next"}) is not None
|
||||||
|
|
||||||
|
if n > 0:
|
||||||
|
assert cid_take_soup.find("button", {"name": "previous"}) is not None
|
||||||
|
|
||||||
|
assert cid_take_soup.find("span", {"id": "question-number"}).string == str(
|
||||||
|
n + 1
|
||||||
|
) # + 1 for 0 offset
|
||||||
|
assert cid_take_soup.find("span", {"id": "exam-length"}).string == str(
|
||||||
|
len(self.generated_questions)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that stem text is displayed
|
||||||
|
assert (
|
||||||
|
cid_take_soup.find("span", {"id": "question-stem"}).string
|
||||||
|
== question.stem
|
||||||
|
)
|
||||||
|
|
||||||
|
assert cid_take_soup.find("label", {"for": "id_a"}).string == question.a
|
||||||
|
assert cid_take_soup.find("label", {"for": "id_b"}).string == question.b
|
||||||
|
assert cid_take_soup.find("label", {"for": "id_c"}).string == question.c
|
||||||
|
assert cid_take_soup.find("label", {"for": "id_d"}).string == question.d
|
||||||
|
assert cid_take_soup.find("label", {"for": "id_e"}).string == question.e
|
||||||
|
|
||||||
|
# As we haven't submitted any answers they should all be blank
|
||||||
|
assert (
|
||||||
|
cid_take_soup.find("input", {"type": "checkbox", "checked": True})
|
||||||
|
is None
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_take_overview(self, answered, total):
|
||||||
|
if self.testing_cid_user:
|
||||||
|
take_overview_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take_overview",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": self.current_user.passcode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
take_overview_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take_overview_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
cid_take_overview_res = self.client.get(take_overview_url)
|
||||||
|
|
||||||
|
# Check that users that have not been added cannot access the take pages
|
||||||
|
if self.current_user in self.invalid_users:
|
||||||
|
assert cid_take_overview_res.status_code == HTTPStatus.NOT_FOUND
|
||||||
|
else:
|
||||||
|
assert cid_take_overview_res.status_code == HTTPStatus.OK
|
||||||
|
|
||||||
|
cid_take_overview_soup = BeautifulSoup(
|
||||||
|
cid_take_overview_res.content, "html.parser"
|
||||||
|
)
|
||||||
|
print(self.generated_questions)
|
||||||
|
assert (
|
||||||
|
f"{answered} out of 3 questions answered"
|
||||||
|
in cid_take_overview_soup.find(
|
||||||
|
"div", attrs={"class": "overview-text"}
|
||||||
|
).string
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
len(
|
||||||
|
cid_take_overview_soup.find_all(
|
||||||
|
"button", attrs={"class": "unanswered"}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== total - answered
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_cid_scores_page(self):
|
||||||
|
if self.testing_cid_user:
|
||||||
|
# Get overview scores page (invalid passcode)
|
||||||
|
AssertNotFound(
|
||||||
|
self.client,
|
||||||
|
reverse(
|
||||||
|
f"cid_scores",
|
||||||
|
kwargs={"cid": self.current_user.cid, "passcode": "AAAA"},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
cid_scores_url = reverse(
|
||||||
|
f"cid_scores",
|
||||||
|
kwargs={
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": self.current_user.passcode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cid_scores_url = reverse(f"user_scores")
|
||||||
|
|
||||||
|
# Get overview scores page
|
||||||
|
cid_scores_res = self.client.get(cid_scores_url)
|
||||||
|
|
||||||
|
assert cid_scores_res.status_code == HTTPStatus.OK
|
||||||
|
|
||||||
|
cid_scores_soup = BeautifulSoup(cid_scores_res.content, "html.parser")
|
||||||
|
|
||||||
|
if self.current_user in self.invalid_users:
|
||||||
|
# page should load but we shouldn't be able to find the exam
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
search_exam = (
|
||||||
|
cid_scores_soup.find("div", {"id": "exam-assigned"})
|
||||||
|
.find("ul", {"class": self.exam.app_name.lower()})
|
||||||
|
.find_all("li", attrs={"data-exam-id": self.exam.pk})
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
search_exam = (
|
||||||
|
cid_scores_soup.find("div", {"id": "exam-assigned"})
|
||||||
|
.find("ul", {"class": self.exam.app_name.lower()})
|
||||||
|
.find_all("li", attrs={"data-exam-id": self.exam.pk})
|
||||||
|
)
|
||||||
|
assert search_exam
|
||||||
|
assert self.exam.name in str(search_exam)
|
||||||
|
assert "Active" in str(search_exam)
|
||||||
|
# assert "Active" in assigned_exams # check it is active
|
||||||
|
|
||||||
|
invalid_exam = cid_scores_soup.find_all(
|
||||||
|
"li", attrs={"data-exam-id": self.exam.pk + 5}
|
||||||
|
)
|
||||||
|
assert not invalid_exam # Check we can't find an invalid exam
|
||||||
|
|
||||||
|
# Check that we have a results link
|
||||||
|
results_exam = (
|
||||||
|
cid_scores_soup.find("div", {"id": "exam-results"})
|
||||||
|
.find("ul", {"class": self.exam.app_name})
|
||||||
|
.find_all("li", attrs={"data-exam-id": self.exam.pk})
|
||||||
|
)
|
||||||
|
assert results_exam
|
||||||
|
assert self.exam.name in str(results_exam)
|
||||||
|
assert self.exam.name + " test" not in str(results_exam)
|
||||||
|
assert "Results Published" not in str(
|
||||||
|
results_exam
|
||||||
|
) # It should not be published yet
|
||||||
|
|
||||||
|
def check_cid_scores_user_page(self):
|
||||||
|
if self.testing_cid_user:
|
||||||
|
AssertNotFound(
|
||||||
|
self.client,
|
||||||
|
reverse(
|
||||||
|
f"{self.exam.app_name}:exam_scores_cid_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": "AAAA",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
AssertNotFound(
|
||||||
|
self.client,
|
||||||
|
reverse(
|
||||||
|
f"{self.exam.app_name}:exam_scores_cid_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"cid": self.cid_user_2001.cid,
|
||||||
|
"passcode": self.cid_user_2001.passcode,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
exam_scores_url = reverse(
|
||||||
|
f"{self.exam.app_name}:exam_scores_cid_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": self.current_user.passcode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
exam_scores_url = reverse(
|
||||||
|
f"{self.exam.app_name}:exam_scores_user",
|
||||||
|
kwargs={"pk": self.exam.pk},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.exam_scores_url = exam_scores_url
|
||||||
|
|
||||||
|
# Load the exam results page
|
||||||
|
cid_exam_scores_res = self.client.get(exam_scores_url)
|
||||||
|
|
||||||
|
if self.current_user in self.invalid_users:
|
||||||
|
assert cid_exam_scores_res.status_code == HTTPStatus.NOT_FOUND
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
assert cid_exam_scores_res.status_code == HTTPStatus.OK
|
||||||
|
|
||||||
|
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
||||||
|
|
||||||
|
# Check that we have an alert that exams are not published
|
||||||
|
alert = cid_exam_scores_soup.find("div", {"class": "alert"})
|
||||||
|
assert "Results are not currently published." in str(alert)
|
||||||
|
|
||||||
|
# Check that we are showing enough questions / answers
|
||||||
|
answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"})
|
||||||
|
assert len(answer_lis) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
submitted_answers = cid_exam_scores_soup.find_all(
|
||||||
|
"span", {"class": "submitted-user-answer"}
|
||||||
|
)
|
||||||
|
assert len(submitted_answers) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
for ans in submitted_answers:
|
||||||
|
assert ans.text.strip() == "True"
|
||||||
|
|
||||||
|
# Check no correct answers are shown
|
||||||
|
assert not cid_exam_scores_soup.find_all("span", {"class": "correct-answer"})
|
||||||
|
|
||||||
|
# Add another question to the exam
|
||||||
|
self.add_question()
|
||||||
|
|
||||||
|
# Load the exam results page (again)
|
||||||
|
cid_exam_scores_res = self.client.get(exam_scores_url)
|
||||||
|
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
||||||
|
|
||||||
|
answer_lis = cid_exam_scores_soup.find_all("li", {"class": "question-part"})
|
||||||
|
assert len(answer_lis) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
submitted_answers = cid_exam_scores_soup.find_all(
|
||||||
|
"span", {"class": "submitted-user-answer"}
|
||||||
|
)
|
||||||
|
assert len(submitted_answers) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
for ans in submitted_answers[:-5]:
|
||||||
|
assert ans.text.strip() == "True"
|
||||||
|
|
||||||
|
# The new question will not have any answers
|
||||||
|
for ans in submitted_answers[-5:]:
|
||||||
|
assert ans.text.strip() == ""
|
||||||
|
|
||||||
|
# Publish the results!
|
||||||
|
self.exam.publish_results = True
|
||||||
|
self.exam.save()
|
||||||
|
|
||||||
|
# Load the exam results page (again)
|
||||||
|
cid_exam_scores_res = self.client.get(exam_scores_url)
|
||||||
|
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
||||||
|
|
||||||
|
assert (
|
||||||
|
cid_exam_scores_soup.find("div", {"class": "alert"}) is None
|
||||||
|
) # Check our warning banner is gone
|
||||||
|
|
||||||
|
# Check that we are displaying the correct answers (correctly)
|
||||||
|
correct_answers = cid_exam_scores_soup.find_all(
|
||||||
|
"span", {"class": "correct-answer"}
|
||||||
|
)
|
||||||
|
assert len(correct_answers) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
for question in self.generated_questions:
|
||||||
|
for ans in question.get_answers():
|
||||||
|
assert correct_answers[n].text.strip() == f"Correct answer: {ans}"
|
||||||
|
n = n + 1
|
||||||
|
|
||||||
|
submitted_answers = cid_exam_scores_soup.find_all(
|
||||||
|
"span", {"class": "submitted-user-answer"}
|
||||||
|
)
|
||||||
|
assert len(submitted_answers) == 5 * len(self.generated_questions)
|
||||||
|
|
||||||
|
for ans in submitted_answers[:-5]:
|
||||||
|
assert ans.text.strip() == "True"
|
||||||
|
|
||||||
|
# The new question will not have any answers
|
||||||
|
for ans in submitted_answers[-5:]:
|
||||||
|
assert ans.text.strip() == ""
|
||||||
|
|
||||||
|
assert (
|
||||||
|
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
||||||
|
.find("span", {"id": "total-score"})
|
||||||
|
.string
|
||||||
|
== "9"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
||||||
|
.find("span", {"id": "max-score"})
|
||||||
|
.string
|
||||||
|
== "20"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def check_cid_scores_user_page2(self):
|
||||||
|
|
||||||
|
cid_exam_scores_res = self.client.get(self.exam_scores_url)
|
||||||
|
|
||||||
|
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# As we have answered correctly the new score should be increased by 5
|
||||||
|
assert (
|
||||||
|
cid_exam_scores_soup.find("div", {"class": "score-overview"})
|
||||||
|
.find("span", {"id": "total-score"})
|
||||||
|
.string
|
||||||
|
== "14"
|
||||||
|
), f"Current user: {self.current_user}"
|
||||||
|
|
||||||
|
# Check what happens when exam is not active
|
||||||
|
self.exam.active = False
|
||||||
|
self.exam.save()
|
||||||
|
|
||||||
|
start_page_res = self.client.get(
|
||||||
|
reverse(f"{self.app_name}:exam_start", kwargs={"pk": self.exam.pk})
|
||||||
|
)
|
||||||
|
start_page_soup = BeautifulSoup(start_page_res.content, "html.parser")
|
||||||
|
|
||||||
|
assert "Exam is currently inactive" in start_page_soup.text
|
||||||
|
|
||||||
|
if self.testing_cid_user:
|
||||||
|
cid_take_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"sk": 0,
|
||||||
|
"cid": self.current_user.cid,
|
||||||
|
"passcode": self.current_user.passcode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cid_take_url = reverse(
|
||||||
|
f"{self.app_name}:exam_take_user",
|
||||||
|
kwargs={
|
||||||
|
"pk": self.exam.pk,
|
||||||
|
"sk": 0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
cid_take_res = self.client.get(cid_take_url)
|
||||||
|
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
|
||||||
|
assert "Exam is currently inactive" in cid_take_soup.text
|
||||||
|
|
||||||
|
# Delete the last question, from both the list
|
||||||
|
q= self.generated_questions.pop()
|
||||||
|
# and the database
|
||||||
|
q.delete()
|
||||||
Reference in New Issue
Block a user