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 sbas.views import GenericExamViews as SbaExamViews from sbas.models import Category, UserAnswer, Exam, Question from generic.models import CidUser, CidUserGroup, UserUserGroup from rad.tests.test_helpers import AssertNotFound, ExamTester, create_cid_user_and_groups, create_exam from django.contrib.auth.models import User APP_NAME = "sbas" 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: best_answer = "a" else: best_answer = answer question: Question = Question.objects.create( stem="test question stem", a_answer="question a text", a_feedback="question a feedback", b_answer="question b text", b_feedback="question b feedback", c_answer="question c text", c_feedback="question c feedback", d_answer="question d text", d_feedback="question d feedback", e_answer="question e text", e_feedback="question e feedback", best_answer=best_answer, ) question.exams.set([exam]) return question def test_exams(db, client): create_category(db) exam_tester = ExamTester(db, client, APP_NAME, SbaExamViews) 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, "answer": "a", "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_answer()) # 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, answer = "a", cid=cid_user.cid, exam=exam, ) else: cid_user_answer = UserAnswer( question=extra_question, answer = "a", user=exam_tester.current_user, exam=exam, ) cid_user_answer.save() exam_tester.check_cid_scores_user_page2() users_tested = users_tested + 1