import uuid from fastapi.testclient import TestClient from app.main import app client = TestClient(app) def _unique_email() -> str: return f"test-{uuid.uuid4().hex}@example.com" def _register(email: str | None = None, password: str = "securepass1") -> tuple[str, dict]: address = email or _unique_email() response = client.post( "/api/auth/register", json={"email": address, "password": password, "full_name": "Test User"}, ) return address, response def test_register_login_and_me() -> None: email, register_response = _register() assert register_response.status_code == 201 token = register_response.json()["access_token"] assert token login_response = client.post("/api/auth/login", json={"email": email, "password": "securepass1"}) assert login_response.status_code == 200 assert login_response.json()["token_type"] == "bearer" me_response = client.get("/api/auth/me", headers={"Authorization": f"Bearer {token}"}) assert me_response.status_code == 200 body = me_response.json() assert body["email"] == email assert body["full_name"] == "Test User" assert body["is_active"] is True assert "hashed_password" not in body def test_register_duplicate_email() -> None: email, first = _register() assert first.status_code == 201 second = client.post( "/api/auth/register", json={"email": email, "password": "securepass1"}, ) assert second.status_code == 409 def test_register_password_too_short() -> None: response = client.post( "/api/auth/register", json={"email": _unique_email(), "password": "short"}, ) assert response.status_code == 422 def test_login_invalid_credentials() -> None: email, register_response = _register() assert register_response.status_code == 201 wrong_password = client.post("/api/auth/login", json={"email": email, "password": "wrongpassword"}) assert wrong_password.status_code == 401 unknown = client.post("/api/auth/login", json={"email": "nobody@example.com", "password": "securepass1"}) assert unknown.status_code == 401 def test_me_requires_auth() -> None: response = client.get("/api/auth/me") assert response.status_code == 401 def test_me_rejects_invalid_token() -> None: response = client.get("/api/auth/me", headers={"Authorization": "Bearer not-a-valid-jwt"}) assert response.status_code == 401 def test_passwords_are_hashed_in_database() -> None: from app.db.session import SessionLocal from app.services.users import get_user_by_email email, register_response = _register(password="anotherpass9") assert register_response.status_code == 201 db = SessionLocal() try: user = get_user_by_email(db, email) assert user is not None assert user.hashed_password != "anotherpass9" assert user.hashed_password.startswith("$2") finally: db.close()