From a467f24e1015b507cfe399441d2c19deb9e46095 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 5 Dec 2022 12:22:26 +0000 Subject: [PATCH] more cid user anatomy testing --- anatomy/models.py | 10 +- .../templates/anatomy/exam_scores_user.html | 17 +-- anatomy/tests/test_exams.py | 118 +++++++++++++++++- generic/models.py | 12 +- generic/templates/generic/ciduser_form.html | 2 +- rad/urls.py | 2 +- templates/cid_scores.html | 56 ++++----- templates/user_scores_footer.html | 4 +- 8 files changed, 170 insertions(+), 51 deletions(-) diff --git a/anatomy/models.py b/anatomy/models.py index ba5539ef..40063fb4 100644 --- a/anatomy/models.py +++ b/anatomy/models.py @@ -199,7 +199,15 @@ class AnatomyQuestion(models.Model): ) ) - def get_unmarked_user_answers(self, exam_pk=None): + def get_unmarked_user_answers(self, exam_pk: int|None = None): + """_summary_ + + Args: + exam_pk (_type_, optional): _description_. Defaults to None. + + Returns: + set: set of unmarked user strings + """ if exam_pk is None: user_answers = set([i.answer_compare for i in self.cid_user_answers.all()]) else: diff --git a/anatomy/templates/anatomy/exam_scores_user.html b/anatomy/templates/anatomy/exam_scores_user.html index 274c85d0..39f80027 100644 --- a/anatomy/templates/anatomy/exam_scores_user.html +++ b/anatomy/templates/anatomy/exam_scores_user.html @@ -14,13 +14,16 @@
{% include 'user_score_header.html' %} -
diff --git a/anatomy/tests/test_exams.py b/anatomy/tests/test_exams.py index 480fbb36..60118b74 100644 --- a/anatomy/tests/test_exams.py +++ b/anatomy/tests/test_exams.py @@ -15,7 +15,7 @@ from bs4 import BeautifulSoup from anatomy.views import GenericExamViews as AnatomyExamViews -from anatomy.models import Exam, AnatomyQuestion as Question, QuestionType, Structure +from anatomy.models import Answer, Exam, AnatomyQuestion as Question, QuestionType, Structure from generic.models import CidUser, CidUserGroup @@ -66,7 +66,7 @@ def create_question_types(db): question_type.save() -def create_question(exam): +def create_question(exam, answer=None): # Just assign random stuff image = tempfile.NamedTemporaryFile( @@ -79,6 +79,15 @@ def create_question(exam): image=image.name, ) question.exams.set([exam]) + + # Create an answer for the question + if answer is None: + answer_text = "testanswer" + else: + answer_text = answer + answer = Answer(question=question, answer=answer_text, answer_compare=answer_text, status=Answer.MarkOptions.CORRECT) + answer.save() + return question @@ -219,21 +228,118 @@ def test_exams(db, client): # Test submission # give three answers - print("post_json", post_json) res = client.post(reverse("global_exam_answers_submit"), data=post_json) json_res = json.loads(res.content) - print(json_res) assert json_res["success"] == True assert json_res["question_count"] == 3 # We can then check the answers have been submitted (and can be viewed by the user) + + # Get overview scores page cid_scores_res = client.get( reverse(f"cid_scores", kwargs={"cid": 1001, "passcode": "EFGH"}) ) cid_scores_soup = BeautifulSoup(cid_scores_res.content, "html.parser") - assigned_exams = cid_scores_soup.find(id="exam-assigned").find_all("li") - print(assigned_exams) + print(cid_scores_soup.find("div", {"id" : "exam-assigned"})) + search_exam = cid_scores_soup.find("div", {"id" : "exam-assigned"}).find("ul", {"class" : exam.app_name}).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 + + + # Load the exam results page + cid_exam_scores_res = client.get( + reverse(f"{exam.app_name}:exam_scores_cid_user", kwargs={"pk": exam.pk, "cid": 1001, "passcode": "EFGH"}) + ) + 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) + + + answer_lis = cid_exam_scores_soup.find("ul", {"class": "score-answer-list"}).find_all("li") + + assert len(answer_lis) == len(valid_answers) + + for n in range(len(valid_answers)): # Check no answers are visible if results not published + answer = valid_answers[n] + li = answer_lis[n] + + assert answer["ans"] in str(li) # Check that the saved answer is shown + + assert li.find("span", {"class": "correct-answer"}).string == "*****" # and that the correct answer isn't + + assert cid_exam_scores_soup.find("div", {"class": "score-overview"}) is None # check we hide the score overview if not published + + # Add another question to the exam + create_question(exam) + + # Load the exam results page (again) + cid_exam_scores_res = client.get( + reverse(f"{exam.app_name}:exam_scores_cid_user", kwargs={"pk": exam.pk, "cid": 1001, "passcode": "EFGH"}) + ) + cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") + + answer_lis = cid_exam_scores_soup.find("ul", {"class": "score-answer-list"}).find_all("li") + assert len(answer_lis) == len(valid_answers) + 1 + assert "Not answered" in str(answer_lis[-1]) + + # Publish the results! + exam.publish_results = True + exam.save() + + # Load the exam results page (again) + cid_exam_scores_res = client.get( + reverse(f"{exam.app_name}:exam_scores_cid_user", kwargs={"pk": exam.pk, "cid": 1001, "passcode": "EFGH"}) + ) + 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 + + answer_lis = cid_exam_scores_soup.find("ul", {"class": "score-answer-list"}).find_all("li") + + assert len(answer_lis) == len(valid_answers) + 1 + assert "Not answered" in str(answer_lis[-1]) + + # Repetition.... + for n in range(len(valid_answers)): # Check answers are visible if results published + answer = valid_answers[n] + li = answer_lis[n] + + assert answer["ans"] in str(li) # Check that the saved answer is shown + + assert li.find("span", {"class": "correct-answer"}).string == "testanswer" + + assert cid_exam_scores_soup.find("div", {"class": "score-overview"}).find("span", {"id": "total-score"}).string == "0 (3 unmarked)" + + + for question in exam.exam_questions.all(): + try: + new_ans = Answer(question=question, answer=question.get_unmarked_user_answers().pop(), status=Answer.MarkOptions.CORRECT) + new_ans.save() + except KeyError: # Final question does not have an answer + pass + + # Load the exam results page (again) + cid_exam_scores_res = client.get( + reverse(f"{exam.app_name}:exam_scores_cid_user", kwargs={"pk": exam.pk, "cid": 1001, "passcode": "EFGH"}) + ) + cid_exam_scores_soup = BeautifulSoup(cid_exam_scores_res.content, "html.parser") + + assert cid_exam_scores_soup.find("div", {"class": "score-overview"}).find("span", {"id": "total-score"}).string == "6" \ No newline at end of file diff --git a/generic/models.py b/generic/models.py index d120e40b..291f579d 100644 --- a/generic/models.py +++ b/generic/models.py @@ -423,12 +423,12 @@ class QuestionNote(models.Model): return f"{self.note_type} - {self.note}" EXAM_TYPES = ( - ("Physics", "physics_exams"), - ("Rapids", "rapid_exams"), - ("SBAs", "sba_exams"), - ("Anatomy", "anatomy_exams"), - ("Longs", "longs_exams"), - ("CaseCollection", "casecollection_exams"), + ("physics", "physics_exams"), + ("rapids", "rapid_exams"), + ("sbas", "sba_exams"), + ("anatomy", "anatomy_exams"), + ("longs", "longs_exams"), + ("casecollection", "casecollection_exams"), ) class CidUser(models.Model): diff --git a/generic/templates/generic/ciduser_form.html b/generic/templates/generic/ciduser_form.html index 088e5ec8..d20a18f2 100755 --- a/generic/templates/generic/ciduser_form.html +++ b/generic/templates/generic/ciduser_form.html @@ -29,7 +29,7 @@

{% with object.get_cid_exams as exam_map %} - {% for exam_type, exams in exam_map.items %} + {% for exam_type, exams in exam_map %}

{{exam_type}}