Skip to content

test(staking): add unit tests for staking panel claim button lock state - #891

Merged
Chucks1093 merged 4 commits into
accesslayerorg:devfrom
Ajibose:test/staking-panel-claim-button-state
Sep 5, 2026
Merged

test(staking): add unit tests for staking panel claim button lock state#891
Chucks1093 merged 4 commits into
accesslayerorg:devfrom
Ajibose:test/staking-panel-claim-button-state

Conversation

@Ajibose

@Ajibose Ajibose commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Closes #815

Summary

The staking panel had no Claim button gated on the stake's lock expiry, so the unit tests requested in #815 had nothing to exercise. This PR adds a production StakingPanel component (Claim button + live lock-expiry countdown) alongside its contract-call hook, and the unit tests that assert the button's state across the lock lifecycle using fake timers.

New files

  • src/components/common/StakingPanel.tsx — staking panel with a live lock-expiry countdown and a Claim button gated on unlockLedger.
  • src/utils/stakingClaim.utils.ts — pure helper computeRemainingClaimSeconds(unlockLedger, nowMs) computing seconds remaining until unlock; reuses the existing formatCountdownTime from lockupCountdown.utils.ts for HH:MM:SS formatting.
  • src/components/common/__tests__/StakingPanel.test.tsx — component tests (below).
  • src/utils/__tests__/stakingClaim.utils.test.ts — pure-function tests for computeRemainingClaimSeconds.

Modified files

  • src/hooks/useWallet.ts — added useClaimStakeMutation, a holder-facing mutation that submits the claim_stake contract call with the holder's key_id, following the existing useReinvestDividendMutation / useCreatorContractActions simulated-contract-call pattern (toast on success/error, invalidates queryKeys.wallet.holdings). No existing exports were changed.

Implementation details

  • StakingPanel takes keyId, unlockLedger (unix seconds), an onClaim(keyId) callback, and an optional isClaiming flag — mirroring the decoupled prop pattern already used by LaunchPenaltyPanel (parent wires the actual mutation via onClaim, e.g. useClaimStakeMutation), which keeps the component presentational and easy to unit test without a QueryClientProvider.
  • A setInterval ticks every second (cleared on unmount / prop change), recomputing computeRemainingClaimSeconds(unlockLedger) and re-rendering the countdown — the button's disabled state is derived directly from remainingSeconds > 0, so it flips to enabled the instant the countdown reaches zero, no reload needed.
  • data-testids: staking-panel, staking-lock-countdown, staking-claim-button.

Tests added

src/components/common/__tests__/StakingPanel.test.tsx (describe('StakingPanel (#815)'), using vi.useFakeTimers() / vi.setSystemTime()):

  1. Claim button is disabled while unlockLedger is in the future.
  2. Claim button is enabled once unlockLedger has passed.
  3. Countdown renders the correct HH:MM:SS value (e.g. 01:01:01 for 3661s remaining).
  4. Countdown ticks down via vi.advanceTimersByTime and reaches 00:00:00, with the Claim button enabling automatically — no reload/re-render trigger from the test.
  5. Clicking Claim calls onClaim with the correct key_id (covers both string and numeric ids).
  6. Claim button stays disabled and shows "Claiming…" while isClaiming is true (in-flight guard).

src/utils/__tests__/stakingClaim.utils.test.ts:

  • Future unlockLedger returns the correct remaining-seconds count.
  • Past unlockLedger returns 0.
  • Exact-expiry boundary returns 0.

How to test

pnpm install
pnpm test -- src/components/common/__tests__/StakingPanel.test.tsx src/utils/__tests__/stakingClaim.utils.test.ts
pnpm lint
pnpm build

All 9 new tests pass, pnpm lint is clean, and pnpm exec tsc -b succeeds. The full pnpm test suite was also run; it has 43 pre-existing failing files unrelated to this change (a WagmiProvider wallet-connector test setup issue), none of which touch StakingPanel, stakingClaim.utils, or useWallet.ts.

Add the staking panel's Claim button, gated on unlock_ledger, plus the
claim_stake contract hook, and unit tests using fake timers asserting
button state across the lock lifecycle (disabled/enabled, countdown
format, auto-enable at zero, and claim invoked with the correct key_id).

Closes accesslayerorg#815
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Ajibose Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Merge commit e498adc concatenated two independent, unrelated
implementations that landed under the same file paths instead of
picking one — accesslayerorg#872 vs accesslayerorg#877 for slippageTolerance.utils.ts /
SlippageToleranceSelector.tsx, and accesslayerorg#875 vs accesslayerorg#887 for
KeySimulationTool.tsx. The result had duplicate/interleaved
declarations and broken syntax, failing `tsc` outright.

Restores each file to the version that's actually wired into the app
(TradeDialog's value/onChange selector API and CreatorDetailPage's
currentSupply/protocolFeeBps/creatorFeeBps props) and matches the
surviving test files; the orphaned, never-integrated duplicate
implementations are dropped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K2iSG6NcphR3o7H3FLGLYf
Merges dev (via fix/dev-broken-merge-slippage-keysim, which also
repairs the pre-existing corruption in slippageTolerance.utils.ts /
SlippageToleranceSelector.tsx / KeySimulationTool.tsx) into this
branch. Resolves the resulting useWallet.ts conflict by keeping both
useClaimStakeMutation (this branch, accesslayerorg#815) and
useRedeemDeprecatedKeyMutation (dev, accesslayerorg#871) as separate exports.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K2iSG6NcphR3o7H3FLGLYf
@Chucks1093

Copy link
Copy Markdown
Member

Fix Merge conflict

@Chucks1093

Copy link
Copy Markdown
Member

CI is green but this PR has a merge conflict with dev and cannot be auto-merged. Pull the latest dev into your branch with git fetch origin && git checkout your-branch && git merge origin/dev, resolve any conflicts, then run npm run build and npm run lint to confirm everything is clean before pushing.

Resolves conflicts in slippageTolerance.utils.ts and its test file
(accesslayerorg#872 vs accesslayerorg#877 additions landed adjacent to each other) — both sides
are purely additive, so both blocks are kept.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCiPXzfWN9jdJAfNQQ6nbW
@Chucks1093
Chucks1093 merged commit df29135 into accesslayerorg:dev Sep 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add unit tests for the staking panel asserting the claim button state based on the lock expiry

2 participants