"""Auth + session tests.""" from __future__ import annotations import os import pytest from fastapi.testclient import TestClient def _make_client(): # Ensure local mode + no bypass for these tests. os.environ["AUTH_MODE"] = "local" os.environ["DEV_AUTH_BYPASS"] = "false" from app.config import get_settings get_settings.cache_clear() # Re-import main so middleware picks up settings. import importlib import app.main as main_mod importlib.reload(main_mod) # base_url must be https so the Secure session cookie is sent back. return TestClient(main_mod.app, base_url="https://testserver") @pytest.fixture def client(): yield _make_client() def test_login_happy_path(client): r = client.post("/api/auth/login", json={"username": "admin", "password": "admin"}) assert r.status_code == 200, r.text body = r.json() assert body["ok"] is True assert body["username"] == "admin" # Session cookie present. assert "ud_session" in r.cookies def test_login_wrong_password(client): r = client.post("/api/auth/login", json={"username": "admin", "password": "nope"}) assert r.status_code == 401 assert r.json()["detail"] == "Invalid credentials" def test_me_requires_session(client): r = client.get("/api/auth/me") assert r.status_code == 401 def test_me_after_login(client): r = client.post("/api/auth/login", json={"username": "admin", "password": "admin"}) assert r.status_code == 200 r2 = client.get("/api/auth/me") assert r2.status_code == 200 assert r2.json()["username"] == "admin" def test_logout(client): client.post("/api/auth/login", json={"username": "admin", "password": "admin"}) r = client.post("/api/auth/logout") assert r.status_code == 204 def test_bypass_mode(): os.environ["DEV_AUTH_BYPASS"] = "true" from app.config import get_settings get_settings.cache_clear() import importlib import app.main as main_mod importlib.reload(main_mod) c = TestClient(main_mod.app, base_url="https://testserver") r = c.get("/api/auth/me") assert r.status_code == 200 assert r.json()["mode"] == "bypass" # Restore for any subsequent tests. os.environ["DEV_AUTH_BYPASS"] = "false" get_settings.cache_clear() importlib.reload(main_mod) def test_login_rate_limit(client): # 5/minute → 6th attempt should 429. last = None for _ in range(6): last = client.post("/api/auth/login", json={"username": "admin", "password": "wrong"}) assert last is not None assert last.status_code == 429