Files
erp-nutzfahrzeuge/backend/tests/test_auth.py
T

156 lines
5.1 KiB
Python
Raw Normal View History

"""Tests for auth endpoints: login, refresh, me."""
import pytest
from httpx import AsyncClient
from app.models.user import User
from app.utils.jwt import create_access_token, create_refresh_token
@pytest.mark.asyncio
async def test_login_valid_credentials(client: AsyncClient, admin_user: User):
"""POST /api/v1/auth/login with valid credentials returns 200 + JWT."""
response = await client.post("/api/v1/auth/login", json={
"email": "admin@test.com",
"password": "Admin12345!",
})
assert response.status_code == 200
data = response.json()
assert "access_token" in data
assert "refresh_token" in data
assert data["token_type"] == "bearer"
assert data["expires_in"] > 0
@pytest.mark.asyncio
async def test_login_invalid_password(client: AsyncClient, admin_user: User):
"""POST /api/v1/auth/login with wrong password returns 401."""
response = await client.post("/api/v1/auth/login", json={
"email": "admin@test.com",
"password": "WrongPassword!",
})
assert response.status_code == 401
data = response.json()
assert "error" in data["detail"]
@pytest.mark.asyncio
async def test_login_nonexistent_user(client: AsyncClient):
"""POST /api/v1/auth/login with unknown email returns 401."""
response = await client.post("/api/v1/auth/login", json={
"email": "nobody@test.com",
"password": "SomePassword!",
})
assert response.status_code == 401
@pytest.mark.asyncio
async def test_login_inactive_user(client: AsyncClient, inactive_user: User):
"""POST /api/v1/auth/login with deactivated account returns 401."""
response = await client.post("/api/v1/auth/login", json={
"email": "inactive@test.com",
"password": "Inactive123!",
})
assert response.status_code == 401
@pytest.mark.asyncio
async def test_login_invalid_email_format(client: AsyncClient):
"""POST /api/v1/auth/login with invalid email format returns 422."""
response = await client.post("/api/v1/auth/login", json={
"email": "not-an-email",
"password": "SomePassword!",
})
assert response.status_code == 422
@pytest.mark.asyncio
async def test_refresh_valid_token(client: AsyncClient, admin_user: User):
"""POST /api/v1/auth/refresh with valid refresh token returns new tokens."""
refresh_token = create_refresh_token(
user_id=str(admin_user.id),
role="admin",
email=admin_user.email,
lang=admin_user.language,
)
response = await client.post("/api/v1/auth/refresh", json={
"refresh_token": refresh_token,
})
assert response.status_code == 200
data = response.json()
assert "access_token" in data
assert "refresh_token" in data
assert data["token_type"] == "bearer"
@pytest.mark.asyncio
async def test_refresh_invalid_token(client: AsyncClient):
"""POST /api/v1/auth/refresh with invalid token returns 401."""
response = await client.post("/api/v1/auth/refresh", json={
"refresh_token": "invalid.token.here",
})
assert response.status_code == 401
@pytest.mark.asyncio
async def test_refresh_access_token_rejected(client: AsyncClient, admin_user: User):
"""POST /api/v1/auth/refresh with an access token (not refresh) returns 401."""
access_token = create_access_token(
user_id=str(admin_user.id),
role="admin",
email=admin_user.email,
lang=admin_user.language,
)
response = await client.post("/api/v1/auth/refresh", json={
"refresh_token": access_token,
})
assert response.status_code == 401
@pytest.mark.asyncio
async def test_get_me_with_valid_token(client: AsyncClient, admin_user: User, admin_token: str):
"""GET /api/v1/auth/me with valid JWT returns 200 + user object."""
response = await client.get(
"/api/v1/auth/me",
headers={"Authorization": f"Bearer {admin_token}"},
)
assert response.status_code == 200
data = response.json()
assert data["email"] == "admin@test.com"
assert data["role"] == "admin"
assert data["is_active"] is True
assert "password_hash" not in data
@pytest.mark.asyncio
async def test_get_me_without_token(client: AsyncClient):
"""GET /api/v1/auth/me without token returns 401."""
response = await client.get("/api/v1/auth/me")
assert response.status_code == 401
@pytest.mark.asyncio
async def test_get_me_with_invalid_token(client: AsyncClient):
"""GET /api/v1/auth/me with invalid token returns 401."""
response = await client.get(
"/api/v1/auth/me",
headers={"Authorization": "Bearer invalid.token.here"},
)
assert response.status_code == 401
@pytest.mark.asyncio
async def test_get_me_with_refresh_token(client: AsyncClient, admin_user: User):
"""GET /api/v1/auth/me with a refresh token (not access) returns 401."""
refresh_token = create_refresh_token(
user_id=str(admin_user.id),
role="admin",
email=admin_user.email,
lang=admin_user.language,
)
response = await client.get(
"/api/v1/auth/me",
headers={"Authorization": f"Bearer {refresh_token}"},
)
assert response.status_code == 401