65 lines
2.2 KiB
Python
65 lines
2.2 KiB
Python
|
|
import subprocess
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from app.adapter import HermesCliKanbanAdapter, HermesCommandError, parse_tasks_payload
|
||
|
|
from app.config import Settings
|
||
|
|
from app.models import TaskCreate
|
||
|
|
|
||
|
|
|
||
|
|
def test_hermes_cli_adapter_uses_argv_list_and_no_shell(monkeypatch):
|
||
|
|
calls = []
|
||
|
|
|
||
|
|
def fake_run(argv, **kwargs):
|
||
|
|
calls.append((argv, kwargs))
|
||
|
|
return subprocess.CompletedProcess(argv, 0, stdout='{"tasks": []}', stderr="")
|
||
|
|
|
||
|
|
monkeypatch.setattr(subprocess, "run", fake_run)
|
||
|
|
adapter = HermesCliKanbanAdapter(Settings(hermes_bin="hermes"))
|
||
|
|
adapter.list_tasks(board="default")
|
||
|
|
argv, kwargs = calls[0]
|
||
|
|
assert argv[:3] == ["hermes", "kanban", "list"]
|
||
|
|
assert isinstance(argv, list)
|
||
|
|
assert kwargs.get("shell") is not True
|
||
|
|
|
||
|
|
|
||
|
|
def test_create_task_cli_uses_fixed_subcommand(monkeypatch):
|
||
|
|
calls = []
|
||
|
|
|
||
|
|
def fake_run(argv, **kwargs):
|
||
|
|
calls.append(argv)
|
||
|
|
return subprocess.CompletedProcess(argv, 0, stdout='{"id": "t_new"}', stderr="")
|
||
|
|
|
||
|
|
monkeypatch.setattr(subprocess, "run", fake_run)
|
||
|
|
adapter = HermesCliKanbanAdapter(Settings(hermes_bin="hermes"))
|
||
|
|
adapter.create_task(TaskCreate(title="Hello", assignee="developer", priority=5), board="default")
|
||
|
|
argv = calls[0]
|
||
|
|
assert argv[:4] == ["hermes", "kanban", "create", "Hello"]
|
||
|
|
assert "--assignee" in argv
|
||
|
|
assert "developer" in argv
|
||
|
|
|
||
|
|
|
||
|
|
def test_failed_command_raises_sanitized_error(monkeypatch):
|
||
|
|
def fake_run(argv, **kwargs):
|
||
|
|
return subprocess.CompletedProcess(argv, 1, stdout="", stderr="bad token secret")
|
||
|
|
|
||
|
|
monkeypatch.setattr(subprocess, "run", fake_run)
|
||
|
|
adapter = HermesCliKanbanAdapter(Settings(hermes_bin="hermes"))
|
||
|
|
with pytest.raises(HermesCommandError) as exc:
|
||
|
|
adapter.list_tasks()
|
||
|
|
assert "secret" not in str(exc.value).lower()
|
||
|
|
|
||
|
|
|
||
|
|
def test_parse_tasks_payload_accepts_json_list_and_normalizes():
|
||
|
|
tasks = parse_tasks_payload('[{"id":"t_1","title":"A","status":"ready"}]')
|
||
|
|
assert tasks[0]["id"] == "t_1"
|
||
|
|
assert tasks[0]["assignee"] is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_parse_tasks_payload_accepts_cli_text_table():
|
||
|
|
text = "t_1 ready developer 10 Build thing\n"
|
||
|
|
tasks = parse_tasks_payload(text)
|
||
|
|
assert tasks[0]["id"] == "t_1"
|
||
|
|
assert tasks[0]["status"] == "ready"
|
||
|
|
assert tasks[0]["assignee"] == "developer"
|