Repository navigation
test(ui): cover a period-end cancellation whose final invoice is paid - #7320
Conversation
|
Claude finished @otavio's task in 4m 9s —— View job Code Review CompleteReviewed 2 files. 1 inline issue posted. Standards: 0 violations, 0 judgement calls. Spec: 0. Correctness: 1. StandardsNo violations. Correctness
I also checked these against the sibling
SpecThe Spec axis did not run. The PR closes no issue in this repo, and the issue it cites (shellhub-io/team#260) is in a repo this run cannot read. To request another review round, comment |
af7d62e to
a6cac77
Compare
|
/review |
|
Claude finished @otavio's task in 6m 11s —— View job Code Review CompleteReviewed 2 files on two axes: Standards (repo rules, language conventions, tests, code smells) and Correctness (security and runtime defects). No new issues found. The code looks good as-is. The Spec axis did not run. The PR closes no issue in this repo, and the issue it cites (shellhub-io/team#260) is in a repo this run cannot read. |
a6cac77 to
f749de3
Compare
A namespace canceled at the end of its period was subscribed again when Stripe charged the final invoice of that period (shellhub-io/team#260). The test runs the real period end on a Stripe test clock and fails without the cloud fix that abandons that invoice.paid. A test clock can only be attached when a customer is created, and the console creates customers without one, so the test creates the customer on the clock and writes its ID into the namespace's billing through psql. The console then skips creating its own. Deleting the clock deletes its customer, so teardown does that and skips deleteStripeCustomer. Advancing the clock past the period end ends the subscription and drafts its final invoice, but Stripe does not finalize that draft during the advance: in CI the clock read ready two hours past the period end with the invoice still a draft and no invoice.paid sent. The test finalizes it with the CLI, as the issue's manual reproduction does, and a $0 invoice is paid on finalization, which sends invoice.paid. Advancing a month takes Stripe tens of seconds or more, hence the long timeouts. The state the test checks (canceled, the free device limit, no active subscription) already holds before invoice.paid arrives, so asserting it alone would pass while the webhook is still in flight. The test first waits for the server's log line that abandons the event, which never appears on the old code. Usage reports use real time, not the clock's, so Stripe may reject one after the advance; the server logs the error and the assertions do not depend on it. When a billing test fails, its fixture attaches the events stripe-cli forwarded, with the status the server answered, and the server's lines for the webhook route or the test's tenant. The webhook route logs only errors, so without them a failed run cannot tell a missing event from one handled on another path. Only the event lines of the stripe-cli log go in: it prints the webhook signing secret when it starts, and the report is a public artifact.
f749de3 to
51d0785
Compare
Summary
Adds a cloud-edition Playwright test for shellhub-io/team#260: an owner who cancels at the end of the period must stay canceled after Stripe charges the final invoice. The fix is shellhub-io/cloud#2616, on the same branch name, so this PR's cloud e2e leg builds it.
The log poll gives the test a positive signal that
invoice.paidwas handled. Without it, the final assertions would already hold before the webhook arrives.Evidence
invoice.paidre-subscribes the namespace first, the status assertion fails).After: the cloud e2e leg of this PR's
ui-e2erun.Merge Danger
Door: two-way
Blast Radius: cloud e2e leg
Test-only. The test adds about a minute to the cloud leg, most of it waiting for Stripe to advance the clock by a month. A slow advance shows up as a timeout on the clock poll.
Merge shellhub-io/cloud#2616 first. Once this is on master, the cloud leg fails against a cloud master that lacks the fix.