from __future__ import annotations from fastapi.testclient import TestClient def test_profile_onboarding_consent_gender_age_no_birthday(client: TestClient) -> None: login = client.post("/api/v1/auth/dev-login", json={"nickname": "koala_kid"}) assert login.status_code == 200 token = login.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} # Without public_website_consent, creating a quiz is blocked blocked = client.post( "/api/v1/quizzes", headers=headers, json={"title": "Early Quiz", "description": "Test", "is_public": True, "questions": []}, ) assert blocked.status_code == 403 # Update profile with stylized animal, color, inclusive gender, age (no birthday) & consent updated = client.patch( "/api/v1/users/me", headers=headers, json={ "nickname": "koala_kid", "first_name": "Sam", "last_name": "Chen", "age": 16, "gender": "other", "gender_custom": "Demiboy", "avatar_animal": "koala", "avatar_color": "avatar-5", "public_website_consent": True, }, ) assert updated.status_code == 200 profile = updated.json() assert profile["onboarded"] is True assert profile["age"] == 16 assert "birthday" not in profile assert "birth_date" not in profile assert profile["gender"] == "other" assert profile["gender_custom"] == "Demiboy" assert profile["avatar_animal"] == "koala" assert profile["avatar_color"] == "avatar-5" assert profile["public_website_consent"] is True def test_api_key_lifecycle_and_expiration(client: TestClient) -> None: login = client.post("/api/v1/auth/dev-login", json={"nickname": "key_tester"}) token = login.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} client.patch( "/api/v1/users/me", headers=headers, json={"public_website_consent": True}, ) # Create API key create_resp = client.post( "/api/v1/users/me/api-keys", headers=headers, json={"name": "CLI Study Bot", "expires_in_days": 30}, ) assert create_resp.status_code == 201 key_data = create_resp.json() raw_key = key_data["raw_key"] key_id = key_data["id"] assert raw_key.startswith("tm_live_") assert key_data["is_active"] is True # Authenticate using X-API-Key header me_via_key = client.get("/api/v1/users/me", headers={"X-API-Key": raw_key}) assert me_via_key.status_code == 200 assert me_via_key.json()["nickname"] == "key_tester" # List keys should not leak raw_key list_resp = client.get("/api/v1/users/me/api-keys", headers=headers) assert list_resp.status_code == 200 listed = list_resp.json() assert len(listed) == 1 assert "raw_key" not in listed[0] assert listed[0]["last_used_at"] is not None # Expire old key expire_resp = client.post( f"/api/v1/users/me/api-keys/{key_id}/expire", headers=headers, ) assert expire_resp.status_code == 200 assert expire_resp.json()["is_active"] is False # Subsequent calls with the expired API key must fail with 401 revoked_check = client.get("/api/v1/users/me", headers={"X-API-Key": raw_key}) assert revoked_check.status_code == 401