"""Integration tests for authentication endpoints.""" import pytest from httpx import AsyncClient class TestAuthentication: """Test suite for authentication endpoints.""" @pytest.mark.asyncio async def test_register_user(self, client: AsyncClient): """Test user registration.""" user_data = { "email": "newuser@example.com", "password": "SecurePass123!", "name": "New User" } response = await client.post("/api/v1/auth/register", json=user_data) assert response.status_code == 201 data = response.json() assert data["email"] == user_data["email"] assert data["name"] == user_data["name"] assert data["role"] == "engineer" assert "id" in data assert "password" not in data # Password should not be returned @pytest.mark.asyncio async def test_register_duplicate_email( self, client: AsyncClient, test_user: dict ): """Test that registering with duplicate email fails.""" user_data = { "email": test_user["email"], # Use existing email "password": "AnotherPass123!", "name": "Another User" } response = await client.post("/api/v1/auth/register", json=user_data) assert response.status_code == 400 assert "already registered" in response.json()["detail"].lower() @pytest.mark.asyncio async def test_login_json(self, client: AsyncClient, test_user: dict): """Test JSON login endpoint.""" login_data = { "email": test_user["email"], "password": test_user["password"] } response = await client.post("/api/v1/auth/login/json", json=login_data) 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_login_invalid_credentials( self, client: AsyncClient, test_user: dict ): """Test login with wrong password.""" login_data = { "email": test_user["email"], "password": "WrongPassword123!" } response = await client.post("/api/v1/auth/login/json", json=login_data) assert response.status_code == 401 assert "incorrect" in response.json()["detail"].lower() @pytest.mark.asyncio async def test_get_current_user( self, client: AsyncClient, auth_headers: dict, test_user: dict ): """Test getting current authenticated user.""" response = await client.get("/api/v1/auth/me", headers=auth_headers) assert response.status_code == 200 data = response.json() assert data["email"] == test_user["email"] assert "password" not in data @pytest.mark.asyncio async def test_get_current_user_unauthorized(self, client: AsyncClient): """Test that unauthenticated request fails.""" response = await client.get("/api/v1/auth/me") assert response.status_code == 401 @pytest.mark.asyncio async def test_register_with_role_field_ignored(self, client: AsyncClient): """Test that sending a role field at registration is ignored — always engineer.""" user_data = { "email": "hacker@example.com", "password": "HackerPass123!", "name": "Hacker", "role": "admin" } response = await client.post("/api/v1/auth/register", json=user_data) assert response.status_code == 201 data = response.json() assert data["role"] == "engineer" @pytest.mark.asyncio async def test_register_default_role_is_engineer(self, client: AsyncClient): """Test that omitting role defaults to engineer.""" user_data = { "email": "default@example.com", "password": "DefaultPass123!", "name": "Default User" } response = await client.post("/api/v1/auth/register", json=user_data) assert response.status_code == 201 assert response.json()["role"] == "engineer"