"""Auth API tests.""" import pytest from httpx import AsyncClient class TestRegister: @pytest.mark.asyncio async def test_register_success(self, client: AsyncClient): resp = await client.post("/api/v1/auth/register", json={ "username": "owner1", "email": "owner@test.local", "password": "Pass1234", }) assert resp.status_code == 201 data = resp.json() assert data["username"] == "owner1" assert data["role"] == "owner" assert data["is_approved"] is True @pytest.mark.asyncio async def test_register_duplicate(self, client: AsyncClient): resp = await client.post("/api/v1/auth/register", json={ "username": "owner1", "email": "another@test.local", "password": "Pass1234", }) assert resp.status_code == 409 assert "Username" in resp.json()["detail"] @pytest.mark.asyncio async def test_register_second_user_is_viewer(self, client: AsyncClient): resp = await client.post("/api/v1/auth/register", json={ "username": "viewer1", "email": "viewer@test.local", "password": "Pass1234", }) assert resp.status_code == 201 data = resp.json() assert data["role"] == "viewer" assert data["is_approved"] is False class TestLogin: @pytest.mark.asyncio async def test_login_success(self, client: AsyncClient): resp = await client.post("/api/v1/auth/login", json={ "username": "owner1", "password": "Pass1234", }) assert resp.status_code == 200 data = resp.json() assert "access_token" in data assert data["token_type"] == "bearer" @pytest.mark.asyncio async def test_login_wrong_password(self, client: AsyncClient): resp = await client.post("/api/v1/auth/login", json={ "username": "owner1", "password": "wrongpass", }) assert resp.status_code == 401 @pytest.mark.asyncio async def test_login_locked(self, client: AsyncClient): # Fail 4 more times (already failed once above) → total 5 failures for _ in range(4): await client.post("/api/v1/auth/login", json={ "username": "owner1", "password": "wrongpass", }) resp = await client.post("/api/v1/auth/login", json={ "username": "owner1", "password": "wrongpass", }) assert resp.status_code == 423 class TestAuthGuard: @pytest.mark.asyncio async def test_require_auth_no_token(self, client: AsyncClient): resp = await client.post("/api/v1/auth/refresh") assert resp.status_code == 401 @pytest.mark.asyncio async def test_viewer_cannot_manage_users(self, client: AsyncClient): # Login as viewer1 → token login = await client.post("/api/v1/auth/login", json={ "username": "viewer1", "password": "Pass1234", }) token = login.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} resp = await client.get("/api/v1/users", headers=headers) assert resp.status_code == 403