Files
LEDMatrix/test/web_interface/test_app_plugins_dir_resolution.py
ChuckandClaude Opus 5.5 f813ea2117 fix(web): define project_root when plugins_directory is absolute (#616)
project_root was only assigned in the relative-path branch, so an absolute
plugin_system.plugins_directory made web_interface/app.py raise NameError
at import (first use: the SchemaManager construction). Define it before the
if/else; plugins_dir resolution is unchanged.

Adds a regression test that imports the real module in a fresh interpreter
with an absolute and a relative plugins_directory.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 12:54:29 -04:00

66 lines
2.1 KiB
Python

"""
web_interface/app.py must start with an absolute ``plugins_directory``.
``project_root`` used to be assigned only in the relative-path branch, so an
absolute path in config.json raised NameError at module import (the
SchemaManager construction was the first use). Each case imports the real
module in a fresh interpreter, since app.py does its setup at import time and
the test process may already hold a copy built from the real config.
"""
import json
import subprocess
import sys
import textwrap
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
_IMPORT_APP = textwrap.dedent(
"""
import json, sys
from pathlib import Path
sys.path.insert(0, {root!r})
from src.config_manager import ConfigManager
ConfigManager.load_config = lambda self: {config!r}
import web_interface.app as web_app
print(json.dumps({{
"plugins_dir": str(web_app.plugins_dir),
"project_root": str(web_app.project_root),
"schema_project_root": str(web_app.schema_manager.project_root),
}}))
"""
)
def _import_app_with(plugins_directory):
config = {"plugin_system": {"plugins_directory": plugins_directory}}
script = _IMPORT_APP.format(root=str(PROJECT_ROOT), config=config)
result = subprocess.run(
[sys.executable, "-c", script],
cwd=str(PROJECT_ROOT),
capture_output=True,
text=True,
timeout=120,
)
assert result.returncode == 0, result.stderr
return json.loads(result.stdout.strip().splitlines()[-1])
def test_absolute_plugins_directory_imports(tmp_path):
plugins = tmp_path / "my-plugins"
plugins.mkdir()
info = _import_app_with(str(plugins))
assert Path(info["plugins_dir"]) == plugins
assert Path(info["project_root"]) == PROJECT_ROOT
assert Path(info["schema_project_root"]) == PROJECT_ROOT
def test_relative_plugins_directory_resolves_under_project_root():
info = _import_app_with("plugin-repos")
assert Path(info["plugins_dir"]) == PROJECT_ROOT / "plugin-repos"
assert Path(info["project_root"]) == PROJECT_ROOT