sdlc-hub/tests/test_mcp.py
Andrey Epifancev cc0026bb1c feat(hub): MCP-сервер — инструменты поверх HTTP API
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Typ5sXWNMFirr2va2uL8o
2026-10-11 22:32:23 +04:00

75 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import threading
import pytest
from jira_hub import api, mcp_server, settings
from jira_hub.client import HubClient
@pytest.fixture
def live(tmp_path, monkeypatch):
h = api.Hub(tmp_path / "hub.sqlite", backups_dir=tmp_path / "backups")
h.claim_wait = 0
conn = h.conn()
tok = settings.tokens(conn)
conn.close()
srv = api.make_server(h, "127.0.0.1", 0)
threading.Thread(target=srv.serve_forever, daemon=True).start()
base = f"http://127.0.0.1:{srv.server_port}"
monkeypatch.setattr(mcp_server, "_client", lambda: HubClient(base, tok["client"]))
monkeypatch.setattr(mcp_server, "POLL_SECONDS", 0.05)
yield {"agent": HubClient(base, tok["agent"])}
srv.shutdown()
def test_offline_message(monkeypatch):
monkeypatch.setattr(mcp_server, "_client", lambda: HubClient("http://127.0.0.1:9", "t", timeout=1))
assert mcp_server.issues() == mcp_server.OFFLINE
assert mcp_server.agent_status() == mcp_server.OFFLINE
def test_tools_roundtrip(live):
live["agent"].post("/agent/state", {"issues": [{"key": "A-1", "summary": "Тема раз", "status": "Готово", "duedate": "2026-10-23",
"assignee": "ivanov", "sprint": "Спринт 2", "labels": ["AWPCA"]}], "links": []})
out = mcp_server.issues(sprint="Спринт 2")
assert "A-1" in out and "Тема раз" in out and "ivanov" in out
assert "В работе" in mcp_server.notes_set("A-1", fact_status="В работе")
detail = mcp_server.issue("A-1")
assert "fact_status: В работе" in detail and "Готово" in detail
created = mcp_server.batch_create("срок", [{"type": "ensure_fields", "params": {"key": "A-1", "duedate": "2026-10-24"}}])
batch_id = int(created.split("#")[1].split()[0])
assert "2 команд" in created and "мин" in created
bad = mcp_server.batch_create("x", [{"type": "ensure_fields", "params": {"key": "A-1"}}])
assert bad.startswith("ошибка хаба 422")
cmd = live["agent"].post("/agent/claim", {})["command"]
live["agent"].post(f"/agent/commands/{cmd['id']}/result", {"status": "failed", "error": "HTTP 400 поле"})
tail = live["agent"].post("/agent/claim", {})["command"]
live["agent"].post(f"/agent/commands/{tail['id']}/result", {"status": "done"})
waited = mcp_server.batch_wait(batch_id, timeout_minutes=1)
assert "done" in waited and "failed" in waited and "HTTP 400" in waited
assert f"#{batch_id}" in mcp_server.batches(limit=5)
assert "Повтор команды" in mcp_server.command_retry(cmd["id"])
assert "cancelled" in mcp_server.batch_cancel(batch_id + 1)
r = mcp_server.refresh(full=True, wait=False)
assert "Обновление" in r or "#" in r
assert "онлайн" in mcp_server.agent_status()
assert "A-1" in mcp_server.sync_log(limit=3) or "keys" in mcp_server.sync_log(limit=3)
assert "120" in mcp_server.settings_get("pacing")
assert "settings_version" in mcp_server.settings_set("pacing", json.dumps({"refresh": 1}))
assert mcp_server.settings_set("tokens", '"x"').startswith("ошибка хаба 422")
def test_formatters():
assert mcp_server.fmt_issues([]) == "задач нет"
text = mcp_server.fmt_issues([{"key": "A-1", "summary": "x" * 100, "status": "Готово", "duedate": None, "assignee": None,
"sprint": None, "fact_status": None}])
assert "x" * 79 + "…" in text and "x" * 80 not in text and "—" in text
assert "очередь" in mcp_server.fmt_agent({"online": False, "agent_version": None, "current_command_id": None,
"rate_limited_24h": 0, "stuck": [], "warning": None, "last_seen_at": None,
"settings_version": None})
def test_settings_set_bad_json(live):
assert mcp_server.settings_set("pacing", "{не json").startswith("значение не JSON")