Files
ITWorx_MCP_Hub-Public/tests/test_gitea_merge_validation_fallback.py
T

189 lines
6.8 KiB
Python

"""Regression tests for empty Gitea Actions wrappers and merge validation fallback."""
from __future__ import annotations
import pytest
from packages.connector_kit import GiteaError, PageRequest
from tests.test_gitea_connector import connector, context
def _force_empty_actions_wrapper(connector_instance) -> None:
original_request = connector_instance.client._request
actions_runs_path = connector_instance.client._path("repos", "acme", "hub", "actions", "runs")
def request(path, *args, **kwargs):
if path == actions_runs_path:
return {"workflow_runs": []}
return original_request(path, *args, **kwargs)
connector_instance.client._request = request
def _add_validated_head_branch(fixture) -> None:
fixture._branches.append(
{"name": "codex/workflows", "commit": {"id": "e" * 40}, "protected": False}
)
def test_empty_actions_wrapper_uses_green_exact_head_status_evidence() -> None:
connector_instance, fixture = connector()
_add_validated_head_branch(fixture)
_force_empty_actions_wrapper(connector_instance)
try:
result = connector_instance.validation_list(
context(),
"hub-repository",
"codex/workflows",
page=PageRequest(limit=10),
)["data"]["items"]
assert len(result) == 1
assert result[0]["id"] == 0
assert result[0]["status"] == "completed"
assert result[0]["conclusion"] == "success"
assert result[0]["headSha"] == "e" * 40
finally:
connector_instance.client.close()
def test_merge_uses_status_linked_run_when_actions_wrapper_is_empty() -> None:
connector_instance, fixture = connector()
_add_validated_head_branch(fixture)
_force_empty_actions_wrapper(connector_instance)
try:
merged = connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)["data"]
assert merged["validationRunId"] == 42
assert fixture._pulls[0]["merged"] is True
finally:
connector_instance.client.close()
def test_merge_accepts_exact_head_managed_run_when_gitea_omits_workflow_id() -> None:
connector_instance, fixture = connector()
_add_validated_head_branch(fixture)
fixture._action_run.pop("workflow_id")
try:
review = connector_instance.change_review(context(), "hub-repository", "codex/workflows")[
"data"
]
assert review["readyToMerge"] is True
assert review["validationRuns"][0]["id"] > 0
assert review["validationRuns"][0]["workflowId"] == ""
merged = connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)["data"]
assert merged["merged"] is True
assert merged["validationRunId"] > 0
assert fixture._pulls[0]["merged"] is True
finally:
connector_instance.client.close()
def test_green_workflow_dispatch_cannot_authorize_pr_merge() -> None:
connector_instance, fixture = connector()
fixture._action_run["event"] = "workflow_dispatch"
try:
with pytest.raises(GiteaError) as captured:
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert captured.value.code == "GITEA_PR_VALIDATION_REQUIRED"
assert fixture._pulls[0].get("merged") is not True
finally:
connector_instance.client.close()
def test_green_pr_run_for_old_sha_cannot_authorize_merge() -> None:
connector_instance, fixture = connector()
fixture._action_run["head_sha"] = "d" * 40
try:
with pytest.raises(GiteaError) as captured:
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert captured.value.code == "GITEA_PR_VALIDATION_REQUIRED"
assert fixture._pulls[0].get("merged") is not True
finally:
connector_instance.client.close()
def test_green_pr_run_with_pending_required_context_cannot_authorize_merge() -> None:
connector_instance, fixture = connector()
fixture._statuses[0]["status"] = "pending"
try:
with pytest.raises(GiteaError) as captured:
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert captured.value.code == "GITEA_PR_CHECK_PENDING"
assert fixture._pulls[0].get("merged") is not True
finally:
connector_instance.client.close()
def test_status_linked_pr_run_without_workflow_id_requires_green_full_job() -> None:
connector_instance, fixture = connector()
fixture._action_run.pop("workflow_id")
fixture._action_job["conclusion"] = "failure"
try:
with pytest.raises(GiteaError) as captured:
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert captured.value.code == "GITEA_PR_VALIDATION_REQUIRED"
assert fixture._pulls[0].get("merged") is not True
finally:
connector_instance.client.close()
def test_empty_actions_wrapper_fails_closed_when_latest_status_is_pending() -> None:
connector_instance, fixture = connector()
_add_validated_head_branch(fixture)
fixture._statuses[0]["status"] = "pending"
_force_empty_actions_wrapper(connector_instance)
try:
validation_items = connector_instance.validation_list(
context(),
"hub-repository",
"codex/workflows",
page=PageRequest(limit=10),
)["data"]["items"]
assert validation_items == []
with pytest.raises(GiteaError, match="status is not successful"):
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert fixture._pulls[0].get("merged") is not True
assert not any(body.get("Do") == "squash" for body in fixture.recorded_bodies)
finally:
connector_instance.client.close()
def test_merge_reports_pending_readiness_instead_of_unsupported_capability() -> None:
connector_instance, _ = connector()
writer = connector_instance._writer()
def reject_pending(*args, **kwargs):
raise GiteaError(
"GITEA_STATE_TRANSITION_DENIED",
"Gitea rejected the requested state transition",
)
writer.merge_pull_request = reject_pending
try:
with pytest.raises(GiteaError) as captured:
connector_instance.pull_request_merge(
context(), "hub-repository", 7, "e" * 40, "squash"
)
assert captured.value.code == "GITEA_UPSTREAM_MERGE_REJECTED"
assert "after eligibility verification" in str(captured.value)
assert "unsupported" not in str(captured.value).casefold()
finally:
connector_instance.client.close()