odysseus/tests/test_model_helper_owner_scope.py
Tal.Yuan bb719f217a
refactor(routes): move document domain into routes/document/ subpackage (#5885)
Slice 2m of the route-domain reorganization (#4082/#4071, per
specs/architecture-runtime-inventory.md §6.3). Moves document_routes.py
(1810 lines) and document_helpers.py (243 lines) into routes/document/,
leaving backward-compat sys.modules shims at the old paths. Pure file
reorganization, no behavior change.

Both shims use sys.modules replacement so the `import ... as droutes` +
`droutes.SessionLocal = ...` / `monkeypatch.setattr(droutes, ...)` pattern
in multiple tests, and the `sys.modules.pop("routes.document_helpers")` +
re-import pattern in test_security_regressions.py, all reach the canonical
modules.

The canonical document_routes.py imports helpers from the canonical path
(routes.document.document_helpers), not the legacy shim.

Three source-introspection test sites repointed to the new canonical path:
- test_imap_mailbox_quoting.py
- test_model_helper_owner_scope.py
- test_vision_owner_scope.py (shared with other domains; document entry repointed)

Adds tests/test_document_routes_shim.py to pin the sys.modules shim contract
for both modules.

Verified: compileall clean; full suite 4789 passed, 3 skipped.
2026-08-04 03:54:55 -06:00

45 lines
1.9 KiB
Python

"""Model-assisted route helpers must resolve endpoints with owner scope."""
import ast
from pathlib import Path
def _function_source(path: str, name: str) -> str:
source = Path(path).read_text(encoding="utf-8")
tree = ast.parse(source)
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.name == name:
return ast.get_source_segment(source, node) or ""
raise AssertionError(f"{name} not found in {path}")
def test_document_ai_tidy_resolves_with_owner_scope():
body = _function_source("routes/document/document_routes.py", "ai_tidy_documents")
assert "resolve_task_endpoint(owner=user or None)" in body
assert 'resolve_endpoint("default", owner=user or None)' in body
def test_calendar_quick_parse_resolves_with_owner_scope():
body = _function_source("routes/calendar_routes.py", "quick_parse")
assert "owner = _require_user(request)" in body
assert 'resolve_endpoint("utility", owner=owner or None)' in body
assert 'resolve_endpoint("default", owner=owner or None)' in body
def test_task_parse_resolves_with_owner_scope():
body = _function_source("routes/task_routes.py", "parse_task")
assert "user = _owner(request)" in body
assert 'resolve_endpoint("utility", owner=user or None)' in body
assert 'resolve_endpoint("default", owner=user or None)' in body
def test_history_compact_resolves_with_owner_scope():
body = _function_source("routes/history/history_routes.py", "compact_session")
assert "owner = effective_user(request)" in body
assert 'resolve_endpoint("utility", owner=owner or None)' in body
def test_note_reminder_synthesis_resolves_with_owner_scope():
body = _function_source("routes/note/note_routes.py", "dispatch_reminder")
assert 'resolve_endpoint("utility", owner=owner or None)' in body
assert 'resolve_endpoint("default", owner=owner or None)' in body