forked from retoor/devplacepy
Quiiz system
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import requests
|
||||
|
||||
from tests.api.quizzes._helpers import (
|
||||
JSON,
|
||||
NUMERIC,
|
||||
answer_correctly,
|
||||
attempt_state,
|
||||
build_published,
|
||||
create_quiz,
|
||||
signup,
|
||||
start_attempt,
|
||||
)
|
||||
from tests.conftest import BASE_URL
|
||||
|
||||
|
||||
def _play(session, slug, correct=True):
|
||||
attempt_uid = start_attempt(session, slug)
|
||||
state = attempt_state(session, slug, attempt_uid)
|
||||
for question in state["attempt"]["questions"]:
|
||||
if correct:
|
||||
answer_correctly(session, slug, attempt_uid, question)
|
||||
else:
|
||||
session.post(
|
||||
f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}/answer",
|
||||
data={"question_uid": question["uid"], "answer_text": "-1"},
|
||||
headers=JSON,
|
||||
)
|
||||
session.post(f"{BASE_URL}/quizzes/{slug}/attempts/{attempt_uid}/finish", headers=JSON)
|
||||
|
||||
|
||||
def _entries(slug, limit=None):
|
||||
url = f"{BASE_URL}/quizzes/{slug}/leaderboard"
|
||||
if limit is not None:
|
||||
url = f"{url}?limit={limit}"
|
||||
return requests.get(url, headers=JSON).json()["entries"]
|
||||
|
||||
|
||||
def test_the_leaderboard_is_public(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Public board quiz")
|
||||
response = requests.get(f"{BASE_URL}/quizzes/{slug}/leaderboard", headers=JSON)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["entries"] == []
|
||||
|
||||
|
||||
def test_the_leaderboard_reports_its_quiz(app_server, seeded_db):
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board uid quiz")
|
||||
refresh_snapshot()
|
||||
quiz = get_table("quizzes").find_one(slug=slug)
|
||||
payload = requests.get(f"{BASE_URL}/quizzes/{slug}/leaderboard", headers=JSON).json()
|
||||
assert payload["quiz_uid"] == quiz["uid"]
|
||||
|
||||
|
||||
def test_a_completed_attempt_appears(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board entry quiz")
|
||||
player, player_name = signup()
|
||||
_play(player, slug)
|
||||
entries = _entries(slug)
|
||||
assert len(entries) == 1
|
||||
assert entries[0]["user"]["username"] == player_name
|
||||
assert entries[0]["score_percent"] == 100.0
|
||||
assert entries[0]["rank"] == 1
|
||||
|
||||
|
||||
def test_an_unfinished_attempt_never_appears(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board unfinished quiz")
|
||||
player, _ = signup()
|
||||
start_attempt(player, slug)
|
||||
assert _entries(slug) == []
|
||||
|
||||
|
||||
def test_the_best_score_ranks_first(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board ranking quiz")
|
||||
weak, weak_name = signup()
|
||||
strong, strong_name = signup()
|
||||
_play(weak, slug, correct=False)
|
||||
_play(strong, slug, correct=True)
|
||||
entries = _entries(slug)
|
||||
assert entries[0]["user"]["username"] == strong_name
|
||||
assert entries[-1]["user"]["username"] == weak_name
|
||||
|
||||
|
||||
def test_ranks_are_gapless(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board gapless quiz")
|
||||
for _ in range(3):
|
||||
player, _ = signup()
|
||||
_play(player, slug)
|
||||
ranks = [entry["rank"] for entry in _entries(slug)]
|
||||
assert ranks == list(range(1, len(ranks) + 1))
|
||||
|
||||
|
||||
def test_the_limit_bounds_the_board(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board limit quiz")
|
||||
for _ in range(3):
|
||||
player, _ = signup()
|
||||
_play(player, slug)
|
||||
assert len(_entries(slug, limit=2)) == 2
|
||||
|
||||
|
||||
def test_the_pass_verdict_is_carried(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(
|
||||
owner, questions=(NUMERIC,), title="Board verdict quiz", pass_percent="50"
|
||||
)
|
||||
player, _ = signup()
|
||||
_play(player, slug)
|
||||
assert _entries(slug)[0]["passed"] is True
|
||||
|
||||
|
||||
def test_the_board_projects_users_through_the_safe_schema(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board safe user quiz")
|
||||
player, _ = signup()
|
||||
_play(player, slug)
|
||||
user = _entries(slug)[0]["user"]
|
||||
assert "email" not in user
|
||||
assert "api_key" not in user
|
||||
|
||||
|
||||
def test_the_authors_own_attempt_is_on_the_quiz_board(app_server, seeded_db):
|
||||
owner, owner_name = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board author quiz")
|
||||
_play(owner, slug)
|
||||
assert _entries(slug)[0]["user"]["username"] == owner_name
|
||||
|
||||
|
||||
def test_a_draft_board_is_hidden_from_a_guest(app_server, seeded_db):
|
||||
session, _ = signup()
|
||||
slug = create_quiz(session, "Board draft quiz")
|
||||
response = requests.get(f"{BASE_URL}/quizzes/{slug}/leaderboard", headers=JSON)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_the_detail_page_embeds_the_board(app_server, seeded_db):
|
||||
owner, _ = signup()
|
||||
slug = build_published(owner, questions=(NUMERIC,), title="Board embedded quiz")
|
||||
player, player_name = signup()
|
||||
_play(player, slug)
|
||||
payload = requests.get(f"{BASE_URL}/quizzes/{slug}", headers=JSON).json()
|
||||
assert any(entry["user"]["username"] == player_name for entry in payload["leaderboard"])
|
||||
Reference in New Issue
Block a user