|
# 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"])
|