Fix failing CI: lint, tests, accidentally-deleted types, audit finding - #347
Merged
chonilius merged 7 commits intoSep 7, 2026
Merged
Conversation
- CallbackClient.test.tsx / DashboardShell.test.tsx / Navbar.test.tsx: replace require()-based jest mock overrides and `any` casts with proper ES imports typed against jest.Mock, and fix a leftover `usePathname.mockReturnValue` call that should have been `mockedUsePathname.mockReturnValue`. - WalletContext.tsx: replace the setState(prev => ...) functional-updater read of previous state inside the logout-clearing effect (flagged by react-hooks/set-state-in-effect) with a ref kept current after every render, preserving the original behavior without peeking at previous state from inside an effect.
- Tabs.test.tsx: query by role "tab", not "button" — Tabs.tsx renders <button role="tab">, and the explicit ARIA role overrides the implicit button role. - BountyCard.test.tsx: expect "5 days left", matching formatDaysUntil's actual pluralized output, not the "5d left" abbreviation the test incorrectly expected. - WalletContext.test.tsx: add the missing getActiveFreighterAddress and checkNetworkMismatch mocks to the @/lib/wallet mock — any test path reaching the mount-hydration effect was throwing "is not a function" without them.
AuthContext.refresh() never called setLoading(false) in its 401/403 error branch, so the UI stayed stuck showing "loading" indefinitely once a session became invalid — the only way out was a full reload.
Commit 1717eee ("feat: add smart polling with claim-race detection for bounty status") replaced the entire src/types/index.ts with a single `export * from './bounty'` line as an apparent unrelated side effect, deleting UserRole, Difficulty, TeamSplit, Milestone, ReputationProfile, MaintenancePool, and AuthUser. tsc/next build (but not Jest, which doesn't type-check) have been failing on the missing imports ever since across src/lib/adapters.ts, src/lib/api.ts, src/lib/mock-data.ts, and src/context/AuthContext.tsx. - Add src/types/shared.ts with the 7 recovered types (content restored verbatim from the pre-1717eee index.ts via git history). - Re-export it from the src/types barrel alongside the existing ./bounty export. - Tighten Bounty.difficulty from a bare `string` to the restored Difficulty union, and Bounty.teamSplits to use the restored TeamSplit interface instead of an inline duplicate — both had quietly widened in the same commit, and every real usage (DifficultyBadge, etc.) was already written against the narrower types. - Fix the resulting real type mismatch in useBountyStatus.ts: fetchBounty can resolve with `data: undefined` (no fallback bounty, live fetch failed), which the hook's useSmartPolling<> generic didn't allow for.
Both components were written against a status vocabulary
('in-progress', 'completed', 'cancelled') that has never matched the
actual BountyStatus union (open/funded/claimed/in_review/merged/paid/
refunded/expired) used everywhere else (BountyCard, StatusBadge). This
only surfaced once the type restoration made tsc check these files at
all — status/style lookups keyed by the wrong strings, and dead
`status === 'completed'` comparisons that could never be true.
- BountyStatus.tsx: rebuild statusColors/statusLabels against the real
union, and drop the "Updated: ..." line, which read a bounty.updatedAt
field that doesn't exist anywhere in the Bounty type.
- ClaimButton.tsx: drop the unreachable `status === 'completed'` checks;
'claimed' already covers "already claimed" for this union.
npm audit --audit-level=high (run in CI) was failing on GHSA-c83g-rgw3-j3cx / GHSA-73wf-gq98-2v4g in browserslist <=4.28.6. Resolved via npm audit fix (transitive bump only, no direct dependency changes).
|
@gideononiru is attempting to deploy a commit to the chonilius' projects Team on Vercel. A member of the Team first needs to authorize it. |
CI's own PR run failed at "npm test" — Jest couldn't load jest.config.ts: "'ts-node' is required for the TypeScript configuration files... Cannot find package 'ts-node'". jest-config tries a native require/import of the .ts config first and only falls back to ts-node (or esbuild-register) if that fails; it never showed up locally because this sandbox's Node version natively strips TypeScript syntax well enough for the native path to succeed, silently masking the gap. CI's pinned Node 24 does not, and falls through to the ts-node path, which was never added as a dependency. Verified with a from-scratch `rm -rf node_modules && npm ci` plus the full lint/test/verify:env/build/ verify:headers/audit pipeline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CI on
mainhas been red across the board (lint, tests,verify:env/build type-checking, andnpm audit). This PR walks every stage of.github/workflows/ci.yml'sbuild-and-lintjob in order and fixes everything found at each stage.require()-based jest mock overrides andanycasts replaced with proper ES imports typed againstjest.Mock(CallbackClient.test.tsx,DashboardShell.test.tsx,Navbar.test.tsx, including a leftoverusePathname.mockReturnValuethat should have readmockedUsePathname), and thereact-hooks/set-state-in-effectviolation inWalletContext.tsxfixed via a ref kept current every render instead of peeking at previous state from inside an effect.Tabs.test.tsxquerying the wrong ARIA role,BountyCard.test.tsxexpecting an abbreviated deadline string the component never produces), one was an incomplete mock (WalletContext.test.tsxmissinggetActiveFreighterAddress/checkNetworkMismatchon@/lib/wallet), and one was a real bug:AuthContext.refresh()never clearedloadingon a 401/403, leaving the UI stuck showing "loading" forever after a session became invalid.1717eeeaccidentally replaced the entiresrc/types/index.tswith a single re-export line as a side effect of an unrelated feature commit, deletingUserRole,Difficulty,TeamSplit,Milestone,ReputationProfile,MaintenancePool, andAuthUser. This doesn't fail Jest (no type-checking there) but failstsc/next build/npm run verify:envacrossadapters.ts,api.ts,mock-data.ts, andAuthContext.tsx. Restored the 7 types verbatim (recovered viagit show 1717eee^:src/types/index.ts) into a newsrc/types/shared.ts, re-exported from the barrel, and tightenedBounty.difficulty/teamSplitsto use the restoredDifficulty/TeamSplittypes instead of the widenedstring/inline shapes they'd quietly regressed to — every real consumer (DifficultyBadge, etc.) was already written against the narrower types. Also fixed the resultinguseBountyStatus.tstype mismatch (fetchBountycan resolve withdata: undefined).tscactually checkBountyStatus.tsx/ClaimButton.tsx, both turned out to be written against a status vocabulary ('in-progress','completed','cancelled') that has never matched the realBountyStatusunion. Fixed both to use the real union, and dropped abounty.updatedAtreference — that field doesn't exist anywhere inBounty.npm audit --audit-level=highwas failing on a high-severitybrowserslistadvisory; resolved vianpm audit fix(transitive bump only).Verified locally end-to-end after each stage: lint clean (0 errors, 2 pre-existing unrelated warnings), 291/291 Jest tests passing across 21 suites,
verify:envall 5 scenarios pass,next buildsucceeds,verify:headerspasses,npm audit --audit-level=highclean.Test plan
npm run lint— 0 errorsNEXT_PUBLIC_STELLAR_NETWORK=TESTNET npx jest— 291/291 passingNEXT_PUBLIC_STELLAR_NETWORK=TESTNET npm run verify:env— all scenarios passNEXT_PUBLIC_STELLAR_NETWORK=TESTNET npm run build— succeedsNEXT_PUBLIC_STELLAR_NETWORK=TESTNET npm run verify:headers— passesnpm audit --audit-level=high— 0 vulnerabilities