Files
2026-07-13 11:59:58 +08:00

217 lines
6.9 KiB
Python

"""Tests for the GitHub webhook → prompt translator."""
from __future__ import annotations
from app.gateway.github.prompts import build_prompt
def test_pull_request_prompt_contains_core_fields() -> None:
payload = {
"action": "opened",
"pull_request": {
"number": 7,
"title": "Add webhook receiver",
"user": {"login": "zhfeng"},
"html_url": "https://github.com/a/b/pull/7",
"body": "This adds X and fixes Y.",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request", payload)
assert "pull request" in prompt.lower()
assert "#7" in prompt
assert "Add webhook receiver" in prompt
assert "zhfeng" in prompt
assert "https://github.com/a/b/pull/7" in prompt
assert "This adds X and fixes Y." in prompt
def test_pull_request_prompt_handles_missing_body() -> None:
payload = {
"action": "opened",
"pull_request": {"number": 1, "title": "x", "user": {}, "body": None},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request", payload)
assert "(no description)" in prompt
def test_pull_request_prompt_truncates_huge_body() -> None:
huge = "X" * 50000
payload = {
"action": "opened",
"pull_request": {"number": 1, "title": "x", "user": {}, "body": huge},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request", payload)
assert "truncated" in prompt
assert len(prompt) < 10000
def test_issue_comment_prompt_includes_body_verbatim() -> None:
payload = {
"action": "created",
"issue": {"number": 11, "pull_request": {"url": "..."}},
"comment": {
"body": "Hey @coding-llm-gateway please look at this",
"user": {"login": "zhfeng"},
"html_url": "https://github.com/a/b/issues/11#issuecomment-1",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("issue_comment", payload)
assert "pull request #11" in prompt # is_pr True
assert "@coding-llm-gateway please look at this" in prompt
assert "zhfeng" in prompt
def test_issue_comment_plain_issue_says_issue() -> None:
payload = {
"action": "created",
"issue": {"number": 12},
"comment": {"body": "x", "user": {"login": "u"}},
"repository": {"full_name": "a/b"},
}
assert "issue #12" in build_prompt("issue_comment", payload)
def test_issue_comment_prompt_includes_issue_title_and_body() -> None:
"""The comment alone isn't enough — the agent needs the issue context too.
The webhook payload already includes the parent issue/PR's title and body
on the ``issue`` object; we just have to render them.
"""
payload = {
"action": "created",
"issue": {
"number": 42,
"title": "Login button is broken",
"body": "Clicking login throws a 500. Repro: open /login, click submit.",
"user": {"login": "reporter"},
},
"comment": {
"body": "@bot what do you think?",
"user": {"login": "asker"},
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("issue_comment", payload)
assert "Login button is broken" in prompt
assert "Clicking login throws a 500" in prompt
assert "reporter" in prompt # issue author, distinct from comment author
assert "@bot what do you think?" in prompt
def test_pull_request_review_comment_includes_pr_title_and_body() -> None:
payload = {
"action": "created",
"pull_request": {
"number": 9,
"title": "Refactor auth flow",
"body": "Splits AuthService into AuthN/AuthZ.",
"user": {"login": "author"},
},
"comment": {
"user": {"login": "alice"},
"path": "src/foo.py",
"line": 42,
"diff_hunk": "@@ -1 +1 @@\n-a\n+b",
"body": "consider renaming",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request_review_comment", payload)
assert "Refactor auth flow" in prompt
assert "Splits AuthService into AuthN/AuthZ." in prompt
assert "consider renaming" in prompt
def test_pull_request_review_prompt_includes_pr_title_and_body() -> None:
payload = {
"action": "submitted",
"pull_request": {
"number": 5,
"title": "Bump deps",
"body": "Updates everything to latest.",
"user": {"login": "author"},
},
"review": {
"state": "changes_requested",
"user": {"login": "alice"},
"body": "Looks risky",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request_review", payload)
assert "Bump deps" in prompt
assert "Updates everything to latest." in prompt
assert "changes_requested" in prompt
assert "Looks risky" in prompt
def test_pull_request_review_comment_includes_file_and_diff() -> None:
payload = {
"action": "created",
"pull_request": {"number": 9},
"comment": {
"user": {"login": "alice"},
"path": "src/foo.py",
"line": 42,
"diff_hunk": "@@ -1,3 +1,4 @@\n a\n+b\n c",
"body": "consider renaming",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request_review_comment", payload)
assert "src/foo.py:42" in prompt
assert "+b" in prompt
assert "consider renaming" in prompt
def test_pull_request_review_prompt_includes_state() -> None:
payload = {
"action": "submitted",
"pull_request": {"number": 5},
"review": {
"state": "changes_requested",
"user": {"login": "alice"},
"body": "Looks risky",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("pull_request_review", payload)
assert "changes_requested" in prompt
assert "Looks risky" in prompt
assert "alice" in prompt
def test_issues_prompt() -> None:
payload = {
"action": "opened",
"issue": {
"number": 3,
"title": "bug",
"user": {"login": "u"},
"html_url": "https://github.com/a/b/issues/3",
"body": "things broken",
},
"repository": {"full_name": "a/b"},
}
prompt = build_prompt("issues", payload)
assert "#3" in prompt
assert "bug" in prompt
assert "things broken" in prompt
def test_ping_prompt() -> None:
payload = {"zen": "Practicality beats purity.", "hook": {"id": 42}}
prompt = build_prompt("ping", payload)
assert "ping" in prompt.lower()
assert "42" in prompt
def test_unknown_event_returns_generic_stub() -> None:
prompt = build_prompt("workflow_run", {"action": "completed", "repository": {"full_name": "a/b"}})
assert "workflow_run" in prompt
assert "a/b" in prompt