test: issue, pull request, release, secret, variable and webhook scenarios
This commit is contained in:
1 parent
51c766b231
commit
825c3c93e2
2 files changed
+489
No files matched your search
@@ -0,0 +1,224 @@
|
||||
"""Scenarios: issues (labels, milestones, time tracking, reactions) and pull requests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
|
||||
from tests.integration.conftest import McpSession, RegularUser, RepoRef, b64
|
||||
from tests.integration.harness import GiteaInstance
|
||||
|
||||
|
||||
async def test_issue_lifecycle(
|
||||
mcp: McpSession, regular_user: RegularUser, fresh_repo: RepoRef
|
||||
) -> None:
|
||||
repo = fresh_repo.args
|
||||
watcher = regular_user.login
|
||||
|
||||
issue = await mcp.ok(
|
||||
"gitea_issue_create_issue",
|
||||
status=201,
|
||||
body={"title": "Broken widget", "body": "It does not widget."},
|
||||
**repo,
|
||||
)
|
||||
index = issue.data["number"]
|
||||
assert issue.data["state"] == "open"
|
||||
|
||||
# Comments.
|
||||
comment = await mcp.ok(
|
||||
"gitea_issue_create_comment", status=201, index=index, body={"body": "first"}, **repo
|
||||
)
|
||||
comment_id = comment.data["id"]
|
||||
edited = await mcp.ok(
|
||||
"gitea_issue_edit_comment", id=comment_id, body={"body": "first, edited"}, **repo
|
||||
)
|
||||
assert edited.data["body"] == "first, edited"
|
||||
comments = await mcp.ok("gitea_issue_get_comments", index=index, **repo)
|
||||
assert [item["body"] for item in comments.data] == ["first, edited"]
|
||||
|
||||
# Labels: create, add, remove.
|
||||
label = await mcp.ok(
|
||||
"gitea_issue_create_label",
|
||||
status=201,
|
||||
body={"name": "bug", "color": "#d73a4a", "description": "something is broken"},
|
||||
**repo,
|
||||
)
|
||||
label_id = label.data["id"]
|
||||
added = await mcp.ok("gitea_issue_add_label", index=index, body={"labels": [label_id]}, **repo)
|
||||
assert [item["name"] for item in added.data] == ["bug"]
|
||||
assert (await mcp.ok("gitea_issue_get_labels", index=index, **repo)).data
|
||||
await mcp.ok("gitea_issue_remove_label", index=index, id=label_id, **repo)
|
||||
assert (await mcp.ok("gitea_issue_get_labels", index=index, **repo)).data == []
|
||||
await mcp.ok("gitea_issue_replace_labels", index=index, body={"labels": [label_id]}, **repo)
|
||||
await mcp.ok("gitea_issue_clear_labels", index=index, **repo)
|
||||
|
||||
# Milestone.
|
||||
milestone = await mcp.ok(
|
||||
"gitea_issue_create_milestone", status=201, body={"title": "v1"}, **repo
|
||||
)
|
||||
await mcp.ok(
|
||||
"gitea_issue_edit_issue", index=index, body={"milestone": milestone.data["id"]}, **repo
|
||||
)
|
||||
assert (await mcp.ok("gitea_issue_get_issue", index=index, **repo)).data["milestone"][
|
||||
"title"
|
||||
] == "v1"
|
||||
|
||||
# Pin and unpin.
|
||||
await mcp.ok("gitea_issue_pin_issue", index=index, **repo)
|
||||
pinned = await mcp.ok("gitea_issue_list_pinned_issues", **repo)
|
||||
assert [item["number"] for item in pinned.data] == [index]
|
||||
await mcp.ok("gitea_issue_unpin_issue", index=index, **repo)
|
||||
assert (await mcp.ok("gitea_issue_list_pinned_issues", **repo)).data == []
|
||||
|
||||
# Subscriptions.
|
||||
await mcp.ok(
|
||||
"gitea_issue_add_subscription", status=(200, 201), index=index, user=watcher, **repo
|
||||
)
|
||||
subscribers = await mcp.ok("gitea_issue_subscriptions", index=index, **repo)
|
||||
assert watcher in [item["login"] for item in subscribers.data]
|
||||
await mcp.ok("gitea_issue_delete_subscription", index=index, user=watcher, **repo)
|
||||
assert (await mcp.ok("gitea_issue_subscriptions", index=index, **repo)).data == []
|
||||
|
||||
# Time tracking and the stopwatch.
|
||||
await mcp.ok("gitea_issue_add_time", index=index, body={"time": 3600}, **repo)
|
||||
times = await mcp.ok("gitea_issue_tracked_times", index=index, **repo)
|
||||
assert [item["time"] for item in times.data] == [3600]
|
||||
await mcp.ok("gitea_issue_delete_time", index=index, id=times.data[0]["id"], **repo)
|
||||
assert (await mcp.ok("gitea_issue_tracked_times", index=index, **repo)).data == []
|
||||
await mcp.ok("gitea_issue_start_stopwatch", status=201, index=index, **repo)
|
||||
running = await mcp.ok("gitea_user_get_stopwatches")
|
||||
assert index in [item["issue_index"] for item in running.data]
|
||||
await mcp.ok("gitea_issue_stop_stopwatch", status=201, index=index, **repo)
|
||||
assert (await mcp.ok("gitea_issue_tracked_times", index=index, **repo)).data
|
||||
|
||||
# Reactions.
|
||||
await mcp.ok(
|
||||
"gitea_issue_post_issue_reaction",
|
||||
status=(200, 201),
|
||||
index=index,
|
||||
body={"content": "+1"},
|
||||
**repo,
|
||||
)
|
||||
reactions = await mcp.ok("gitea_issue_get_issue_reactions", index=index, **repo)
|
||||
assert [item["content"] for item in reactions.data] == ["+1"]
|
||||
await mcp.ok("gitea_issue_delete_issue_reaction", index=index, body={"content": "+1"}, **repo)
|
||||
|
||||
# Search finds the issue (indexing is asynchronous, so poll briefly).
|
||||
deadline = time.monotonic() + 20
|
||||
hits: list[int] = []
|
||||
while time.monotonic() < deadline and index not in hits:
|
||||
found = await mcp.ok("gitea_issue_list_issues", q="widget", **repo)
|
||||
hits = [item["number"] for item in found.data]
|
||||
if index not in hits:
|
||||
time.sleep(0.5)
|
||||
assert index in hits
|
||||
assert (await mcp.ok("gitea_issue_search_issues", q="Broken widget")).data is not None
|
||||
|
||||
# Close.
|
||||
closed = await mcp.ok("gitea_issue_edit_issue", index=index, body={"state": "closed"}, **repo)
|
||||
assert closed.data["state"] == "closed"
|
||||
assert (await mcp.ok("gitea_issue_get_issue", index=index, **repo)).data["state"] == "closed"
|
||||
await mcp.ok("gitea_issue_delete_comment", id=comment_id, **repo)
|
||||
await mcp.ok("gitea_issue_delete_label", id=label_id, **repo)
|
||||
await mcp.ok("gitea_issue_delete_milestone", id=str(milestone.data["id"]), **repo)
|
||||
|
||||
|
||||
async def test_pull_request_review_and_merge(
|
||||
mcp: McpSession, gitea: GiteaInstance, regular_user: RegularUser, fresh_repo: RepoRef
|
||||
) -> None:
|
||||
repo = fresh_repo.args
|
||||
reviewer = regular_user.login
|
||||
await mcp.ok(
|
||||
"gitea_repo_add_collaborator",
|
||||
collaborator=reviewer,
|
||||
body={"permission": "write"},
|
||||
**repo,
|
||||
)
|
||||
try:
|
||||
# A branch with a change, pushed through the contents API.
|
||||
await mcp.ok(
|
||||
"gitea_repo_create_branch",
|
||||
status=201,
|
||||
body={"new_branch_name": "feat/greeting", "old_branch_name": "main"},
|
||||
**repo,
|
||||
)
|
||||
await mcp.ok(
|
||||
"gitea_repo_create_file",
|
||||
status=201,
|
||||
filepath="greeting.txt",
|
||||
body={
|
||||
"content": b64("hello pull request\n"),
|
||||
"message": "add greeting",
|
||||
"branch": "feat/greeting",
|
||||
},
|
||||
**repo,
|
||||
)
|
||||
pull = await mcp.ok(
|
||||
"gitea_pull_create_pull_request",
|
||||
status=201,
|
||||
body={"title": "Add greeting", "base": "main", "head": "feat/greeting"},
|
||||
**repo,
|
||||
)
|
||||
index = pull.data["number"]
|
||||
assert pull.data["state"] == "open"
|
||||
assert not pull.data["merged"]
|
||||
|
||||
files = await mcp.ok("gitea_pull_get_pull_request_files", index=index, **repo)
|
||||
assert [item["filename"] for item in files.data] == ["greeting.txt"]
|
||||
commits = await mcp.ok("gitea_pull_get_pull_request_commits", index=index, **repo)
|
||||
assert len(commits.data) == 1
|
||||
|
||||
diff = await mcp.ok(
|
||||
"gitea_pull_download_pull_diff_or_patch", index=index, diffType="diff", **repo
|
||||
)
|
||||
assert isinstance(diff.data, str)
|
||||
assert "+hello pull request" in diff.data
|
||||
|
||||
# Requested reviewer, then a pending review with an inline comment (as the
|
||||
# reviewer, through sudo), submitted as an approval.
|
||||
await mcp.ok(
|
||||
"gitea_pull_create_pull_review_requests",
|
||||
status=201,
|
||||
index=index,
|
||||
body={"reviewers": [reviewer]},
|
||||
**repo,
|
||||
)
|
||||
pending = await mcp.ok(
|
||||
"gitea_pull_create_pull_review",
|
||||
sudo=reviewer,
|
||||
index=index,
|
||||
body={
|
||||
"body": "looks fine",
|
||||
"comments": [{"path": "greeting.txt", "new_position": 1, "body": "nice"}],
|
||||
},
|
||||
**repo,
|
||||
)
|
||||
assert pending.identity["sudo"] == reviewer
|
||||
review_id = pending.data["id"]
|
||||
assert pending.data["state"] == "PENDING"
|
||||
submitted = await mcp.ok(
|
||||
"gitea_pull_submit_pull_review",
|
||||
sudo=reviewer,
|
||||
index=index,
|
||||
id=review_id,
|
||||
body={"event": "APPROVED", "body": "approved"},
|
||||
**repo,
|
||||
)
|
||||
assert submitted.data["state"] == "APPROVED"
|
||||
reviews = await mcp.ok("gitea_pull_list_pull_reviews", index=index, **repo)
|
||||
assert "APPROVED" in [item["state"] for item in reviews.data]
|
||||
comments = await mcp.ok(
|
||||
"gitea_pull_get_pull_review_comments", index=index, id=review_id, **repo
|
||||
)
|
||||
assert [item["body"] for item in comments.data] == ["nice"]
|
||||
|
||||
# Not merged yet, then merged.
|
||||
await mcp.fail("gitea_pull_pull_request_is_merged", 404, index=index, **repo)
|
||||
await mcp.ok("gitea_pull_merge_pull_request", index=index, body={"do": "merge"}, **repo)
|
||||
await mcp.ok("gitea_pull_pull_request_is_merged", index=index, **repo)
|
||||
merged = await mcp.ok("gitea_pull_get_pull_request", index=index, **repo)
|
||||
assert merged.data["merged"] is True
|
||||
assert merged.data["state"] == "closed"
|
||||
readme = await mcp.ok("gitea_repo_get_contents", filepath="greeting.txt", **repo)
|
||||
assert readme.data["path"] == "greeting.txt"
|
||||
finally:
|
||||
gitea.api("DELETE", f"/repos/{fresh_repo.owner}/{fresh_repo.name}/collaborators/{reviewer}")
|
||||
Reference in new issue
Block a user