"""Tests for Customers API using FastAPI TestClient (no live server required).""" import os import uuid from datetime import datetime import pytest from fastapi.testclient import TestClient # Ensure required env vars for app import/config os.environ.setdefault("SECRET_KEY", "x" * 32) os.environ.setdefault("DATABASE_URL", "sqlite:////tmp/delphi_test.sqlite") from app.main import app # noqa: E402 from app.auth.security import get_current_user # noqa: E402 @pytest.fixture(scope="module") def client(): # Override auth to bypass JWT for these tests app.dependency_overrides[get_current_user] = lambda: { "id": "test", "username": "tester", "is_admin": True, "is_active": True, } try: yield TestClient(app) finally: app.dependency_overrides.pop(get_current_user, None) def test_customers_crud_and_queries(client: TestClient): unique_id = f"TEST-{uuid.uuid4().hex[:8]}" # List (empty or not, but should 200) resp = client.get("/api/customers/?limit=5") assert resp.status_code == 200 assert isinstance(resp.json(), list) # Create payload = { "id": unique_id, "last": "Doe", "first": "John", "city": "Dallas", "abrev": "TX", "email": "john.doe@example.com", "memo": "Created by pytest", } resp = client.post("/api/customers/", json=payload) assert resp.status_code == 200 body = resp.json() assert body["id"] == unique_id assert body["last"] == "Doe" # Add phones for phone in ("(214) 555-0100", "(214) 555-0101"): resp = client.post( f"/api/customers/{unique_id}/phones", json={"location": "Office", "phone": phone}, ) assert resp.status_code == 200 # Retrieve and assert phones present resp = client.get(f"/api/customers/{unique_id}") assert resp.status_code == 200 customer = resp.json() assert customer["id"] == unique_id assert len(customer.get("phone_numbers", [])) >= 2 # Search by last name resp = client.get("/api/customers/?search=Doe") assert resp.status_code == 200 assert any(c["id"] == unique_id for c in resp.json()) # Phone search resp = client.get("/api/customers/search/phone", params={"phone": "214"}) assert resp.status_code == 200 assert isinstance(resp.json(), list) # Stats endpoint returns expected fields resp = client.get("/api/customers/stats") assert resp.status_code == 200 stats = resp.json() assert {"total_customers", "total_phone_numbers", "customers_with_email", "group_breakdown"} <= set(stats.keys()) # Update resp = client.put( f"/api/customers/{unique_id}", json={"memo": f"Updated at {datetime.utcnow().isoformat()}"}, ) assert resp.status_code == 200 # Cleanup resp = client.delete(f"/api/customers/{unique_id}") assert resp.status_code == 200 def test_pages_and_health(client: TestClient): # Health resp = client.get("/health") assert resp.status_code == 200 assert resp.json().get("status") == "healthy" # Customers page should load HTML resp = client.get("/customers") assert resp.status_code in (200, 401, 403) or resp.headers.get("content-type", "").startswith("text/html")