Recover from referral invite send failures - #132
Conversation
Greptile SummaryThis PR fixes a UX bug where the "Send Invites" button could get stuck in a "Sending..." state after a failed network request or a non-JSON error response from
Confidence Score: 4/5Safe to merge — the change is narrow and well-tested, fixing a real user-facing stuck-button issue. The production fix in page.tsx is correct: try/catch/finally guarantees setSending resets on every path, and the .catch(() => null) guard cleanly handles non-JSON bodies without masking the HTTP error. The one thing holding the score slightly below a clean pass is in the test file — cleanup() from @testing-library/react is never explicitly called in afterEach (only vi.unstubAllGlobals), so test isolation depends entirely on the auto-cleanup behaviour that @testing-library/react wires up via the global afterEach. If the project's vitest config sets globals: false, auto-cleanup would not fire and DOM state from one test would leak into the next, potentially causing false passes. src/app/dashboard/referrals/page.invites.test.tsx — verify that @testing-library/react auto-cleanup is active in this project's vitest configuration. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[sendInvites called] --> B[setSending=true, clear error/success]
B --> C{emailList empty?}
C -- Yes --> D[setError + setSending=false + early return]
C -- No --> E[try: POST /api/referrals]
E --> F[parse JSON, fallback to null on failure]
F --> G{res.ok?}
G -- No --> H[setError with fallback message]
G -- Yes --> I[setSuccess + clear emails + reload referrals]
E -- throws --> J[catch: setError network fallback]
H --> K[finally: setSending=false]
I --> K
J --> K
Reviews (1): Last reviewed commit: "Recover from referral invite send failur..." | Re-trigger Greptile |
| afterEach(() => { | ||
| vi.unstubAllGlobals(); | ||
| }); | ||
|
|
||
| it("recovers from invite network errors", async () => { |
There was a problem hiding this comment.
Missing explicit cleanup between tests
afterEach only calls vi.unstubAllGlobals() — it never calls cleanup() from @testing-library/react. Auto-cleanup relies on @testing-library/react detecting a globally-available afterEach, which only happens when vitest's globals: true option is set. If the project runs vitest with globals disabled, the rendered <ReferralsPage /> from the first test remains mounted in the JSDOM document when the second test runs, and screen queries in the second test will see both instances, which could produce false positives. Adding import { cleanup } from "@testing-library/react" and cleanup() inside afterEach makes the teardown explicit and independent of the globals configuration.
Summary
try/catch/finallyso the form recovers from failed requestsPOST /api/referralsFixes #131
Validation
pnpm test:run src/app/dashboard/referrals/page.invites.test.tsxpnpm type-checkpnpm exec eslint src/app/dashboard/referrals/page.tsx src/app/dashboard/referrals/page.invites.test.tsxgit diff --checkBounty / payment
Submitted for the active uGig affiliate-program testing task. SOL receive address:
27sdMYXofqoM9qR13bZhccRNYeEgYn5EoHXTSJn4QWKP.Payment fallback: PayPal cultofrozen@gmail.com