mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-07-21 07:00:23 +00:00
57 lines
2.6 KiB
Python
57 lines
2.6 KiB
Python
"""Regression test for #4768.
|
|
|
|
In split-container / minimal Docker deployments the WebUI image may not ship the
|
|
agent's ``cron`` package on its import path. Before the fix, ``GET /api/crons``
|
|
(the Tasks tab's initial load) did ``from cron.jobs import list_jobs`` with no
|
|
guard, so a ``ModuleNotFoundError`` bubbled up as a 500 and broke the whole tab.
|
|
|
|
The fix degrades gracefully: an empty job list with a ``cron_unavailable`` flag.
|
|
"""
|
|
import pathlib
|
|
|
|
REPO = pathlib.Path(__file__).resolve().parent.parent
|
|
ROUTES = (REPO / "api" / "routes.py").read_text(encoding="utf-8")
|
|
|
|
|
|
def _api_crons_branch() -> str:
|
|
"""Return the source of the `if parsed.path == "/api/crons":` GET branch."""
|
|
marker = ROUTES.index('if parsed.path == "/api/crons":')
|
|
# Stop at the next sibling branch so we only inspect this handler.
|
|
nxt = ROUTES.index('if parsed.path == "/api/crons/output":', marker)
|
|
return ROUTES[marker:nxt]
|
|
|
|
|
|
def test_api_crons_guards_missing_cron_module():
|
|
"""The /api/crons GET branch must wrap the cron.jobs import in a guard that
|
|
returns a graceful payload instead of letting ModuleNotFoundError 500 — but
|
|
only for a genuinely-absent cron package, not an internal import bug."""
|
|
branch = _api_crons_branch()
|
|
assert "from cron.jobs import list_jobs" in branch
|
|
assert "except ModuleNotFoundError as exc" in branch, (
|
|
"GET /api/crons must catch ModuleNotFoundError so the Tasks tab does not "
|
|
"500 when the cron package is absent (#4768)."
|
|
)
|
|
# The except path returns an empty list + an unavailable flag (not a re-raise)
|
|
# ONLY for the genuinely-missing cron package...
|
|
assert "cron_unavailable" in branch
|
|
assert 'exc.name in ("cron", "cron.jobs")' in branch, (
|
|
"Must only treat an absent cron package as unavailable; an internal "
|
|
"dependency ImportError of an existing cron/jobs.py must still surface."
|
|
)
|
|
# ...and re-raises everything else (a real cron bug is not swallowed).
|
|
assert "\n raise" in branch
|
|
# The try guards the import specifically (not some unrelated block).
|
|
try_idx = branch.index("try:")
|
|
import_idx = branch.index("from cron.jobs import list_jobs")
|
|
except_idx = branch.index("except ModuleNotFoundError")
|
|
assert try_idx < import_idx < except_idx
|
|
|
|
|
|
def test_api_crons_still_lists_jobs_on_happy_path():
|
|
"""The guard must not remove the normal behavior: when cron imports fine, the
|
|
branch still calls list_jobs(include_disabled=True) under cron_profile_context."""
|
|
branch = _api_crons_branch()
|
|
assert "list_jobs(include_disabled=True)" in branch
|
|
assert "cron_profile_context()" in branch
|
|
assert "_cron_jobs_for_api(" in branch
|