Files
qtalker---/backend/tests/test_auth_guest.py
Indiana f5320fcdec feat: guest passage — slip through as a wanderer
POST /auth/guest mints a real user row (wanderer-<4 hex>, collision
retry, unusable random password) and issues the normal session cookie,
per-IP rate limited at 5/hour. EnterPage gains the guest action;
the séance shows a dismissible claim-a-name note for wanderer- users.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 17:18:16 +00:00

61 lines
2.0 KiB
Python

import pytest
import app.routes.auth as auth_module
@pytest.fixture(autouse=True)
def _reset_guest_limiter():
# The limiter is module-level state; a previous test's hits would bleed
# into the next one's per-IP budget.
auth_module.guest_limiter._hits.clear()
yield
@pytest.mark.asyncio
async def test_guest_creates_wanderer_and_cookie_works_on_me(client):
response = await client.post("/auth/guest")
assert response.status_code == 201
body = response.json()
assert body["username"].startswith("wanderer-")
assert "password" not in body
assert "qm_session" in response.cookies
me_resp = await client.get("/auth/me")
assert me_resp.status_code == 200
assert me_resp.json()["username"] == body["username"]
@pytest.mark.asyncio
async def test_guest_cannot_login_with_any_password(client):
response = await client.post("/auth/guest")
username = response.json()["username"]
login_resp = await client.post(
"/auth/login", json={"username": username, "password": "anythingatall"}
)
assert login_resp.status_code == 401
@pytest.mark.asyncio
async def test_guest_rate_limit_fires_per_ip(client):
for _ in range(5):
response = await client.post("/auth/guest")
assert response.status_code == 201
response = await client.post("/auth/guest")
assert response.status_code == 429
@pytest.mark.asyncio
async def test_guest_username_collision_retries(client, monkeypatch):
taken_resp = await client.post("/auth/guest")
taken = taken_resp.json()["username"].removeprefix("wanderer-")
# First attempt collides with the existing wanderer; the retry must land
# on the fresh suffix instead of erroring out.
suffixes = iter([taken, "f4ee"])
monkeypatch.setattr(
auth_module.secrets, "token_hex", lambda n: next(suffixes)
)
response = await client.post("/auth/guest")
assert response.status_code == 201
assert response.json()["username"] == "wanderer-f4ee"