test(dashboard): cover constants, git helper, cron endpoint, files sandbox

This commit is contained in:
2026-04-21 07:22:48 +00:00
parent fa7c0fd1c6
commit d741541e23
4 changed files with 486 additions and 0 deletions

133
tests/test_dashboard_git.py Normal file
View File

@@ -0,0 +1,133 @@
"""Unit tests for dashboard.handlers.git — _run_git helper + endpoint shapes."""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
from unittest.mock import patch
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[1]
DASH = PROJECT_ROOT / "dashboard"
if str(DASH) not in sys.path:
sys.path.insert(0, str(DASH))
@pytest.fixture(scope="module")
def git_module():
from handlers import git as _g # type: ignore
return _g
@pytest.fixture
def handler(git_module):
"""A bare instance of GitHandlers with a captured send_json."""
class _Stub(git_module.GitHandlers):
def __init__(self):
self.captured = None
self.captured_code = None
def send_json(self, data, code=200):
self.captured = data
self.captured_code = code
return _Stub()
def test_run_git_is_a_subprocess_call(handler, git_module, tmp_path):
"""_run_git must use subprocess.run with the supplied cwd + timeout."""
with patch.object(git_module.subprocess, "run") as mock_run:
mock_run.return_value = subprocess.CompletedProcess(
args=["git", "status"], returncode=0, stdout="clean\n", stderr=""
)
result = handler._run_git(tmp_path, ["status"], timeout=3)
mock_run.assert_called_once()
args, kwargs = mock_run.call_args
assert args[0] == ["git", "status"]
assert kwargs["cwd"] == str(tmp_path)
assert kwargs["timeout"] == 3
assert kwargs["capture_output"] is True
assert kwargs["text"] is True
assert result.stdout == "clean\n"
def test_run_git_default_timeout_is_5(handler, git_module, tmp_path):
with patch.object(git_module.subprocess, "run") as mock_run:
mock_run.return_value = subprocess.CompletedProcess(
args=["git", "log"], returncode=0, stdout="", stderr=""
)
handler._run_git(tmp_path, ["log"])
_, kwargs = mock_run.call_args
assert kwargs["timeout"] == 5
def test_legacy_git_commit_handler_is_gone(git_module):
"""/api/git-commit was consolidated into /api/eco/git-commit."""
assert not hasattr(git_module.GitHandlers, "handle_git_commit")
def test_git_status_uses_echo_core_workspace(handler, git_module):
"""handle_git_status must target constants.GIT_WORKSPACE (echo-core), not clawd."""
captured_workspaces = []
def fake_run(_self, workspace, args, timeout=5):
captured_workspaces.append(workspace)
stdout_map = {
("branch", "--show-current"): "master\n",
("log", "-1", "--format=%h|%s|%cr"): "abc1234|test commit|1 hour ago\n",
("status", "--short"): "",
("diff", "--stat", "--cached"): "",
("diff", "--stat"): "",
}
return subprocess.CompletedProcess(
args=["git", *args],
returncode=0,
stdout=stdout_map.get(tuple(args), ""),
stderr="",
)
with patch.object(git_module.GitHandlers, "_run_git", fake_run):
handler.handle_git_status()
import constants # type: ignore
assert all(w == constants.GIT_WORKSPACE for w in captured_workspaces)
assert handler.captured is not None
assert handler.captured["branch"] == "master"
def test_git_status_parses_uncommitted_paths(handler, git_module):
def fake_run(_self, workspace, args, timeout=5):
if args == ["status", "--short"]:
return subprocess.CompletedProcess(
args=["git"] + args, returncode=0,
stdout=" M src/foo.py\n?? new_file.txt\n", stderr="",
)
if args[:1] == ["branch"]:
return subprocess.CompletedProcess(
args=["git"] + args, returncode=0, stdout="feat-x\n", stderr="",
)
if args[:1] == ["log"]:
return subprocess.CompletedProcess(
args=["git"] + args, returncode=0,
stdout="deadbee|msg|2 minutes ago\n", stderr="",
)
return subprocess.CompletedProcess(
args=["git"] + args, returncode=0, stdout="", stderr="",
)
with patch.object(git_module.GitHandlers, "_run_git", fake_run):
handler.handle_git_status()
data = handler.captured
assert data is not None
assert data["uncommittedCount"] == 2
assert data["clean"] is False
paths = [u["path"] for u in data["uncommittedParsed"]]
statuses = {u["status"] for u in data["uncommittedParsed"]}
assert "src/foo.py" in paths
assert "new_file.txt" in paths
assert "M" in statuses
assert "??" in statuses