Compare commits

..
Author SHA1 Message Date
Alexandre Teixeira d237c3fbba perf(tests): reuse immutable admin auth configuration 2026-10-29 17:35:59 +00:00
3 changed files with 36 additions and 12 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
# Optional dependencies — install only if you use the corresponding feature. # Optional dependencies — install only if you use the corresponding feature.
# Local OCR for screenshots, scans, labels, and coordinate-grounded text extraction. # Local OCR for screenshots, scans, labels, and coordinate-grounded text extraction.
rapidocr==3.10.0 rapidocr==3.9.2
onnxruntime>=1.31.0,<2 onnxruntime>=1.20,<2
# The app handles their absence gracefully (clear error message on first use). # The app handles their absence gracefully (clear error message on first use).
# #
# Note: chromadb-client + fastembed moved to requirements.txt — RAG, semantic # Note: chromadb-client + fastembed moved to requirements.txt — RAG, semantic
@@ -46,7 +46,7 @@ PyMuPDF
# magika (onnxruntime), already a core dep via fastembed. We avoid the # magika (onnxruntime), already a core dep via fastembed. We avoid the
# [all]/Azure/audio extras (cloud + heavy). Pinned to a release >30 days old per # [all]/Azure/audio extras (cloud + heavy). Pinned to a release >30 days old per
# the dependency-age discussion in issue #485. # the dependency-age discussion in issue #485.
markitdown[docx,pptx,xlsx,xls]==0.1.9 markitdown[docx,pptx,xlsx,xls]==0.1.6
# Photoshop PSD opening / flattened previews / layer inspection. # Photoshop PSD opening / flattened previews / layer inspection.
psd-tools psd-tools
+5 -5
View File
@@ -5,9 +5,9 @@ python-dotenv
httpx httpx
# HTTPS clients using certifi must distrust the compromised eMudhra CA paths. # HTTPS clients using certifi must distrust the compromised eMudhra CA paths.
certifi>=2026.10.23 certifi>=2026.10.23
httpcore>=1.0.9,<2.0 httpcore>=1.0,<2.0
pydantic>=2.14.1 pydantic>=2.13.4
pydantic-settings>=2.16.1 pydantic-settings>=2.14.1
SQLAlchemy SQLAlchemy
pypdf pypdf
pypdfium2 pypdfium2
@@ -25,7 +25,7 @@ numpy
# ChromaDB service); fastembed runs local ONNX embeddings. # ChromaDB service); fastembed runs local ONNX embeddings.
chromadb-client chromadb-client
# gRPC vendors independent roots; 1.84.1 removes the incident trust anchors. # gRPC vendors independent roots; 1.84.1 removes the incident trust anchors.
grpcio>=1.85.0 grpcio>=1.84.1
fastembed>=0.9.1 fastembed>=0.9.1
youtube-transcript-api youtube-transcript-api
yt-dlp yt-dlp
@@ -51,7 +51,7 @@ bcrypt
# Built-in servers use the v1 low-level Server decorator API. MCP SDK v2 is a # Built-in servers use the v1 low-level Server decorator API. MCP SDK v2 is a
# breaking rewrite, so keep fresh installs on the maintained v1 line until the # breaking rewrite, so keep fresh installs on the maintained v1 line until the
# servers are migrated together. # servers are migrated together.
mcp<3 mcp<2
pyotp pyotp
qrcode[pil] qrcode[pil]
croniter croniter
+28 -4
View File
@@ -14,12 +14,22 @@ from routes.auth_routes import SESSION_COOKIE
from tests.helpers.database import disposable_database from tests.helpers.database import disposable_database
@pytest.fixture @pytest.fixture(scope="module")
def authenticated_app(tmp_path, monkeypatch): def auth_configuration(tmp_path_factory):
monkeypatch.setenv("AUTH_ENABLED", "true") """Hash real fixture passwords once; only immutable bytes are reused."""
auth = AuthManager(str(tmp_path / "auth.json")) path = tmp_path_factory.mktemp("admin-auth-seed") / "auth.json"
auth = AuthManager(str(path))
for user, admin in (("member", False), ("admin", True)): for user, admin in (("member", False), ("admin", True)):
assert auth.create_user(user, "disposable-test-password", is_admin=admin) assert auth.create_user(user, "disposable-test-password", is_admin=admin)
return path.read_bytes()
@pytest.fixture
def authenticated_app(tmp_path, monkeypatch, auth_configuration):
monkeypatch.setenv("AUTH_ENABLED", "true")
path = tmp_path / "auth.json"
path.write_bytes(auth_configuration)
auth = AuthManager(str(path))
app = FastAPI() app = FastAPI()
app.state.auth_manager = auth app.state.auth_manager = auth
@@ -133,3 +143,17 @@ def test_diagnostics_require_real_admin_before_sensitive_work(
for operation in (stats, rag.get_stats, research.call_research_service, for operation in (stats, rag.get_stats, research.call_research_service,
extract_id, transcript, collect, read_log): extract_id, transcript, collect, read_log):
operation.assert_not_called() operation.assert_not_called()
@pytest.mark.parametrize("instance", [0, 1])
def test_authenticated_fixture_has_private_users_sessions_and_file(authenticated_app, instance):
app, client_for = authenticated_app
auth = app.state.auth_manager
assert set(auth.users) == {"member", "admin"}
assert not auth._sessions
with client_for("member") as client:
assert auth.get_username_for_token(client.cookies.get(SESSION_COOKIE)) == "member"
assert auth.create_user("fixture-local", "disposable-test-password")
# Both parameter cases mutate their own file. Any shared manager, mutable
# users/sessions or written-back seed makes the next case fail, in any order.
assert "fixture-local" in auth.users