Quiiz system
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
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
|
||||
)
|
||||
Reference in New Issue
Block a user