mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 17:55:26 -04:00
refactor(constants): single source of truth for data dir (#3368)
* refactor(constants): single source of truth for data dir + merge core/src constants Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(contributing): use named src.constants for data paths, drop core/constants references Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -118,10 +118,11 @@ def test_pairing_payload_shape():
|
||||
|
||||
@pytest.mark.parametrize("payload", ["[]", '{"users": []}'])
|
||||
def test_find_admin_user_ignores_invalid_auth_shape(tmp_path, monkeypatch, payload):
|
||||
data_dir = tmp_path / "data"
|
||||
data_dir.mkdir()
|
||||
(data_dir / "auth.json").write_text(payload)
|
||||
monkeypatch.chdir(tmp_path)
|
||||
auth_file = tmp_path / "auth.json"
|
||||
auth_file.write_text(payload)
|
||||
# find_admin_user reads the import-time AUTH_FILE constant, so redirect that
|
||||
# rather than relying on cwd.
|
||||
monkeypatch.setattr(P, "AUTH_FILE", str(auth_file))
|
||||
|
||||
assert P.find_admin_user() is None
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
"""Guard: cookbook_state.json must be located via DATA_DIR, not hardcoded /app/data
|
||||
(which breaks native runs) or a relative os.environ fallback."""
|
||||
import pathlib
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
FILES = [
|
||||
"src/cookbook_serve_lifecycle.py",
|
||||
"src/builtin_actions.py",
|
||||
"routes/codex_routes.py",
|
||||
"routes/cookbook_routes.py",
|
||||
]
|
||||
|
||||
|
||||
def test_no_hardcoded_app_data_cookbook_state():
|
||||
for rel in FILES:
|
||||
text = (ROOT / rel).read_text(encoding="utf-8")
|
||||
for ln in text.splitlines():
|
||||
if ln.strip().startswith("#"):
|
||||
continue
|
||||
assert "/app/data/cookbook_state" not in ln, f"{rel}: hardcoded /app/data: {ln.strip()}"
|
||||
assert 'os.environ.get("DATA_DIR"' not in ln, f"{rel}: relative DATA_DIR env fallback: {ln.strip()}"
|
||||
|
||||
|
||||
def test_cookbook_state_uses_datadir_constant():
|
||||
# Each file that references cookbook_state.json should import the DATA_DIR constant.
|
||||
for rel in FILES:
|
||||
text = (ROOT / rel).read_text(encoding="utf-8")
|
||||
if "cookbook_state.json" in text:
|
||||
assert "from core.constants import DATA_DIR" in text, f"{rel}: missing DATA_DIR import"
|
||||
@@ -11,6 +11,16 @@ from fastapi import HTTPException
|
||||
from routes.research_routes import setup_research_routes
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _redirect_research_dir(tmp_path, monkeypatch):
|
||||
# Deep-research paths are resolved from an import-time constant now, so chdir
|
||||
# no longer redirects them. Point the constant the routes read at the temp dir.
|
||||
monkeypatch.setattr(
|
||||
"routes.research_routes.DEEP_RESEARCH_DIR",
|
||||
str(tmp_path / "data" / "deep_research"),
|
||||
)
|
||||
|
||||
|
||||
def _request(user: str):
|
||||
return SimpleNamespace(state=SimpleNamespace(current_user=user))
|
||||
|
||||
|
||||
@@ -946,7 +946,7 @@ def _import_mcp_routes():
|
||||
|
||||
def test_mcp_oauth_paths_resolve_under_data_dir(tmp_path, monkeypatch):
|
||||
mcp_routes = _import_mcp_routes()
|
||||
monkeypatch.setattr(mcp_routes, "DATA_DIR", str(tmp_path / "data"))
|
||||
monkeypatch.setattr(mcp_routes, "MCP_OAUTH_DIR", str(tmp_path / "data" / "mcp_oauth"))
|
||||
|
||||
resolved = Path(mcp_routes._resolve_mcp_oauth_path("gmail/credentials.json", "token_file"))
|
||||
|
||||
@@ -963,7 +963,7 @@ def test_mcp_oauth_paths_reject_escapes(tmp_path, monkeypatch, raw_path):
|
||||
from fastapi import HTTPException
|
||||
|
||||
mcp_routes = _import_mcp_routes()
|
||||
monkeypatch.setattr(mcp_routes, "DATA_DIR", str(tmp_path / "data"))
|
||||
monkeypatch.setattr(mcp_routes, "MCP_OAUTH_DIR", str(tmp_path / "data" / "mcp_oauth"))
|
||||
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
mcp_routes._resolve_mcp_oauth_path(raw_path, "token_file")
|
||||
@@ -974,7 +974,7 @@ def test_mcp_oauth_filename_join_cannot_escape_base(tmp_path, monkeypatch):
|
||||
from fastapi import HTTPException
|
||||
|
||||
mcp_routes = _import_mcp_routes()
|
||||
monkeypatch.setattr(mcp_routes, "DATA_DIR", str(tmp_path / "data"))
|
||||
monkeypatch.setattr(mcp_routes, "MCP_OAUTH_DIR", str(tmp_path / "data" / "mcp_oauth"))
|
||||
|
||||
safe_dir = mcp_routes._resolve_mcp_oauth_path("gmail", "dir")
|
||||
with pytest.raises(HTTPException):
|
||||
@@ -983,7 +983,7 @@ def test_mcp_oauth_filename_join_cannot_escape_base(tmp_path, monkeypatch):
|
||||
|
||||
def test_mcp_oauth_config_sanitizes_paths_and_env(tmp_path, monkeypatch):
|
||||
mcp_routes = _import_mcp_routes()
|
||||
monkeypatch.setattr(mcp_routes, "DATA_DIR", str(tmp_path / "data"))
|
||||
monkeypatch.setattr(mcp_routes, "MCP_OAUTH_DIR", str(tmp_path / "data" / "mcp_oauth"))
|
||||
|
||||
cfg = mcp_routes._sanitize_mcp_oauth_config({
|
||||
"provider": "google",
|
||||
|
||||
@@ -13,7 +13,7 @@ def _load_setup_module():
|
||||
|
||||
def test_create_default_admin_normalizes_env_username(tmp_path, monkeypatch):
|
||||
setup_module = _load_setup_module()
|
||||
monkeypatch.setattr(setup_module, "DATA_DIR", str(tmp_path))
|
||||
monkeypatch.setattr(setup_module, "AUTH_FILE", str(tmp_path / "auth.json"))
|
||||
monkeypatch.setenv("ODYSSEUS_ADMIN_USER", " AdminUser ")
|
||||
monkeypatch.setenv("ODYSSEUS_ADMIN_PASSWORD", "temporary-password")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user