Push V1 app
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
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"
|
||||
Reference in New Issue
Block a user