forked from heavy-duty/ceremony
test(forge): cover the open-pull REST gather at main() granularity
@codex-reviewer-andresmgsl's draft-stage finding: the closed/merged half of
the term-3 replacement had an executable-path case, the open half did not.
The 27 closes_references cases test the parser, not the
`.body | @base64` -> base64 -d -> closes_references wiring around it.
Both directions in one sweep so neither assertion passes vacuously: #50 is
closed by an open PR and keeps its claim, #51 is closed by nothing and is
reclaimed. `Closes #50` sits on the third line of the body, so the newline
protection is non-vacuous — an @tsv-shaped regression that keeps only the
first line reclaims #50 and reds the case.
Verified by mutation: replacing the decode with `base64 -d | head -1` fails
exactly "a claim closed by an open PR survives the base64 round trip" and
nothing else; reverting restores 148/148.
The clock is injected. INOW is a fixed 2033 epoch, so without ISSUEFLOW_NOW
the subprocess reads its own wall clock, dates both claims in the future and
keeps them on a negative age — green, and proving nothing. Caught while
writing this case.
Also renames the sibling assertion that still said "through GraphQL"; that
gather has been REST since 5797b41.
Refs #188
This commit is contained in:
parent
5797b418b9
commit
3885437f02
1 changed files with 53 additions and 1 deletions
|
|
@ -653,12 +653,64 @@ subprocess_out="$(
|
|||
subprocess_rc=$?
|
||||
check "executable sweep transitions merged Refs work" 0 "" \
|
||||
test "$subprocess_rc" -eq 0
|
||||
check "...reaches the transition through GraphQL and the issue loop" 0 "" \
|
||||
check "...reaches the transition through the REST gather and the issue loop" 0 "" \
|
||||
grep -qF '#40: merged Refs PR -> post-merge; claim released' <<<"$subprocess_out"
|
||||
check "...and performs the release edit from the executable path" 0 "" \
|
||||
grep -qF -- 'issue edit 40 -R owner/repo --remove-assignee builder --remove-label claimed --add-label post-merge' \
|
||||
"$ARRIVAL/fixtures/edits"
|
||||
|
||||
# -- the OPEN-pull gather, at main() granularity ----------------------------
|
||||
# The closed/merged half above proves one REST path; this proves the other,
|
||||
# which is a DIFFERENT pipeline: `.body | @base64` -> base64 -d ->
|
||||
# closes_references -> OPEN_PR_ISSUES. The 27 parser cases in
|
||||
# test/closes_references.test.sh cannot reach it — they test the parser, not
|
||||
# the encoding and wiring around it (#188).
|
||||
#
|
||||
# Both directions in ONE sweep, so neither assertion can pass vacuously:
|
||||
# #50 IS closed by an open PR -> the claim is KEPT, no reclaim edit
|
||||
# #51 is closed by nothing -> the claim is RECLAIMED
|
||||
# A break anywhere in the pipeline reclaims #50 too, and the first check
|
||||
# fails. A break that reclaims nothing fails the second.
|
||||
#
|
||||
# `Closes #50` sits on the THIRD line of the body on purpose. jq's @tsv
|
||||
# escapes a newline to a literal backslash-n, so a line-oriented parser
|
||||
# reading an @tsv-encoded body sees one line and drops everything after the
|
||||
# first — with the declaration on line 3, that defect reclaims #50 and this
|
||||
# case goes red. On line 1 it would pass either way, which is the definition
|
||||
# of a vacuous test.
|
||||
printf '%s\n' \
|
||||
'[{"number":500,"body":"## Summary\nSome prose about the work.\nCloses #50\n","merged_at":null}]' \
|
||||
>"$ARRIVAL/fixtures/repos_owner_repo_pulls_state_open_per_page_100.json"
|
||||
printf '[]\n' >"$ARRIVAL/fixtures/repos_owner_repo_pulls_state_closed_per_page_100.json"
|
||||
printf '[{"number":50},{"number":51}]\n' \
|
||||
>"$ARRIVAL/fixtures/repos_owner_repo_issues_state_open_per_page_100.json"
|
||||
# Both claims are two hours quiet against a ONE-hour stale bound, so the
|
||||
# reclaim clock has genuinely expired for whichever of them no open PR
|
||||
# rescues. The clock is injected rather than real: INOW is a fixed epoch in
|
||||
# 2033, so without ISSUEFLOW_NOW the subprocess reads its own wall clock,
|
||||
# dates these claims in the future, and both survive on a negative age —
|
||||
# which is a green test proving nothing.
|
||||
for n in 50 51; do
|
||||
jq -n --arg at "$(iso_at $((INOW - 7200)))" --argjson n "$n" \
|
||||
'{number:$n,user:{login:"triage-one"},created_at:$at,body:"- [x] built",labels:[{name:"claimed"}],assignees:[{login:"builder"}]}' \
|
||||
>"$ARRIVAL/fixtures/repos_owner_repo_issues_$n.json"
|
||||
printf '[]\n' >"$ARRIVAL/fixtures/repos_owner_repo_issues_${n}_comments.json"
|
||||
done
|
||||
: >"$ARRIVAL/fixtures/edits"
|
||||
open_pr_out="$(
|
||||
env PATH="$ARRIVAL/stub:$PATH" GH_FIXTURES="$ARRIVAL/fixtures" \
|
||||
CEREMONY_FORGE=github ISSUEFLOW_NOW="$INOW" ISSUEFLOW_STALE_HOURS=1 \
|
||||
REPO=owner/repo LABELS_CONF="$ARRIVAL/labels.conf" \
|
||||
bash "$ROOT/actions/issueflow-reconcile/issueflow-reconcile.sh" 2>&1
|
||||
)"
|
||||
check "the open-pull gather completes" 0 "" \
|
||||
grep -qF 'issueflow: reconciled.' <<<"$open_pr_out"
|
||||
check "a claim closed by an open PR survives the base64 round trip" 1 "" \
|
||||
grep -qE 'issue edit 50 .*--remove-label claimed' "$ARRIVAL/fixtures/edits"
|
||||
check "...while the claim no open PR closes is reclaimed in the same sweep" 0 "" \
|
||||
grep -qE 'issue edit 51 .*--remove-label claimed --add-label ready' \
|
||||
"$ARRIVAL/fixtures/edits"
|
||||
|
||||
# D2 preserved: only the deliberate stand-downs changed; a genuine failure on
|
||||
# the arrival path still kills the run loudly.
|
||||
: >"$ARRIVAL/fixtures/repos_owner_repo_issues_91.json.error"
|
||||
|
|
|
|||
Loading…
Reference in a new issue