import os from tests.conftest import client, get_admin_token, get_invite_token, ADMIN_PASSWORD # ── Auth tests ── def test_login_success(): resp = client.post("/api/auth/login", json={"username": "admin", "password": ADMIN_PASSWORD}) assert resp.status_code == 200 data = resp.json() assert "access_token" in data assert data["user"]["username"] == "admin" def test_login_wrong_password(): resp = client.post("/api/auth/login", json={"username": "admin", "password": "wrong"}) assert resp.status_code == 401 def test_login_wrong_username(): resp = client.post("/api/auth/login", json={"username": "nobody", "password": ADMIN_PASSWORD}) assert resp.status_code == 401 def test_me_unauthorized(): resp = client.get("/api/auth/me") assert resp.status_code == 401 def test_me_authorized(): token = get_admin_token() resp = client.get("/api/auth/me", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 assert resp.json()["username"] == "admin" # ── Invitation tests ── def test_register_with_invite(): invite_token = get_invite_token() resp = client.post("/api/auth/register", json={ "username": "newuser", "email": "new@test.com", "password": "NewPass123", "invite_token": invite_token, }) assert resp.status_code == 200 assert resp.json()["user"]["username"] == "newuser" def test_register_invalid_invite(): resp = client.post("/api/auth/register", json={ "username": "user2", "email": "u2@test.com", "password": "Pass1234", "invite_token": "invalid-token", }) assert resp.status_code == 400 def test_invite_reuse(): invite_token = get_invite_token() client.post("/api/auth/register", json={ "username": "reuse1", "email": "r1@test.com", "password": "Pass1234", "invite_token": invite_token, }) resp = client.post("/api/auth/register", json={ "username": "reuse2", "email": "r2@test.com", "password": "Pass1234", "invite_token": invite_token, }) # 400 = invitation déjà utilisée, 429 = rate limit (les deux empêchent la réutilisation) assert resp.status_code in (400, 429) # ── Drink CRUD tests ── def test_create_drink(): token = get_admin_token() resp = client.post("/api/drinks", json={ "name": "Château Test", "category": "wine", "rating": 4.5, }, headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 data = resp.json() assert data["name"] == "Château Test" assert data["category"] == "wine" def test_list_drinks(): token = get_admin_token() resp = client.get("/api/drinks", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 assert len(resp.json()) > 0 def test_update_drink(): token = get_admin_token() create_resp = client.post("/api/drinks", json={ "name": "Château Test", "category": "wine", }, headers={"Authorization": f"Bearer {token}"}) drink_id = create_resp.json()["id"] resp = client.put(f"/api/drinks/{drink_id}", json={ "name": "Château Updated", "rating": 5.0, }, headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 assert resp.json()["name"] == "Château Updated" assert resp.json()["rating"] == 5.0 def test_delete_drink(): token = get_admin_token() create_resp = client.post("/api/drinks", json={ "name": "Château Test", "category": "wine", }, headers={"Authorization": f"Bearer {token}"}) drink_id = create_resp.json()["id"] resp = client.delete(f"/api/drinks/{drink_id}", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 resp = client.get(f"/api/drinks/{drink_id}", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 404 def test_drink_owner_isolation(): token = get_admin_token() create_resp = client.post("/api/drinks", json={ "name": "Château Test", "category": "wine", }, headers={"Authorization": f"Bearer {token}"}) drink_id = create_resp.json()["id"] from database import SessionLocal from models import User from auth import hash_password, create_access_token db = SessionLocal() try: other = User(username="other", email="other@test.com", hashed_password=hash_password("Other123")) db.add(other) db.commit() db.refresh(other) other_token = create_access_token({"sub": str(other.id), "token_version": other.token_version}) finally: db.close() resp = client.get(f"/api/drinks/{drink_id}", headers={"Authorization": f"Bearer {other_token}"}) assert resp.status_code == 404 # ── Rate limiter test ── def test_rate_limit_blocks(): for _ in range(6): client.post("/api/auth/login", json={"username": "admin", "password": "wrong"}) resp = client.post("/api/auth/login", json={"username": "admin", "password": "wrong"}) assert resp.status_code == 429 # ── Logout test ── def test_logout_invalidates_token(): token = get_admin_token() resp = client.post("/api/auth/logout", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 200 resp = client.get("/api/auth/me", headers={"Authorization": f"Bearer {token}"}) assert resp.status_code == 401 # ── Health check ── def test_health(): resp = client.get("/api/health") assert resp.status_code == 200 assert resp.json()["status"] == "ok"