feat: feedback_api — build_issue_body
This commit is contained in:
parent
6764ad4288
commit
1940cfb131
2 changed files with 102 additions and 0 deletions
|
|
@ -82,3 +82,46 @@ def collect_listings(db_path: Path | None = None, n: int = 5) -> list[dict]:
|
|||
).fetchall()
|
||||
conn.close()
|
||||
return [{"title": r["title"], "company": r["company"], "url": r["url"]} for r in rows]
|
||||
|
||||
|
||||
def build_issue_body(form: dict, context: dict, attachments: dict) -> str:
|
||||
"""Assemble the Forgejo issue markdown body from form data, context, and attachments."""
|
||||
_TYPE_LABELS = {"bug": "🐛 Bug", "feature": "✨ Feature Request", "other": "💬 Other"}
|
||||
lines: list[str] = [
|
||||
f"## {_TYPE_LABELS.get(form.get('type', 'other'), '💬 Other')}",
|
||||
"",
|
||||
form.get("description", ""),
|
||||
"",
|
||||
]
|
||||
|
||||
if form.get("type") == "bug" and form.get("repro"):
|
||||
lines += ["### Reproduction Steps", "", form["repro"], ""]
|
||||
|
||||
if context:
|
||||
lines += ["### Context", ""]
|
||||
for k, v in context.items():
|
||||
lines.append(f"- **{k}:** {v}")
|
||||
lines.append("")
|
||||
|
||||
if attachments.get("logs"):
|
||||
lines += [
|
||||
"<details>",
|
||||
"<summary>App Logs (last 100 lines)</summary>",
|
||||
"",
|
||||
"```",
|
||||
attachments["logs"],
|
||||
"```",
|
||||
"</details>",
|
||||
"",
|
||||
]
|
||||
|
||||
if attachments.get("listings"):
|
||||
lines += ["### Recent Listings", ""]
|
||||
for j in attachments["listings"]:
|
||||
lines.append(f"- [{j['title']} @ {j['company']}]({j['url']})")
|
||||
lines.append("")
|
||||
|
||||
if attachments.get("submitter"):
|
||||
lines += ["---", f"*Submitted by: {attachments['submitter']}*"]
|
||||
|
||||
return "\n".join(lines)
|
||||
|
|
|
|||
|
|
@ -119,3 +119,62 @@ def test_collect_listings_respects_n(tmp_path):
|
|||
"salary": "", "description": "", "date_found": "2026-03-01",
|
||||
})
|
||||
assert len(collect_listings(db_path=db, n=3)) == 3
|
||||
|
||||
|
||||
# ── build_issue_body ──────────────────────────────────────────────────────────
|
||||
|
||||
def test_build_issue_body_contains_description():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "bug", "title": "Test", "description": "it broke", "repro": ""}
|
||||
ctx = {"page": "Home", "version": "v1.0", "tier": "free",
|
||||
"llm_backend": "ollama", "os": "Linux", "timestamp": "2026-03-03T00:00:00Z"}
|
||||
body = build_issue_body(form, ctx, {})
|
||||
assert "it broke" in body
|
||||
assert "Home" in body
|
||||
assert "v1.0" in body
|
||||
|
||||
|
||||
def test_build_issue_body_bug_includes_repro():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "bug", "title": "X", "description": "desc", "repro": "step 1\nstep 2"}
|
||||
body = build_issue_body(form, {}, {})
|
||||
assert "step 1" in body
|
||||
assert "Reproduction" in body
|
||||
|
||||
|
||||
def test_build_issue_body_no_repro_for_feature():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "feature", "title": "X", "description": "add dark mode", "repro": "ignored"}
|
||||
body = build_issue_body(form, {}, {})
|
||||
assert "Reproduction" not in body
|
||||
|
||||
|
||||
def test_build_issue_body_logs_in_collapsible():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "other", "title": "X", "description": "Y", "repro": ""}
|
||||
body = build_issue_body(form, {}, {"logs": "log line 1\nlog line 2"})
|
||||
assert "<details>" in body
|
||||
assert "log line 1" in body
|
||||
|
||||
|
||||
def test_build_issue_body_omits_logs_when_not_provided():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "bug", "title": "X", "description": "Y", "repro": ""}
|
||||
body = build_issue_body(form, {}, {})
|
||||
assert "<details>" not in body
|
||||
|
||||
|
||||
def test_build_issue_body_submitter_attribution():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "bug", "title": "X", "description": "Y", "repro": ""}
|
||||
body = build_issue_body(form, {}, {"submitter": "Jane Doe <jane@example.com>"})
|
||||
assert "Jane Doe" in body
|
||||
|
||||
|
||||
def test_build_issue_body_listings_shown():
|
||||
from scripts.feedback_api import build_issue_body
|
||||
form = {"type": "bug", "title": "X", "description": "Y", "repro": ""}
|
||||
listings = [{"title": "CSM", "company": "Acme", "url": "https://example.com/1"}]
|
||||
body = build_issue_body(form, {}, {"listings": listings})
|
||||
assert "CSM" in body
|
||||
assert "Acme" in body
|
||||
|
|
|
|||
Loading…
Reference in a new issue