Extend physics integration tests to users

This commit is contained in:
Ross
2022-12-12 14:12:53 +00:00
parent 73ebc838cd
commit 66f512f455
3 changed files with 196 additions and 88 deletions
+154 -50
View File
@@ -18,9 +18,10 @@ from physics.views import GenericExamViews as PhysicsExamViews
from physics.models import Category, CidUserAnswer, Exam, Question from physics.models import Category, CidUserAnswer, Exam, Question
from generic.models import CidUser, CidUserGroup from generic.models import CidUser, CidUserGroup, UserUserGroup
from rad.test_helpers import AssertNotFound from rad.test_helpers import AssertNotFound
from django.contrib.auth.models import User
APP_NAME = "physics" APP_NAME = "physics"
@@ -39,6 +40,13 @@ def create_cid_user_and_groups(db):
assert cid_user_1000.cid == 1000 assert cid_user_1000.cid == 1000
assert cid_user_1001.cid == 1001 assert cid_user_1001.cid == 1001
# Create UserUsers
user1 = User.objects.create_user(username="user1", email="test@email.com", password="test1234")
usergroup1 = UserUserGroup.objects.create(name="Group1")
usergroup1.users.add(user1)
usergroup2 = UserUserGroup.objects.create(name="Group2")
def create_exam(db): def create_exam(db):
exam: Exam = PhysicsExamViews.Exam.objects.create( exam: Exam = PhysicsExamViews.Exam.objects.create(
@@ -46,11 +54,15 @@ def create_exam(db):
) )
group1: CidUserGroup = CidUserGroup.objects.get(name="Group1") group1: CidUserGroup = CidUserGroup.objects.get(name="Group1")
usergroup1: UserUserGroup = UserUserGroup.objects.get(name="Group1")
exam.cid_user_groups.add(group1) exam.cid_user_groups.add(group1)
exam.valid_cid_users.add(*group1.ciduser_set.all()) 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 in group1.physics_cid_user_groups.all()
assert exam assert exam
@@ -118,8 +130,23 @@ def test_exams(db, client):
cid_user_1001 = CidUser.objects.get(cid=1001) cid_user_1001 = CidUser.objects.get(cid=1001)
cid_user_1000 = CidUser.objects.get(cid=1000) cid_user_1000 = CidUser.objects.get(cid=1000)
cid_user_2001 = CidUser.objects.get(cid=2001)
user1 = User.objects.get(username="user1")
users_tested = 1
for cid_user in [cid_user_1001, cid_user_1000, user1]:
if isinstance(cid_user, CidUser):
testing_cid_user = True
else:
testing_cid_user = False
current_user = cid_user
client.force_login(cid_user)
for cid_user in [cid_user_1001, cid_user_1000]:
exam.active = True exam.active = True
exam.publish_results = False exam.publish_results = False
exam.save() exam.save()
@@ -127,12 +154,16 @@ def test_exams(db, client):
start_page_res = client.get( start_page_res = client.get(
reverse(f"physics:exam_start", kwargs={"pk": exam.pk}) reverse(f"physics:exam_start", kwargs={"pk": exam.pk})
) )
start_page_soup = BeautifulSoup(start_page_res.content, "html.parser") start_page_soup = BeautifulSoup(start_page_res.content, "html.parser")
assert "Enter your CID and passcode" in str(start_page_soup) if testing_cid_user:
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(questions): for n, question in enumerate(questions):
cid_take_res = client.get( if testing_cid_user:
reverse( take_url = reverse(
f"physics:exam_take", f"physics:exam_take",
kwargs={ kwargs={
"pk": exam.pk, "pk": exam.pk,
@@ -141,12 +172,28 @@ def test_exams(db, client):
"passcode": cid_user.passcode, "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
) )
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser") cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
# Check correct user is displayed # Check correct user is displayed
if testing_cid_user:
display_user = str(cid_user.cid)
else:
display_user = current_user.username
assert ( assert (
str(cid_user.cid) display_user
in cid_take_soup.find("span", {"id": "user-id"}).string in cid_take_soup.find("span", {"id": "user-id"}).string
) )
@@ -188,8 +235,8 @@ def test_exams(db, client):
) )
cid_take_overview_res = client.get( if testing_cid_user:
reverse( take_overview_url = reverse(
f"physics:exam_take_overview", f"physics:exam_take_overview",
kwargs={ kwargs={
"pk": exam.pk, "pk": exam.pk,
@@ -197,6 +244,18 @@ def test_exams(db, client):
"passcode": cid_user.passcode, "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
) )
cid_take_overview_soup = BeautifulSoup( cid_take_overview_soup = BeautifulSoup(
cid_take_overview_res.content, "html.parser" cid_take_overview_res.content, "html.parser"
@@ -219,15 +278,25 @@ def test_exams(db, client):
# 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(questions) - 1 questions_len = len(questions) - 1
for n, question in enumerate(questions): for n, question in enumerate(questions):
question_url = reverse( if testing_cid_user:
f"physics:exam_take", question_url = reverse(
kwargs={ f"physics:exam_take",
"pk": exam.pk, kwargs={
"sk": n, "pk": exam.pk,
"cid": cid_user.cid, "sk": n,
"passcode": cid_user.passcode, "cid": cid_user.cid,
}, "passcode": cid_user.passcode,
) },
)
else:
question_url = reverse(
f"physics:exam_take_user",
kwargs={
"pk": exam.pk,
"sk": n,
},
)
cid_take_res = client.get(question_url) cid_take_res = client.get(question_url)
cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser") cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
@@ -271,16 +340,19 @@ def test_exams(db, client):
# Filter answer to the question we just submitted to # Filter answer to the question we just submitted to
cid_user_answers = question.cid_user_answers.all() cid_user_answers = question.cid_user_answers.all()
assert len(cid_user_answers) in (1, 2) assert len(cid_user_answers) == users_tested
cid_user_answer = cid_user_answers.filter(cid=cid_user.cid)[0] if testing_cid_user:
cid_user_answer = cid_user_answers.filter(cid=cid_user.cid)[0]
else:
cid_user_answer = cid_user_answers.filter(user=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)
cid_take_overview_res = client.get( if testing_cid_user:
reverse( take_overview_url = reverse(
f"physics:exam_take_overview", f"physics:exam_take_overview",
kwargs={ kwargs={
"pk": exam.pk, "pk": exam.pk,
@@ -288,6 +360,16 @@ def test_exams(db, client):
"passcode": cid_user.passcode, "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
) )
cid_take_overview_soup = BeautifulSoup( cid_take_overview_soup = BeautifulSoup(
cid_take_overview_res.content, "html.parser" cid_take_overview_res.content, "html.parser"
@@ -307,20 +389,25 @@ def test_exams(db, client):
) )
# Get overview scores page (invalid passcode) # Get overview scores page (invalid passcode)
AssertNotFound(client, if testing_cid_user:
reverse(f"cid_scores", kwargs={"cid": cid_user.cid, "passcode": "AAAA"}) 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 # Get overview scores page
cid_scores_res = client.get( cid_scores_res = client.get(
reverse(f"cid_scores", kwargs={"cid": cid_user.cid, "passcode": cid_user.passcode}) cid_scores_url
) )
cid_scores_soup = BeautifulSoup(cid_scores_res.content, "html.parser") cid_scores_soup = BeautifulSoup(cid_scores_res.content, "html.parser")
search_exam = ( search_exam = (
cid_scores_soup.find("div", {"id": "exam-assigned"}) cid_scores_soup.find("div", {"id": "exam-assigned"})
.find("ul", {"class": exam.app_name}) .find("ul", {"class": exam.app_name.lower()})
.find_all("li", attrs={"data-exam-id": exam.pk}) .find_all("li", attrs={"data-exam-id": exam.pk})
) )
assert search_exam assert search_exam
@@ -347,19 +434,31 @@ def test_exams(db, client):
) # It should not be published yet ) # It should not be published yet
AssertNotFound(client, if testing_cid_user:
reverse( AssertNotFound(client,
f"{exam.app_name}:exam_scores_cid_user", reverse(
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": "AAAA"}, 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})
) )
)
# Load the exam results page exam_scores_url = reverse(
cid_exam_scores_res = client.get(
reverse(
f"{exam.app_name}:exam_scores_cid_user", f"{exam.app_name}:exam_scores_cid_user",
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": cid_user.passcode}, 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
) )
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
@@ -388,10 +487,7 @@ def test_exams(db, client):
# Load the exam results page (again) # Load the exam results page (again)
cid_exam_scores_res = client.get( cid_exam_scores_res = client.get(
reverse( exam_scores_url
f"{exam.app_name}:exam_scores_cid_user",
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": cid_user.passcode},
)
) )
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
@@ -416,10 +512,7 @@ def test_exams(db, client):
# Load the exam results page (again) # Load the exam results page (again)
cid_exam_scores_res = client.get( cid_exam_scores_res = client.get(
reverse( exam_scores_url
f"{exam.app_name}:exam_scores_cid_user",
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": cid_user.passcode},
)
) )
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
@@ -465,14 +558,14 @@ def test_exams(db, client):
) )
# answer the final question # answer the final question
cid_user_answer = CidUserAnswer(question=extra_question, a=True, b=False, c=True, d=False, e=True, cid=cid_user.cid, exam=exam) if testing_cid_user:
cid_user_answer = CidUserAnswer(question=extra_question, a=True, b=False, c=True, d=False, e=True, cid=cid_user.cid, exam=exam)
else:
cid_user_answer = CidUserAnswer(question=extra_question, a=True, b=False, c=True, d=False, e=True, user=current_user, exam=exam)
cid_user_answer.save() cid_user_answer.save()
cid_exam_scores_res = client.get( cid_exam_scores_res = client.get(
reverse( exam_scores_url
f"{exam.app_name}:exam_scores_cid_user",
kwargs={"pk": exam.pk, "cid": cid_user.cid, "passcode": cid_user.passcode},
)
) )
cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser")
@@ -496,8 +589,8 @@ def test_exams(db, client):
assert "Exam is currently inactive" in start_page_soup.text assert "Exam is currently inactive" in start_page_soup.text
cid_take_res = client.get( if testing_cid_user:
reverse( cid_take_url = reverse(
f"physics:exam_take", f"physics:exam_take",
kwargs={ kwargs={
"pk": exam.pk, "pk": exam.pk,
@@ -506,8 +599,19 @@ def test_exams(db, client):
"passcode": cid_user.passcode, "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") cid_take_soup = BeautifulSoup(cid_take_res.content, "html.parser")
assert "Exam is currently inactive" in cid_take_soup.text assert "Exam is currently inactive" in cid_take_soup.text
questions.pop(-1).delete() questions.pop(-1).delete()
users_tested = users_tested + 1
+2 -2
View File
@@ -8,7 +8,7 @@
The following exams will be available to take when active. The following exams will be available to take when active.
{% for exam_type, exams in available_exams %} {% for exam_type, exams in available_exams %}
<h4>{{exam_type|title}}</h4> <h4>{{exam_type|title}}</h4>
<ul class='{{exam_type}}'> <ul class='{{exam_type|lower}}'>
{% for exam in exams %} {% for exam in exams %}
<li class="exam" data-exam-id="{{exam.pk}}"><a href="{{exam.get_take_url}}?cid={{cid}}&passcode={{passcode}}" target="_blank">{{exam.name}} {% if exam.active %}[Active]{% endif %}</a></li> <li class="exam" data-exam-id="{{exam.pk}}"><a href="{{exam.get_take_url}}?cid={{cid}}&passcode={{passcode}}" target="_blank">{{exam.name}} {% if exam.active %}[Active]{% endif %}</a></li>
{% endfor %} {% endfor %}
@@ -23,7 +23,7 @@
{% for exam_type, exams in all_exams %} {% for exam_type, exams in all_exams %}
{% if exams %} {% if exams %}
<h4>{{exam_type|title}}</h4> <h4>{{exam_type|title}}</h4>
<ul class='{{exam_type}}'> <ul class='{{exam_type|lower}}'>
{% for exam in exams %} {% for exam in exams %}
<li class="exam" data-exam-id="{{exam.pk}}"><a href="{% url exam_type|add:':exam_scores_cid_user' pk=exam.pk cid=cid passcode=passcode %}">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li> <li class="exam" data-exam-id="{{exam.pk}}"><a href="{% url exam_type|add:':exam_scores_cid_user' pk=exam.pk cid=cid passcode=passcode %}">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
{% endfor %} {% endfor %}
+40 -36
View File
@@ -4,43 +4,47 @@
<div class=""> <div class="">
<h2>User: {{ request.user.username }}</h2> <h2>User: {{ request.user.username }}</h2>
<h3>Assigned exams</h3> <h3>Assigned exams</h3>
<p>The following exams will be available to take when active. <div id="exam-assigned">
The following exams will be available to take when active.
{% for exam_type, exams in available_exams %} {% for exam_type, exams in available_exams %}
<h4>{{exam_type}}</h4> {% if exams %}
<ul> <h4>{{exam_type|title}}</h4>
{% for exam in exams %} <ul class='{{exam_type|lower}}'>
<li><a href="{{exam.get_take_url}}" target="_blank">{{exam.name}} {% if exam.active %}[Active]{% endif %}</a></li> {% for exam in exams %}
{% endfor %} <li class="exam" data-exam-id="{{exam.pk}}"><a href="{{exam.get_take_url}}" target="_blank">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
</ul> {% endfor %}
</ul>
{% endif %}
{% endfor %} {% endfor %}
{% if all_exams %}
<h3>Exam results</h3>
<div>
The following exam results been found. Click to view answers (and scores when the results are published):
{% for exam_type, exams in all_exams %}
{% if exams %}
<h4>{{exam_type|title}}</h4>
<ul>
{% for exam in exams %}
<li><a href="{% url exam_type|add:':exam_scores_user' pk=exam.pk %}">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if case_collections %}
<div>
<h3>Case Collection</h3>
The following Case Collections have been found.
{% for collection in case_collections %}
<li><a href="{{collection.get_take_url}}?cid={{cid}}&passcode={{passcode}}">{{collection.name}}</a> {% if collection.active %}[Active]{% endif %} {% if collection.publish_results %}[Results Published]{% endif %}</li>
{% endfor %}
</div>
{% endif %}
</div> </div>
{% if all_exams %}
<h3>Exam results</h3>
<div id="exam-results">
The following exam results been found. Click to view answers (and scores when the results are published):
{% for exam_type, exams in all_exams %}
{% if exams %}
<h4>{{exam_type|title}}</h4>
<ul class='{{exam_type|lower}}'>
{% for exam in exams %}
<li class="exam" data-exam-id="{{exam.pk}}"><a href="{% url exam_type|add:':exam_scores_user' pk=exam.pk %}">{{exam.name}}</a> {% if exam.active %}[Active]{% endif %} {% if exam.publish_results %}[Results Published]{% endif %}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if case_collections %}
<div>
<h3>Case Collection</h3>
The following Case Collections have been found.
{% for collection in case_collections %}
<li><a href="{{collection.get_take_url}}?cid={{cid}}&passcode={{passcode}}">{{collection.name}}</a> {% if collection.active %}[Active]{% endif %} {% if collection.publish_results %}[Results Published]{% endif %}</li>
{% endfor %}
</div>
{% endif %}
</div>
{% endblock %} {% endblock %}