"""Integration tests for NAVI_AUTH_ENABLED=false mode."""
import pytest
from fastapi.testclient import TestClient
from navi.auth import User
from navi.core.registry import BackendRegistry
from navi.core.session import InMemorySessionStore
from navi.main import app
from tests.conftest_factory import FakeConnection, FakeLLMBackend, FakePool, make_profile_registry, make_registry_with_tools
@pytest.fixture
def no_auth_client(monkeypatch):
"""FastAPI TestClient with auth disabled and real auth dependencies."""
import navi.config as _config
new_settings = _config.Settings(
database_url="postgresql://fake",
navi_auth_enabled=False,
)
# Patch settings everywhere it is imported as a module-level name.
monkeypatch.setattr("navi.config.settings", new_settings)
monkeypatch.setattr("navi.auth.deps.settings", new_settings)
monkeypatch.setattr("navi.api.routes.auth.settings", new_settings)
monkeypatch.setattr("navi.api.routes.sessions.settings", new_settings)
store = InMemorySessionStore()
profiles = make_profile_registry()
tools = make_registry_with_tools()
backends = BackendRegistry()
backends.register("ollama", FakeLLMBackend())
_fake_conn = FakeConnection()
_fake_pool = FakePool(_fake_conn)
async def _fake_get_pool():
return _fake_pool
store._get_pool = _fake_get_pool
store._pool = _fake_pool
from tests.conftest_factory import make_scheduler_with_pool
_fake_scheduler = make_scheduler_with_pool(_fake_conn)
from navi.core.container import AppContainer
container = AppContainer(
database=None,
memory_store=None,
session_store=store,
kv_store=None,
scheduler=_fake_scheduler,
tool_registry=tools,
profile_registry=profiles,
backend_registry=backends,
cp_registry=None,
workers=[],
mcp_manager=None,
)
fake_agent = object() # routes requiring an agent are not exercised here
container._agent = fake_agent
app.state.container = container
from navi.api.deps import set_container
set_container(container)
# Clear any auth overrides left by other fixtures in this app instance.
for dep in (
"get_current_user",
"get_current_user_ws",
"require_user",
"require_admin",
"require_permission",
):
app.dependency_overrides.pop(getattr(__import__("navi.api.deps", fromlist=[dep]), dep), None)
# Patch WebSocket user resolver at module level so the real function sees disabled auth.
from navi.auth import deps as auth_deps_mod
original_get_current_user_ws = auth_deps_mod.get_current_user_ws
monkeypatch.setattr(auth_deps_mod, "get_current_user_ws", original_get_current_user_ws)
return TestClient(app), store
class TestNoAuthStatus:
def test_auth_status_reports_disabled(self, no_auth_client):
client, _ = no_auth_client
response = client.get("/auth/status")
assert response.status_code == 200
data = response.json()
assert data["enabled"] is False
assert data["configured"] is False
class TestNoAuthSessions:
@pytest.mark.anyio
async def test_create_session_without_auth(self, no_auth_client):
client, store = no_auth_client
response = client.post("/sessions", json={"profile_id": "secretary"})
assert response.status_code == 201
data = response.json()
assert "session_id" in data
assert data["profile_id"] == "secretary"
session = await store.get(data["session_id"])
assert session is not None
assert session.user_id == "anonymous"
@pytest.mark.anyio
async def test_list_sessions_without_auth(self, no_auth_client):
client, store = no_auth_client
create_resp = client.post("/sessions", json={"profile_id": "secretary"})
session_id = create_resp.json()["session_id"]
response = client.get("/sessions")
assert response.status_code == 200
sessions = response.json()
assert any(s["session_id"] == session_id for s in sessions)