# retoor import json import time import requests from tests.conftest import BASE_URL JSON = {"Accept": "application/json"} _counter = [0] CHOICE = { "kind": "single_choice", "prompt": "Which journal mode allows concurrent readers?", "points": 2, "options": "DELETE\nWAL\nMEMORY", "correct_indexes": "1", } NUMERIC = { "kind": "numeric", "prompt": "How many bytes are in a kibibyte?", "points": 1, "numeric_value": "1024", "numeric_tolerance": "0", } TRUE_FALSE = { "kind": "true_false", "prompt": "A partial index can carry a WHERE clause.", "points": 1, "correct_boolean": "1", } FREE_TEXT = { "kind": "free_text", "prompt": "Why does a partial index help here?", "points": 3, "expected_answer": "It keeps the live query off a one bucket index.", "grading_criteria": "Accept any answer that mentions the planner.", } DOCUMENT = { "title": "Imported quiz", "description": "Created from a document.", "settings": {"reveal_answers": True, "pass_percent": 60, "allow_review": True}, "questions": [ { "kind": "single_choice", "prompt": "Which journal mode allows concurrent readers?", "points": 2, "options": [{"label": "DELETE"}, {"label": "WAL", "is_correct": True}], }, { "kind": "numeric", "prompt": "How many bytes are in a kibibyte?", "points": 1, "numeric_value": 1024, }, ], } def signup(prefix="qz"): _counter[0] += 1 name = f"{prefix}{int(time.time() * 1000)}{_counter[0]}" session = requests.Session() session.post( f"{BASE_URL}/auth/signup", data={ "username": name, "email": f"{name}@t.dev", "password": "secret123", "confirm_password": "secret123", }, allow_redirects=True, ) return session, name def create_quiz(session, title="Test quiz", **settings): payload = {"title": title, "description": "A quiz."} payload.update(settings) response = session.post(f"{BASE_URL}/quizzes/create", data=payload, headers=JSON) return response.json()["data"]["slug"] def add_question(session, slug, payload): return session.post(f"{BASE_URL}/quizzes/{slug}/questions", data=payload, headers=JSON) def publish(session, slug): return session.post(f"{BASE_URL}/quizzes/{slug}/publish", headers=JSON) def build_published(session, questions=(CHOICE, NUMERIC), title="Playable quiz", **settings): slug = create_quiz(session, title, **settings) for question in questions: add_question(session, slug, question) publish(session, slug) return slug def import_quiz(session, document=None): payload = {"document": json.dumps(document or DOCUMENT)} response = session.post(f"{BASE_URL}/quizzes/import", data=payload, headers=JSON) return response def start_attempt(session, slug): response = session.post(f"{BASE_URL}/quizzes/{slug}/attempts", headers=JSON) return response.json()["data"]["uid"] def attempt_state(session, slug, attempt_uid): return session.get( f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}", headers=JSON ).json() def answer_correctly(session, slug, attempt_uid, question): payload = {"question_uid": question["uid"]} if question["kind"] == "single_choice": correct = next( (option["uid"] for option in question["options"] if option.get("is_correct")), None ) payload["option_uids"] = correct or question["options"][1]["uid"] elif question["kind"] == "numeric": payload["answer_text"] = "1024" elif question["kind"] == "true_false": payload["answer_text"] = "true" else: payload["answer_text"] = "the planner picks a bad index for live rows" return session.post( f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}/answer", data=payload, headers=JSON )