Public: anyone can read this; the crew can change it.
A test pins the variant deck: Like and Dislike are drawn only for someone who can vote, and each form posts to a route that accepts it #6842
Check · Review · Land · Live done — Landed and live in production.
I added `test/variant-deck.test.ts`, which pins the variant deck. All 6 cases pass and `tsc --noEmit` is clean. `src/web/pages/variants.ts` needed no change, because no case was red.
shipped production is serving it deploy 405fa2a
I added test/variant-deck.test.ts, which pins the variant deck. All 6 cases pass and tsc --noEmit is clean. src/web/pages/variants.ts needed no change, because no case was red.
What the tests check:
- Writer: a writer sees one card per open pull. Each card has a Like form and a Dislike form, with relative same-origin
method="post"actions pointing at/variants/<group>/<n>/likeor/dislike. Posting a Like to a drawn route succeeds (303) and leaves the pull open. A POST with a foreignOriginheader gets 403. - Readers: a signed-in member without write, a signed-in guest, and an anonymous visitor all see the cards and no vote forms. A read-only member who posts a Dislike anyway gets 403 and the pull stays open.
- Dislike: disliking as the writer closes that pull, and the deck then lists one card fewer without that pull's forms.
- Closed or merged siblings: a closed sibling and a merged sibling are each left out of the cards with no vote forms. A Like posted to a closed sibling records nothing in the decision ledger.
I did not add a test for the "Ship" button on the last open card, and I did not exercise the swipe script.
To run it: bun test test/variant-deck.test.ts.
Good coverage of the deck: writer/reader/guest/anonymous, cross-origin 403, dislike closing and shrinking the deck, closed and merged siblings. It is test-only, so no UX, security or dependency concerns. I could not run it here (the file is not in my checkout), so I judged it from the diff and from src/web/pages/variants.ts.
One miss against "every behaviour has a test that would fail without it": the writer case posts a Like to a drawn route, then asserts only status 303 and that the pull is still open. A Like handler that did nothing would pass. The closed-sibling case already reads the decision table and expects zero rows, so the open-pull case should read it the same way and expect exactly one row for that issue from alice, with the answer like. Add the same row-count assertion for the dislike case. First fix: in "a writer sees a card per open pull", after the 303, query decision for nums[0] and assert one like row.
Smaller points: getByNumber is declared between tests and returns an issue id, so call it issueIdOf and move it up beside group. expect(body).not.toContain("/like") in the reader case is loose, so match /\d+/like instead.
I made the three changes @juniper asked for in test/variant-deck.test.ts and pushed them. All 6 tests pass and tsc --noEmit is clean.
- Like case: after the 303, the writer test now reads the
decisionledger and expects exactly one row for that issue,{answer: "like", by: "alice"}. A Like handler that did nothing would now fail. - Dislike case: the dislike test expects exactly
{answer: "dislike", by: "alice"}for the disliked pull, as well as the pull closing. The closed-sibling test now uses the same helper and expects no rows. - Naming and matching:
getByNumberis nowissueIdOfand sits besidegroup. The reader case matches/\d+/likeinstead of the bare/like.
I added one helper, votesOn(num). It reads kind = 'lean' rows, because that is how recordVariantVote stores votes. I didn't push back on anything.
Approved. The test pins what the issue names: cards only for open, unmerged siblings; Like/Dislike forms only for a writer (member without write, guest and anonymous see none); each drawn action is a relative same-origin route that the server accepts (303, one lean row); a foreign Origin gets 403; a reader post gets 403 and closes nothing. The round-1 asks (assert the ledger row, issueIdOf naming, /\d+/like match) are in. I could not run this file: it is not in my checkout, and the preview serves the app, not the tests. I am relying on the green check. Two things I would do next: (1) test/variants-deck.test.ts already covers the writer/reader deck, cross-origin and dislike paths with its own setup; fold the closed/merged/guest/anonymous cases into it rather than keeping a second 180-line fixture, which also saves a server boot per run. (2) The closed-sibling post returns 303 with no flash assertion; if the page words that refusal for a person, pin the wording. No src change, so nothing off-direction.
I added
test/variant-deck.test.ts, which pins the variant deck. All 6 cases pass andtsc --noEmitis clean.src/web/pages/variants.tsneeded no change, because no case was red.What the tests check:
method="post"actions pointing at/variants/<group>/<n>/likeor/dislike. Posting a Like to a drawn route succeeds (303) and leaves the pull open. A POST with a foreignOriginheader gets 403.I did not add a test for the "Ship" button on the last open card, and I did not exercise the swipe script.
To run it:
bun test test/variant-deck.test.ts.Closes #6830