""" Unit tests for authentication, registration, token refresh, and profile endpoints. """ from __future__ import annotations import pytest from httpx import AsyncClient from sqlalchemy.ext.asyncio import AsyncSession @pytest.mark.asyncio async def test_health_check(client: AsyncClient): """Test health check status returns healthy.""" response = await client.get("/health") assert response.status_code == 200 data = response.json() assert data["status"] == "healthy" assert "deploy_mode" in data assert "llm_provider" in data @pytest.mark.asyncio async def test_root_endpoint(client: AsyncClient): """Test API root description.""" response = await client.get("/") assert response.status_code == 200 data = response.json() assert "Enterprise AI Copilot Platform" in data["name"] @pytest.mark.asyncio async def test_register_and_login_flow(client: AsyncClient, db_session: AsyncSession): """Test full registration and login workflow.""" # 1. Register a new user + tenant register_data = { "email": "test@company.com", "password": "SecretPassword123!", "full_name": "Test User", "tenant_name": "Test Organization" } response = await client.post("/api/v1/auth/register", json=register_data) assert response.status_code == 201, response.text reg_data = response.json() assert "user" in reg_data assert "tokens" in reg_data assert reg_data["user"]["email"] == "test@company.com" assert reg_data["user"]["role"] == "admin" # First user is Admin assert "access_token" in reg_data["tokens"] access_token = reg_data["tokens"]["access_token"] refresh_token = reg_data["tokens"]["refresh_token"] # 2. Login with email and password login_form = { "username": "test@company.com", "password": "SecretPassword123!" } response = await client.post("/api/v1/auth/login", data=login_form) assert response.status_code == 200, response.text login_data = response.json() assert "access_token" in login_data assert "refresh_token" in login_data # 3. Get profile with access token headers = {"Authorization": f"Bearer {access_token}"} response = await client.get("/api/v1/auth/me", headers=headers) assert response.status_code == 200, response.text me_data = response.json() assert me_data["email"] == "test@company.com" assert me_data["role"] == "admin" # 4. Refresh access token refresh_data = { "refresh_token": refresh_token } response = await client.post("/api/v1/auth/refresh", json=refresh_data) assert response.status_code == 200, response.text refreshed_data = response.json() assert "access_token" in refreshed_data assert "refresh_token" in refreshed_data # 5. Logout response = await client.post("/api/v1/auth/logout", headers=headers) assert response.status_code == 200 assert "Logged out successfully" in response.json()["message"] @pytest.mark.asyncio async def test_register_duplicate_email(client: AsyncClient): """Test that duplicate registrations fail with 409 conflict.""" register_data = { "email": "duplicate@company.com", "password": "SecretPassword123!", "full_name": "Test User", "tenant_name": "Test Organization" } # First registration response = await client.post("/api/v1/auth/register", json=register_data) assert response.status_code == 201 # Second registration with same email response = await client.post("/api/v1/auth/register", json=register_data) assert response.status_code == 409 data = response.json() assert data["detail"]["error"] == "email_exists" @pytest.mark.asyncio async def test_login_invalid_credentials(client: AsyncClient): """Test login fails with incorrect password.""" login_form = { "username": "wrong@company.com", "password": "IncorrectPassword" } response = await client.post("/api/v1/auth/login", data=login_form) assert response.status_code == 401 assert response.json()["detail"]["error"] == "invalid_credentials"