useBountyStatus.test.tsx tests a hook that no longer exists: it mocks fetchBounty, asserts data with enabled:false, and leaks the module-level poller registry between cases
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 57/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- react, typescript
Research direction
Start with src/hooks/useBountyStatus.test.tsx, then read src/hooks/useBountyStatus.ts and src/hooks/bountyPoller.ts to align tests with the hook’s subscription registry. Run npx jest src/hooks/useBountyStatus.test.tsx to confirm the failures; done means the suite isolates registry state and covers the stated subscription, polling, refetch, and failed-fetch behavior. The issue also raises whether to remove or reconnect useSmartPolling, which adds scope.
Written by the indexing model from the issue text.
Description
Location
src/hooks/useBountyStatus.test.tsx (whole file), against the current src/hooks/useBountyStatus.ts and src/hooks/bountyPoller.ts.
Problem
The suite was written for the pre-#631 hook, which ran its own useSmartPolling loop over an injected fetchBounty. Its own header still says so: "Covers the hook wrapping useSmartPolling". The hook is now a thin useSyncExternalStore over the module-level registry in bountyPoller.ts. The tests were never updated, and several of them cannot pass against the current implementation:
-
enabled: falsecases assert fetched data. Cases 1 and 2 render withenabled: false. In the current hook that makes the subscribe function a no-op (useBountyStatus.ts:42), sosubscribeBountyis never called, no entry is created, andgetBountySnapshotreturns{ bounty: null, source: null, loading: false, error: null }. The assertionsexpect(result.current.bounty).toEqual(mockBounty)andexpect(result.current.source).toBe("live")are asserting state that the code has no way to produce. -
Case 3 asserts a callback the hook never invokes.
onStatusChangeis destructured and then never referenced anywhere inuseBountyStatus.ts(filed separately), soexpect(onStatusChange).toHaveBeenCalledWith("open")can only time out. -
Cross-test state leakage.
registryinbountyPoller.tsis module-level and is never reset.beforeEach(() => jest.clearAllMocks())clears thefetchBountymock but not the registry, so an entry created by one case — along with itsbounty, itssourceand, if the terminal-status branch did not fire, its livesetInterval— survives into the next. Cases therefore pass or fail depending on declaration order, and the real intervals keep firing across the file. -
The mock is now at the wrong seam.
jest.mock("@/lib/api", () => ({ fetchBounty: jest.fn() }))replaces the module the registry calls, not anything the hook calls. That is why the suite looks like it is exercising fetch behaviour while actually exercising nothing: the hook under test makes no API call of its own, and the mock also strips every other export of@/lib/api, so any future import from that module inside the hook silently becomesundefined.
Relatedly, useSmartPolling is now dead code: the only references to it anywhere under src/ outside its own file are its own test (src/hooks/useSmartPolling.test.tsx) and a comment in useClaimRace.ts. Nothing renders it. The open report #568 ("useSmartPolling stops polling after the first re-render because useBountyStatus passes inline fetchFn/compareFn/onDataChange") describes a call site that no longer exists, so that issue is unverifiable as written and should be re-scoped or closed.
Why it matters
This is worse than having no tests, which is the state #620 was filed about. The file's presence is what makes useBountyStatus look covered, so the genuine defects now living in bountyPoller.ts (a stopped poller that never restarts, a failed fetch blanking the bounty, refetch being a no-op) sit behind a green-looking test file that exercises none of them. And because the suite cannot pass as written, CI is either red on this file or the file is being skipped — both of which hide the same thing.
Reproduction
npx jest src/hooks/useBountyStatus.test.tsx — cases 1, 2 and 3 fail for the reasons above (1 and 2 on the bounty/source assertion, 3 on the waitFor timeout).
Suggested fix
Rewrite the suite against the seam the hook actually has:
- Export a
__resetBountyPollerRegistry()(test-only) frombountyPoller.ts, or clear the map viajest.resetModules()inbeforeEach, so each case starts clean. - Mock
@/lib/apiwith...jest.requireActual("@/lib/api")spread in, overriding onlyfetchBounty, so the rest of the module stays intact. - Use fake timers and assert the behaviours that matter: one shared fetch loop for two subscribers on the same id; polling stops on a terminal status; polling restarts when a new subscriber arrives after the last one left;
refetch()performs a fetch while the loop is stopped; a failed fetch surfaceserrorwithout blanking a previously loadedbounty. - Drop the
enabled: falsedata assertions, and replace them with the real contract:enabled: falsemeans no subscription and no fetch.
Then decide useSmartPolling's fate: delete the hook and its test if the registry is the way forward, or re-wire it and keep its tests meaningful. Leaving it in src/hooks/ invites a contributor to adopt it and inherit the bugs reported against it.
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 94
- Avg merge
- 1h 2m
- Merged PRs (30d)
- 25
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from MergeFi/frontend
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
bug testing
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
accessibility bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
MergeFi/frontend#835 · 1 comment ·
Maintainers usually reply within 1 day
All issues in MergeFi/frontend
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
zapcooking/frontend#946 ·
Maintainers usually reply within 1 day
-
enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
WiliamRosa/cosmos-semantic-platform#40 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
liberation-data/drivine#733 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
makecindy/cindy#10062 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day