tests/test_issue_intake.py
Rama master · réplica de lectura del repositorio original.
"""外部 issue 模板检查的判定;GitHub 写操作在工作流里,这里只验证脚本给出的结论。"""
from __future__ import annotations
import io
import json
import sys
import tempfile
import unittest
from contextlib import redirect_stdout
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
import issue_intake # noqa: E402
JARGON_BODY = "## 目标\n\n导入资料,不做真实账本写入。\n\n## 授权边界\n\n测试使用合成样本。\n"
FEATURE_BODY = "## 使用场景 / Use case\n\n想按女优查看全部作品。\n\n## 期望的行为 / Desired behavior\n\n列出作品。\n"
BUG_BODY = "### 问题描述\n\n闪退\n\n### Environment\n\nWindows 11\n"
def event(action="opened", body=JARGON_BODY, **issue):
return {"action": action, "issue": {"body": body, "author_association": "NONE",
"user": {"type": "User"}, "type": None, "state": "open",
"labels": [], **issue}}
class IssueIntakeTests(unittest.TestCase):
def test_templates_supply_issue_type_and_bilingual_section_names(self):
templates = dict(issue_intake.load_templates())
self.assertIn(("问题描述", "what happened"), templates["Bug"])
self.assertIn(("使用场景", "use case"), templates["Feature"])
self.assertIn(("补充", "additional context"), templates["Feature"])
def test_command_line_issue_that_follows_a_template_gets_its_type(self):
self.assertEqual(issue_intake.verdict(event(body=FEATURE_BODY + "\n不写入账本。\n")), "type Feature")
self.assertEqual(issue_intake.verdict(event(body=BUG_BODY)), "type Bug")
self.assertEqual(issue_intake.verdict(event("edited", BUG_BODY)), "type Bug")
def test_untyped_new_issue_without_template_sections_is_closed(self):
for body in (JARGON_BODY, "希望垃圾文件可以批量删除", ""):
with self.subTest(body=body[:12]):
self.assertEqual(issue_intake.verdict(event(body=body)), "close")
self.assertEqual(issue_intake.verdict(event("edited")), "keep")
def test_已有类型的新问题缺少模板章节时关闭(self):
for kind in ("Bug", "Feature"):
for body in (JARGON_BODY, "nas中docker无法自动更新,是不是因为版本号是edge的原因,能不能优化一下", ""):
with self.subTest(kind=kind, body=body[:12]):
self.assertEqual(issue_intake.verdict(event(body=body, type={"name": kind})), "close")
def test_已有类型且符合模板的问题保留类型(self):
for action in ("opened", "edited"):
for kind, body in (("Bug", BUG_BODY), ("Feature", FEATURE_BODY)):
with self.subTest(action=action, kind=kind):
self.assertEqual(issue_intake.verdict(event(action, body, type={"name": kind})), "keep")
def test_已有类型的待补模板问题补齐后按正文类型重开(self):
closed = {"state": "closed", "labels": [{"name": issue_intake.LABEL}], "type": {"name": "Feature"}}
self.assertEqual(issue_intake.verdict(event("edited", BUG_BODY, **closed)), "reopen Bug")
self.assertEqual(issue_intake.verdict(event("edited", JARGON_BODY, **closed)), "keep")
def test_maintainers_bots_and_pull_requests_are_exempt(self):
for issue in ({"author_association": "MEMBER"}, {"author_association": "OWNER"},
{"author_association": "COLLABORATOR"}, {"user": {"type": "Bot"}},
{"pull_request": {"url": "x"}}):
with self.subTest(issue=issue):
self.assertEqual(issue_intake.verdict(event(**issue)), "keep")
def test_closed_issue_reopens_with_its_type_once_the_sections_are_filled_in(self):
closed = {"state": "closed", "labels": [{"name": issue_intake.LABEL}]}
self.assertEqual(issue_intake.verdict(event("edited", FEATURE_BODY, **closed)), "reopen Feature")
self.assertEqual(issue_intake.verdict(event("edited", JARGON_BODY, **closed)), "keep")
self.assertEqual(issue_intake.verdict(event("edited", FEATURE_BODY, state="closed")), "keep")
def test_重开后只折叠工作流留下的模板提示(self):
comments = [
{"node_id": "notice", "user": {"login": "github-actions[bot]"}, "body": issue_intake.NOTICE},
{"node_id": "other-bot", "user": {"login": "github-actions[bot]"}, "body": "已加入项目看板。"},
{"node_id": "quote", "user": {"login": "reporter"}, "body": issue_intake.NOTICE},
{"node_id": "deleted-user", "user": None, "body": None},
]
self.assertEqual(issue_intake.notice_ids(comments), ["notice"])
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "comments.json"
path.write_text(json.dumps(comments, ensure_ascii=False), encoding="utf-8")
out = io.StringIO()
with redirect_stdout(out):
self.assertEqual(issue_intake.main(["--notice-ids", str(path)]), 0)
self.assertEqual(out.getvalue().split(), ["notice"])
def test_cli_reads_the_event_file_and_prints_the_notice(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "event.json"
path.write_text(json.dumps(event(), ensure_ascii=False), encoding="utf-8")
out = io.StringIO()
with redirect_stdout(out):
self.assertEqual(issue_intake.main(["--event", str(path)]), 0)
self.assertEqual(out.getvalue().strip(), "close")
out = io.StringIO()
with redirect_stdout(out):
issue_intake.main(["--notice"])
self.assertIn("issues/new/choose", out.getvalue())
self.assertIn("This issue was closed automatically", out.getvalue())
if __name__ == "__main__":
unittest.main()