From 181dd659589324b9fc958a47e15ec8631f021137 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 11 Oct 2026 22:51:11 +0400 Subject: [PATCH] =?UTF-8?q?test(hub):=20=D1=81=D0=BA=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BE=D0=BD=20?= =?UTF-8?q?=D0=BE=D1=87=D0=B5=D1=80=D0=B5=D0=B4=D0=B8=20=D1=87=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=20HTTP=20=D1=81=20=D0=B8=D0=BC=D0=B8=D1=82=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B5=D0=B9=20=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Фикстура останавливает сервер (server_close, join потока), иначе ResourceWarning о незакрытом сокете. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_014Typ5sXWNMFirr2va2uL8o --- tests/test_e2e_hub.py | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/test_e2e_hub.py diff --git a/tests/test_e2e_hub.py b/tests/test_e2e_hub.py new file mode 100644 index 0000000..3ac6ba9 --- /dev/null +++ b/tests/test_e2e_hub.py @@ -0,0 +1,59 @@ +import threading + +import pytest + +from jira_hub import api, settings +from jira_hub.client import HubClient + + +@pytest.fixture +def live(tmp_path): + h = api.Hub(tmp_path / "hub.sqlite", backups_dir=tmp_path / "backups") + h.claim_wait = 0 + conn = h.conn() + settings.set_(conn, "link_types", {"связанные": "ASUPR_Связанные"}) + tok = settings.tokens(conn) + conn.close() + srv = api.make_server(h, "127.0.0.1", 0) + th = threading.Thread(target=srv.serve_forever, daemon=True) + th.start() + base = f"http://127.0.0.1:{srv.server_port}" + yield HubClient(base, tok["agent"]), HubClient(base, tok["client"]) + srv.shutdown() + srv.server_close() + th.join(5) + + +def test_create_link_sprint_flow(live): + agent, client = live + client.put("/issues/new:60/note", {"fact_status": "Ожидание разработки", "work_kind": "разработка", "updated_by": "import"}) + b = client.post("/batches", {"title": "новая задача в спринт", "author": "claude", "commands": [ + {"type": "ensure_issue", "params": {"temp_key": "new:60", "issue_type": "task", "summary": "Новая", "duedate": "2026-10-23"}}, + {"type": "ensure_link", "params": {"source": "new:60", "target": "A-1", "link_type": "связанные"}}, + {"type": "ensure_sprint", "params": {"key": "new:60", "sprint": "Спринт 2"}}, + ]}) + assert b["count"] == 4 + seen = [] + while True: + cmd = agent.post("/agent/claim", {"agent_version": 1, "settings_version": 1})["command"] + if cmd is None: + break + seen.append((cmd["type"], cmd["params"])) + if cmd["type"] == "ensure_issue": + agent.post(f"/agent/commands/{cmd['id']}/result", {"status": "done", "result": {"key": "A-90"}, "jira_calls": 2}) + elif cmd["type"] == "refresh": + agent.post("/agent/state", {"command_id": cmd["id"], "issues": [ + {"key": "A-90", "summary": "Новая", "duedate": "2026-10-23", "sprint": "Спринт 2", "labels": [], + "created": "2026-10-11T10:00:00.000+0300"}, + {"key": "A-1", "summary": "Старая", "labels": []}], + "links": [{"source_key": "A-90", "target_key": "A-1", "link_type": "ASUPR_Связанные"}]}) + agent.post(f"/agent/commands/{cmd['id']}/result", {"status": "done", "jira_calls": 1}) + else: + agent.post(f"/agent/commands/{cmd['id']}/result", {"status": "done", "jira_calls": 1}) + assert [t for t, _ in seen] == ["ensure_issue", "ensure_link", "ensure_sprint", "refresh"] + assert seen[1][1]["source"] == "A-90" and seen[2][1]["key"] == "A-90" and seen[3][1]["keys"] == ["A-90", "A-1"] + view = client.get(f"/batches/{b['id']}") + assert view["status"] == "done" and all(c["status"] == "done" for c in view["commands"]) + issue = client.get("/issues/A-90") + assert issue["note"]["work_kind"] == "разработка" and issue["links_out"][0]["target_key"] == "A-1" + assert client.get("/sync-runs")["runs"][0]["issues_count"] == 2