|
| 1 | +import json |
| 2 | +from pathlib import Path |
| 3 | +from typing import Mapping |
| 4 | + |
| 5 | +import pytest |
| 6 | +from typer.testing import CliRunner |
| 7 | + |
1 | 8 | from scripts import bm_bossbot_status |
2 | 9 |
|
3 | 10 |
|
| 11 | +def _event_payload(body: str = "Event snapshot body") -> dict[str, object]: |
| 12 | + return { |
| 13 | + "repository": {"full_name": "basicmachines-co/basic-memory"}, |
| 14 | + "pull_request": { |
| 15 | + "number": 925, |
| 16 | + "body": body, |
| 17 | + "head": {"sha": "abc123"}, |
| 18 | + }, |
| 19 | + } |
| 20 | + |
| 21 | + |
4 | 22 | def test_status_script_is_uv_typer_entrypoint() -> None: |
5 | 23 | source = bm_bossbot_status.__file__ |
6 | 24 | assert source is not None |
@@ -84,3 +102,103 @@ def test_upsert_summary_block_replaces_existing_block() -> None: |
84 | 102 | assert "New summary" in updated |
85 | 103 | assert updated.startswith("Intro") |
86 | 104 | assert updated.endswith("Footer") |
| 105 | + |
| 106 | + |
| 107 | +def test_finalize_review_fetches_current_pr_body_before_upserting( |
| 108 | + tmp_path: Path, |
| 109 | + monkeypatch: pytest.MonkeyPatch, |
| 110 | +) -> None: |
| 111 | + event_path = tmp_path / "event.json" |
| 112 | + review_path = tmp_path / "review.json" |
| 113 | + event_path.write_text(json.dumps(_event_payload()), encoding="utf-8") |
| 114 | + review_path.write_text(json.dumps(_review_payload()), encoding="utf-8") |
| 115 | + monkeypatch.setenv("GITHUB_TOKEN", "token") |
| 116 | + |
| 117 | + updated_bodies: list[str] = [] |
| 118 | + statuses: list[Mapping[str, str]] = [] |
| 119 | + |
| 120 | + def fake_get_pull_request_body(*, token: str, repo: str, number: int) -> str: |
| 121 | + assert token == "token" |
| 122 | + assert repo == "basicmachines-co/basic-memory" |
| 123 | + assert number == 925 |
| 124 | + return "Current body edited while the workflow was running" |
| 125 | + |
| 126 | + def fake_update_pull_request_body(*, token: str, repo: str, number: int, body: str) -> None: |
| 127 | + updated_bodies.append(body) |
| 128 | + |
| 129 | + def fake_set_commit_status( |
| 130 | + *, |
| 131 | + token: str, |
| 132 | + repo: str, |
| 133 | + sha: str, |
| 134 | + payload: Mapping[str, str], |
| 135 | + ) -> None: |
| 136 | + statuses.append(payload) |
| 137 | + |
| 138 | + monkeypatch.setattr(bm_bossbot_status, "get_pull_request_body", fake_get_pull_request_body) |
| 139 | + monkeypatch.setattr(bm_bossbot_status, "update_pull_request_body", fake_update_pull_request_body) |
| 140 | + monkeypatch.setattr(bm_bossbot_status, "set_commit_status", fake_set_commit_status) |
| 141 | + |
| 142 | + result = bm_bossbot_status.finalize_review( |
| 143 | + event_path=event_path, |
| 144 | + review_path=review_path, |
| 145 | + repo=None, |
| 146 | + run_url="https://github.com/basicmachines-co/basic-memory/actions/runs/1", |
| 147 | + token_env="GITHUB_TOKEN", |
| 148 | + ) |
| 149 | + |
| 150 | + assert result.approved is True |
| 151 | + assert "Current body edited while the workflow was running" in updated_bodies[0] |
| 152 | + assert "Event snapshot body" not in updated_bodies[0] |
| 153 | + assert statuses[0]["state"] == "success" |
| 154 | + |
| 155 | + |
| 156 | +def test_finalize_cli_marks_failure_when_review_file_is_missing( |
| 157 | + tmp_path: Path, |
| 158 | + monkeypatch: pytest.MonkeyPatch, |
| 159 | +) -> None: |
| 160 | + event_path = tmp_path / "event.json" |
| 161 | + missing_review_path = tmp_path / "missing-review.json" |
| 162 | + event_path.write_text(json.dumps(_event_payload(body="Current body")), encoding="utf-8") |
| 163 | + monkeypatch.setenv("GITHUB_TOKEN", "token") |
| 164 | + |
| 165 | + updated_bodies: list[str] = [] |
| 166 | + statuses: list[Mapping[str, str]] = [] |
| 167 | + |
| 168 | + def fake_get_pull_request_body(*, token: str, repo: str, number: int) -> str: |
| 169 | + return "Current body" |
| 170 | + |
| 171 | + def fake_update_pull_request_body(*, token: str, repo: str, number: int, body: str) -> None: |
| 172 | + updated_bodies.append(body) |
| 173 | + |
| 174 | + def fake_set_commit_status( |
| 175 | + *, |
| 176 | + token: str, |
| 177 | + repo: str, |
| 178 | + sha: str, |
| 179 | + payload: Mapping[str, str], |
| 180 | + ) -> None: |
| 181 | + statuses.append(payload) |
| 182 | + |
| 183 | + monkeypatch.setattr(bm_bossbot_status, "get_pull_request_body", fake_get_pull_request_body) |
| 184 | + monkeypatch.setattr(bm_bossbot_status, "update_pull_request_body", fake_update_pull_request_body) |
| 185 | + monkeypatch.setattr(bm_bossbot_status, "set_commit_status", fake_set_commit_status) |
| 186 | + |
| 187 | + result = CliRunner().invoke( |
| 188 | + bm_bossbot_status.app, |
| 189 | + [ |
| 190 | + "finalize", |
| 191 | + "--event", |
| 192 | + str(event_path), |
| 193 | + "--review", |
| 194 | + str(missing_review_path), |
| 195 | + "--repo", |
| 196 | + "basicmachines-co/basic-memory", |
| 197 | + "--run-url", |
| 198 | + "https://github.com/basicmachines-co/basic-memory/actions/runs/1", |
| 199 | + ], |
| 200 | + ) |
| 201 | + |
| 202 | + assert result.exit_code == 1 |
| 203 | + assert "BM Bossbot review output was invalid" in updated_bodies[0] |
| 204 | + assert statuses[0]["state"] == "failure" |
0 commit comments