Archive completed tasks, add cleanup commands, self-documenting dashboard UI
CI / build (push) Has been cancelled
CI / build (push) Has been cancelled
- Archive 79 completed framework-dev tasks from tasks/ -> tasks/complete/ - status.py: add --cleanup-done and --install-cleanup-schedule commands - Add scripts/automaton-cleanup.sh for periodic task archiving - Dashboard: rename 'Background' tab -> 'Agent', 'Cleanup' agent -> 'Completed Task Archiver', remove redundant group headers and pill badges, dim inactive agent placeholders - .rules.md: add Self-Documenting UI Names rule - New tests: test_cleanup_done.py, expanded test_app.py and test_task.py
This commit is contained in:
@@ -242,3 +242,78 @@ class TestConfigEndpoint:
|
||||
handler._send_error = lambda c, m: errors.append((c, m))
|
||||
handler._handle_config_update()
|
||||
assert errors[0][0] == 400
|
||||
|
||||
|
||||
def test_serve_scheduled_returns_jobs(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""`/api/scheduled` returns jobs from `_list_scheduled_jobs`."""
|
||||
import automaton.dashboard.ui.app as app_mod
|
||||
|
||||
class _FakeStatusMod:
|
||||
def _list_scheduled_jobs(self=None, project=None):
|
||||
return [
|
||||
{"label": "com.automaton.cleanup", "kind": "cleanup", "name": "",
|
||||
"status": "enabled", "next_run_seconds": 86400,
|
||||
"stub_path": "/x/stub.sh", "runtime_state": None},
|
||||
{"label": "com.automaton.loop.ci", "kind": "loop", "name": "ci",
|
||||
"status": "disabled", "next_run_seconds": 60,
|
||||
"stub_path": None, "runtime_state": {"status": "paused"},
|
||||
"agent_type": "single"},
|
||||
]
|
||||
|
||||
monkeypatch.setattr(app_mod, "_get_status_module", lambda: _FakeStatusMod())
|
||||
handler = DashboardHandler.__new__(DashboardHandler)
|
||||
handler.project_root = tmp_path
|
||||
response = {}
|
||||
handler._send_json = lambda d: response.update(d)
|
||||
handler._serve_scheduled()
|
||||
assert response["available"] is True
|
||||
assert len(response["jobs"]) == 2
|
||||
assert response["jobs"][0]["kind"] == "cleanup"
|
||||
assert response["jobs"][1]["name"] == "ci"
|
||||
assert response["jobs"][1]["agent_type"] == "single"
|
||||
|
||||
|
||||
def test_serve_scheduled_unavailable(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""When status.py can't be loaded, `/api/scheduled` reports unavailable."""
|
||||
import automaton.dashboard.ui.app as app_mod
|
||||
|
||||
monkeypatch.setattr(app_mod, "_get_status_module", lambda: None)
|
||||
handler = DashboardHandler.__new__(DashboardHandler)
|
||||
handler.project_root = tmp_path
|
||||
response = {}
|
||||
handler._send_json = lambda d: response.update(d)
|
||||
handler._serve_scheduled()
|
||||
assert response["available"] is False
|
||||
assert response["jobs"] == []
|
||||
|
||||
|
||||
def test_serve_scheduled_handles_errors(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""Exceptions from `_list_scheduled_jobs` surface as `error` in the response."""
|
||||
import automaton.dashboard.ui.app as app_mod
|
||||
|
||||
class _FakeStatusMod:
|
||||
def _list_scheduled_jobs(self=None, project=None):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
monkeypatch.setattr(app_mod, "_get_status_module", lambda: _FakeStatusMod())
|
||||
handler = DashboardHandler.__new__(DashboardHandler)
|
||||
handler.project_root = tmp_path
|
||||
response = {}
|
||||
handler._send_json = lambda d: response.update(d)
|
||||
handler._serve_scheduled()
|
||||
assert response["available"] is True
|
||||
assert response["jobs"] == []
|
||||
assert "boom" in response["error"]
|
||||
|
||||
|
||||
def test_get_status_module_returns_none_when_missing(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""`_get_status_module` returns None when status.py isn't found in ~/.automaton."""
|
||||
import automaton.dashboard.ui.app as app_mod
|
||||
|
||||
# Reset the cached module, and point HOME at an empty dir so
|
||||
# `Path.home() / .automaton / scripts / status.py` doesn't exist.
|
||||
monkeypatch.setattr(app_mod, "_status_module", None)
|
||||
monkeypatch.setenv("HOME", str(tmp_path))
|
||||
# pathlib.Path.home() respects $HOME on every platform.
|
||||
result = app_mod._get_status_module()
|
||||
assert result is None
|
||||
|
||||
Reference in New Issue
Block a user