|
3 | 3 |
|
4 | 4 | import pytest |
5 | 5 |
|
6 | | -from scripts.reviewer_bot_lib import reconcile |
| 6 | +from scripts import reviewer_bot |
| 7 | +from scripts.reviewer_bot_lib import event_inputs, reconcile |
7 | 8 | from tests.fixtures.app_harness import AppHarness |
8 | 9 | from tests.fixtures.reviewer_bot import make_state, make_tracked_review_state |
9 | 10 |
|
@@ -184,6 +185,107 @@ def test_execute_run_returns_failure_for_invalid_workflow_run_context(monkeypatc |
184 | 185 | assert result.state_changed is False |
185 | 186 |
|
186 | 187 |
|
| 188 | +def test_bootstrapped_runtime_executes_direct_issue_comment_path_with_strict_request_inputs(monkeypatch): |
| 189 | + runtime = reviewer_bot._runtime_bot() |
| 190 | + state = make_state() |
| 191 | + seen = {} |
| 192 | + |
| 193 | + def acquire_lock(): |
| 194 | + runtime.ACTIVE_LEASE_CONTEXT = object() |
| 195 | + return runtime.ACTIVE_LEASE_CONTEXT |
| 196 | + |
| 197 | + def release_lock(): |
| 198 | + runtime.ACTIVE_LEASE_CONTEXT = None |
| 199 | + return True |
| 200 | + |
| 201 | + def handle_comment_event(current_state): |
| 202 | + assert current_state is state |
| 203 | + seen["request"] = event_inputs.build_comment_event_request(runtime) |
| 204 | + runtime.collect_touched_item(42) |
| 205 | + return True |
| 206 | + |
| 207 | + monkeypatch.setattr(runtime.locks, "acquire", acquire_lock) |
| 208 | + monkeypatch.setattr(runtime.locks, "release", release_lock) |
| 209 | + monkeypatch.setattr(runtime.state_store, "load_state", lambda *, fail_on_unavailable=False: state) |
| 210 | + monkeypatch.setattr(runtime.state_store, "save_state", lambda current_state: True) |
| 211 | + monkeypatch.setattr(runtime.adapters.workflow, "process_pass_until_expirations", lambda current_state: (current_state, [])) |
| 212 | + monkeypatch.setattr(runtime.adapters.workflow, "sync_members_with_queue", lambda current_state: (current_state, [])) |
| 213 | + monkeypatch.setattr(runtime.adapters.workflow, "sync_status_labels_for_items", lambda current_state, issue_numbers: False) |
| 214 | + monkeypatch.setattr(runtime.handlers, "handle_comment_event", handle_comment_event) |
| 215 | + monkeypatch.setenv("EVENT_NAME", "issue_comment") |
| 216 | + monkeypatch.setenv("EVENT_ACTION", "created") |
| 217 | + monkeypatch.setenv("ISSUE_NUMBER", "42") |
| 218 | + monkeypatch.setenv("IS_PULL_REQUEST", "false") |
| 219 | + monkeypatch.setenv("ISSUE_STATE", "open") |
| 220 | + monkeypatch.setenv("ISSUE_AUTHOR", "dana") |
| 221 | + monkeypatch.setenv("ISSUE_LABELS", '["triage"]') |
| 222 | + monkeypatch.setenv("COMMENT_ID", "100") |
| 223 | + monkeypatch.setenv("COMMENT_AUTHOR", "alice") |
| 224 | + monkeypatch.setenv("COMMENT_AUTHOR_ID", "200") |
| 225 | + monkeypatch.setenv("COMMENT_BODY", "hello") |
| 226 | + monkeypatch.setenv("COMMENT_CREATED_AT", "2026-04-13T04:30:00Z") |
| 227 | + monkeypatch.delenv("COMMENT_SOURCE_EVENT_KEY", raising=False) |
| 228 | + monkeypatch.setenv("COMMENT_USER_TYPE", "User") |
| 229 | + monkeypatch.setenv("COMMENT_SENDER_TYPE", "User") |
| 230 | + monkeypatch.delenv("COMMENT_INSTALLATION_ID", raising=False) |
| 231 | + monkeypatch.setenv("COMMENT_PERFORMED_VIA_GITHUB_APP", "false") |
| 232 | + |
| 233 | + context = reviewer_bot.build_event_context(runtime) |
| 234 | + result = reviewer_bot.execute_run(context, runtime) |
| 235 | + |
| 236 | + assert result.exit_code == 0 |
| 237 | + assert result.state_changed is True |
| 238 | + assert seen["request"].is_pull_request is False |
| 239 | + assert seen["request"].comment_author_id == 200 |
| 240 | + assert seen["request"].comment_source_event_key == "issue_comment:100" |
| 241 | + assert runtime.ACTIVE_LEASE_CONTEXT is None |
| 242 | + |
| 243 | + |
| 244 | +def test_bootstrapped_runtime_executes_pr_metadata_closed_dispatch_path(monkeypatch): |
| 245 | + runtime = reviewer_bot._runtime_bot() |
| 246 | + state = make_state() |
| 247 | + calls = [] |
| 248 | + |
| 249 | + def acquire_lock(): |
| 250 | + runtime.ACTIVE_LEASE_CONTEXT = object() |
| 251 | + return runtime.ACTIVE_LEASE_CONTEXT |
| 252 | + |
| 253 | + def release_lock(): |
| 254 | + runtime.ACTIVE_LEASE_CONTEXT = None |
| 255 | + return True |
| 256 | + |
| 257 | + def handle_closed_event(current_state): |
| 258 | + calls.append(current_state) |
| 259 | + return True |
| 260 | + |
| 261 | + monkeypatch.setattr(runtime.locks, "acquire", acquire_lock) |
| 262 | + monkeypatch.setattr(runtime.locks, "release", release_lock) |
| 263 | + monkeypatch.setattr(runtime.state_store, "load_state", lambda *, fail_on_unavailable=False: state) |
| 264 | + monkeypatch.setattr(runtime.state_store, "save_state", lambda current_state: True) |
| 265 | + monkeypatch.setattr(runtime.adapters.workflow, "process_pass_until_expirations", lambda current_state: (current_state, [])) |
| 266 | + monkeypatch.setattr(runtime.adapters.workflow, "sync_members_with_queue", lambda current_state: (current_state, [])) |
| 267 | + monkeypatch.setattr(runtime.adapters.workflow, "sync_status_labels_for_items", lambda current_state, issue_numbers: False) |
| 268 | + monkeypatch.setattr(runtime.handlers, "handle_closed_event", handle_closed_event) |
| 269 | + monkeypatch.setenv("EVENT_NAME", "pull_request_target") |
| 270 | + monkeypatch.setenv("EVENT_ACTION", "closed") |
| 271 | + monkeypatch.setenv("ISSUE_NUMBER", "42") |
| 272 | + monkeypatch.setenv("IS_PULL_REQUEST", "true") |
| 273 | + monkeypatch.setenv("ISSUE_AUTHOR", "dana") |
| 274 | + monkeypatch.setenv("ISSUE_LABELS", '["triage"]') |
| 275 | + monkeypatch.setenv("PR_HEAD_SHA", "head-1") |
| 276 | + monkeypatch.setenv("EVENT_CREATED_AT", "2026-04-13T04:31:00Z") |
| 277 | + |
| 278 | + context = reviewer_bot.build_event_context(runtime) |
| 279 | + result = reviewer_bot.execute_run(context, runtime) |
| 280 | + |
| 281 | + assert context.event_name == "pull_request_target" |
| 282 | + assert context.event_action == "closed" |
| 283 | + assert calls == [state] |
| 284 | + assert result.exit_code == 0 |
| 285 | + assert result.state_changed is True |
| 286 | + assert runtime.ACTIVE_LEASE_CONTEXT is None |
| 287 | + |
| 288 | + |
187 | 289 | def test_d4a_app_branch_to_phase_map_is_frozen_pre_edit(): |
188 | 290 | app_text = Path("scripts/reviewer_bot_lib/app.py").read_text(encoding="utf-8") |
189 | 291 |
|
|
0 commit comments