From 98bb07a6e1303042b6a7a481c6d16d3c9d3cd933 Mon Sep 17 00:00:00 2001 From: TJCurnutte <211682330+TJCurnutte@users.noreply.github.com> Date: Wed, 13 May 2026 18:43:55 -0400 Subject: [PATCH] test: add CodeBounty issue 79 markdown fixture --- bounty-notes/issue-79-markdown-upload.md | 28 +++++ scripts/validate-codebounty-issue-79.py | 114 ++++++++++++++++++ .../codebounty-issue-79-markdown-upload.json | 54 +++++++++ 3 files changed, 196 insertions(+) create mode 100644 bounty-notes/issue-79-markdown-upload.md create mode 100644 scripts/validate-codebounty-issue-79.py create mode 100644 test-fixtures/codebounty-issue-79-markdown-upload.json diff --git a/bounty-notes/issue-79-markdown-upload.md b/bounty-notes/issue-79-markdown-upload.md new file mode 100644 index 0000000..87ff232 --- /dev/null +++ b/bounty-notes/issue-79-markdown-upload.md @@ -0,0 +1,28 @@ +# CodeBounty issue #79 markdown/upload note + +Issue: https://github.com/CodeBountyOrg/BountyTestRepository/issues/79 + +## Snapshot + +- State: open +- Locked: false +- Assignees: none +- Labels: `enhancement`; bounty label absent in the live issue snapshot +- Visible CodeBounty amount: `$50 USD`, sourced from two CodeBounty bot announcement comments +- Required PR syntax from bot announcements: `fixes #79` +- Issue body includes bold markdown and a failed upload marker: `*Failed to upload Screenshot 2025-04-01 at 4.36.27 PM.png*` +- Collision searches run immediately before this branch: `79`, `fixes #79`, `issue 79`, and `test issue april 3 12pm`; exact same-scope open PR count was `0`. + +## Payout boundary + +This is a submitted-visible CodeBounty action only. The bot announcement says a developer must submit an application through CodeBounty to be eligible, and this issue does not currently carry the `💰 Bounty Available` label. Do not treat this PR as verified-payable or paid until platform/maintainer acceptance is confirmed. + +## Local validation + +```bash +python3 -m py_compile scripts/validate-codebounty-issue-79.py +python3 scripts/validate-codebounty-issue-79.py test-fixtures/codebounty-issue-79-markdown-upload.json +git diff --check +``` + +The PR body should include `fixes #79` to satisfy the CodeBounty linkage rule and should preserve the `developer_application_required` / `bounty_label_absent` payout blockers. diff --git a/scripts/validate-codebounty-issue-79.py b/scripts/validate-codebounty-issue-79.py new file mode 100644 index 0000000..9bb2f34 --- /dev/null +++ b/scripts/validate-codebounty-issue-79.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +"""Validate the CodeBounty issue #79 markdown/upload fixture. + +The fixture records the live GitHub + CodeBounty snapshot used for this PR. +It keeps the payout boundary explicit: the visible amount comes from bot +announcement comments, not from a verified platform application or payment. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + + +EXPECTED_BOUNTY_LINKS = { + "http://localhost:3000/bounty/67f1cc90f54cb17267113c7e", + "http://localhost:3000/bounty/67f1ccb1f54cb17267113c83", +} + + +def fail(message: str) -> None: + raise SystemExit(f"issue-79 fixture invalid: {message}") + + +def main() -> None: + if len(sys.argv) != 2: + fail("usage: validate-codebounty-issue-79.py ") + + path = Path(sys.argv[1]) + if not path.is_file(): + fail(f"missing fixture: {path}") + + data = json.loads(path.read_text(encoding="utf-8")) + issue = data.get("issue") or {} + bounty = data.get("bounty") or {} + markdown = data.get("markdown_upload_snapshot") or {} + collision = data.get("collision_snapshot") or {} + expected_pr = data.get("expected_pr") or {} + + if issue.get("number") != 79: + fail("issue number must be 79") + if issue.get("state") != "open": + fail("issue must be open at snapshot time") + if issue.get("locked") is not False: + fail("locked must be false at snapshot time") + if issue.get("assignees") != []: + fail("issue must be unassigned at snapshot time") + if "enhancement" not in issue.get("labels", []): + fail("enhancement label missing from live snapshot") + if "💰 Bounty Available" in issue.get("labels", []): + fail("snapshot should document that issue #79 does not carry the bounty label") + + body = issue.get("body", "") + if "**testing markdown**" not in body: + fail("issue body markdown sample missing") + if "failed to upload" not in body.lower(): + fail("failed-upload marker missing from issue body") + + if bounty.get("platform") != "CodeBounty": + fail("platform must be CodeBounty") + if bounty.get("visible_amount_usd") != 50: + fail("visible bounty amount must be $50") + if bounty.get("visible_amount_source") != "bot_comments": + fail("visible amount source must stay scoped to bot comments") + if bounty.get("announcement_comment_count") != 2: + fail("expected two CodeBounty bot announcement comments") + if bounty.get("required_pr_linkage", "").lower() != "fixes #79": + fail("required PR linkage must be `fixes #79`") + if bounty.get("developer_application_required") is not True: + fail("developer application requirement must stay explicit") + if bounty.get("verified_payable_at_snapshot") is not False: + fail("fixture must not claim verified-payable payout") + if set(bounty.get("bounty_links", [])) != EXPECTED_BOUNTY_LINKS: + fail("bounty links should match both announcement comment links") + + if markdown.get("bold_markdown_preserved") is not True: + fail("markdown preservation flag must be true") + if markdown.get("failed_upload_recorded") is not True: + fail("failed upload evidence flag must be true") + + if collision.get("repo_archived") is not False: + fail("repo must be non-archived at snapshot time") + if collision.get("repo_visibility") != "PUBLIC": + fail("repo visibility must be PUBLIC") + if collision.get("same_scope_open_pr_count") != 0: + fail("same-scope open PR count must be zero at snapshot time") + terms = {term.lower() for term in collision.get("open_pr_search_terms", [])} + if {"79", "fixes #79", "issue 79", "test issue april 3 12pm"} - terms: + fail("collision-search terms are incomplete") + + required_body = {item.lower() for item in expected_pr.get("body_must_include", [])} + for required in {"fixes #79", "codebounty", "$50", "developer_application_required", "bounty_label_absent"}: + if required not in required_body: + fail(f"expected PR body requirement missing: {required}") + + print( + json.dumps( + { + "ok": True, + "issue": issue["number"], + "visible_amount_usd": bounty["visible_amount_usd"], + "visible_amount_source": bounty["visible_amount_source"], + "required_pr_linkage": bounty["required_pr_linkage"], + "verified_payable_at_snapshot": bounty["verified_payable_at_snapshot"], + "same_scope_open_pr_count": collision["same_scope_open_pr_count"], + }, + sort_keys=True, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/test-fixtures/codebounty-issue-79-markdown-upload.json b/test-fixtures/codebounty-issue-79-markdown-upload.json new file mode 100644 index 0000000..e531988 --- /dev/null +++ b/test-fixtures/codebounty-issue-79-markdown-upload.json @@ -0,0 +1,54 @@ +{ + "issue": { + "number": 79, + "url": "https://github.com/CodeBountyOrg/BountyTestRepository/issues/79", + "title": "test issue april 3 12pm", + "state": "open", + "body": "test\n\n**testing markdown**\n\n*Failed to upload Screenshot 2025-04-01 at 4.36.27 PM.png*", + "labels": ["enhancement"], + "assignees": [], + "locked": false + }, + "bounty": { + "platform": "CodeBounty", + "visible_amount_usd": 50, + "visible_amount_source": "bot_comments", + "status_at_snapshot": "announced_by_two_bot_comments_bounty_label_absent", + "announcement_comment_count": 2, + "announcement_comments": [ + "https://github.com/CodeBountyOrg/BountyTestRepository/issues/79#issuecomment-2781152381", + "https://github.com/CodeBountyOrg/BountyTestRepository/issues/79#issuecomment-2781152397" + ], + "bounty_links": [ + "http://localhost:3000/bounty/67f1cc90f54cb17267113c7e", + "http://localhost:3000/bounty/67f1ccb1f54cb17267113c83" + ], + "required_pr_linkage": "fixes #79", + "developer_application_required": true, + "verified_payable_at_snapshot": false, + "blocker": "The CodeBounty announcement requires a platform application; GitHub-only PR submission is submitted-visible, not verified-payable. The issue itself lacks the bounty-available label, so the visible amount is sourced only from bot comments." + }, + "markdown_upload_snapshot": { + "bold_markdown_preserved": true, + "failed_upload_recorded": true, + "failed_upload_filename": "Screenshot 2025-04-01 at 4.36.27 PM.png", + "note": "This fixture preserves the issue's markdown and failed-upload evidence so the PR has a deterministic validation target instead of a placeholder edit." + }, + "collision_snapshot": { + "checked_at": "2026-05-13T22:43:39Z", + "repo_archived": false, + "repo_visibility": "PUBLIC", + "open_pr_search_terms": ["79", "fixes #79", "issue 79", "test issue april 3 12pm"], + "same_scope_open_pr_count": 0 + }, + "expected_pr": { + "title": "test: add CodeBounty issue 79 markdown fixture", + "body_must_include": [ + "fixes #79", + "CodeBounty", + "$50", + "developer_application_required", + "bounty_label_absent" + ] + } +}