"""Integration tests for GET/PUT /api/avatar/loadout. Hits the real app against the configured Postgres (same contract as the other integration tests -- migrations applied first). """ import pytest from fastapi.testclient import TestClient from app.main import app from app.models.avatar_loadout import DEFAULT_LOADOUT def _auth_headers(client: TestClient, username: str) -> dict: resp = client.post( "/api/auth/register", json={ "username": username, "email": f"{username}@example.com", "password": "secret123", "date_of_birth": "1990-01-01", }, ) assert resp.status_code == 201, resp.text return {"Authorization": f"Bearer {resp.json()['access_token']}"} class TestGetLoadout: def test_new_user_gets_the_default(self): client = TestClient(app) headers = _auth_headers(client, "av_default") resp = client.get("/api/avatar/loadout", headers=headers) assert resp.status_code == 200 body = resp.json() assert body["is_default"] is True assert body["data"] == DEFAULT_LOADOUT def test_requires_auth(self): client = TestClient(app) assert client.get("/api/avatar/loadout").status_code == 401 class TestPutLoadout: def test_save_then_read_back(self): client = TestClient(app) headers = _auth_headers(client, "av_save") loadout = { "base_body": "base_human_male_01", "slots": {"hair": "hair_mohawk_01", "accessory": ["accessory_belt_01"]}, "skin_tone": {"r": 0.8, "g": 0.6, "b": 0.5, "a": 1.0}, } put = client.put("/api/avatar/loadout", headers=headers, json={"data": loadout}) assert put.status_code == 200, put.text assert put.json()["is_default"] is False got = client.get("/api/avatar/loadout", headers=headers) assert got.status_code == 200 assert got.json()["is_default"] is False assert got.json()["data"] == loadout def test_put_is_idempotent_replace(self): client = TestClient(app) headers = _auth_headers(client, "av_replace") client.put( "/api/avatar/loadout", headers=headers, json={"data": {"base_body": "base_human_male_01", "slots": {"hair": "hair_mohawk_01"}}}, ) second = {"base_body": "base_human_male_01", "slots": {"chest": "chest_bandit_01"}} client.put("/api/avatar/loadout", headers=headers, json={"data": second}) got = client.get("/api/avatar/loadout", headers=headers) assert got.json()["data"] == second def test_rejects_missing_base_body(self): client = TestClient(app) headers = _auth_headers(client, "av_nobase") resp = client.put("/api/avatar/loadout", headers=headers, json={"data": {"slots": {}}}) assert resp.status_code == 422 def test_rejects_non_object_slots(self): client = TestClient(app) headers = _auth_headers(client, "av_badslots") resp = client.put( "/api/avatar/loadout", headers=headers, json={"data": {"base_body": "base_human_male_01", "slots": "nope"}}, ) assert resp.status_code == 422 def test_requires_auth(self): client = TestClient(app) resp = client.put("/api/avatar/loadout", json={"data": {"base_body": "x", "slots": {}}}) assert resp.status_code == 401