"""ORCH-017 / TC-10: analysis-approved flow wires DB fields into the approve ping. When the analyst's artifacts are ready, `_handle_analysis_approved_flow` sets the issue In Review, posts the analyst comment, and calls `notify_approve_requested`. This test drives that flow with all network side-effects mocked and asserts the resulting Telegram ping carries the BRD + Plane links built from the task's DB row (repo / branch / plane_issue_id), while the approval gate name and the no-self-advance contract are unchanged (AC-1 / AC-2 / AC-8). """ import os import tempfile os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token") os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token") _test_db = os.path.join(tempfile.gettempdir(), "test_orchestrator_approve_flow.db") os.environ["ORCH_DB_PATH"] = _test_db import pytest # noqa: E402 import src.db as db_module # noqa: E402 from src.db import init_db, get_db # noqa: E402 from src import notifications as N # noqa: E402 from src import stage_engine as SE # noqa: E402 _ORCH_PROJECT_ID = "8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a" @pytest.fixture(autouse=True) def setup_db(monkeypatch): monkeypatch.setattr(db_module.settings, "db_path", _test_db, raising=False) if os.path.exists(_test_db): os.unlink(_test_db) init_db() yield if os.path.exists(_test_db): os.unlink(_test_db) def _mk_task(monkeypatch): conn = get_db() cur = conn.execute( "INSERT INTO tasks (plane_id, work_item_id, repo, branch, stage, title, " "plane_issue_id) VALUES (?, ?, ?, ?, ?, ?, ?)", ("p1", "ORCH-017", "orchestrator", "feature/ORCH-017-brd-plane-telegram", "analysis", "Approve flow", "issue-uuid-7"), ) tid = cur.lastrowid conn.commit() conn.close() return tid def test_tc10_approved_flow_builds_links_from_db(monkeypatch): tid = _mk_task(monkeypatch) # Settings that make both links resolvable. s = N._get_settings() monkeypatch.setattr(s, "gitea_public_url", "https://git.example.org", raising=False) monkeypatch.setattr(s, "gitea_owner", "orchteam", raising=False) monkeypatch.setattr(s, "plane_web_url", "https://plane.example.org", raising=False) monkeypatch.setattr(s, "plane_workspace_slug", "acme", raising=False) # Isolate every network/fs side-effect of the flow. monkeypatch.setitem(SE.QG_CHECKS, "check_analysis_complete", lambda repo, wid, branch: (True, "ok")) monkeypatch.setattr(SE, "set_issue_in_review", lambda wid: None) monkeypatch.setattr(SE, "plane_add_comment", lambda *a, **k: None) monkeypatch.setattr(SE, "_build_analyst_ready_comment", lambda *a, **k: "c") # Capture the approve ping; stub the tracker refresh. calls = [] monkeypatch.setattr(N, "send_telegram", lambda text, disable_notification=False: calls.append(text) or 1) monkeypatch.setattr(N, "update_task_tracker", lambda task_id: None) result = SE.AdvanceResult() SE._handle_analysis_approved_flow( tid, "analysis", "orchestrator", "ORCH-017", "feature/ORCH-017-brd-plane-telegram", "analyst", result, ) # Gate name + no-self-advance contract unchanged (AC-8). assert result.qg_name == "check_analysis_approved" assert result.note == "analysis-in-review" assert result.advanced is False # Exactly one ping carrying both links built from the DB row (AC-1 / AC-2). assert len(calls) == 1 text = calls[0] assert ( "https://git.example.org/orchteam/orchestrator/src/branch/" "feature/ORCH-017-brd-plane-telegram/docs/work-items/ORCH-017/01-brd.md" ) in text assert ( f"https://plane.example.org/acme/projects/{_ORCH_PROJECT_ID}" f"/issues/issue-uuid-7/" ) in text