test: add unit tests for keyboard shortcut hook confirming it does not fire when focus is in a form element (#626) - #711
Closed
abimbolaalabi wants to merge 173 commits into
Conversation
- Rewrite .env.example with a one-line description for every variable and remove duplicate entries; group into required vs optional - Add an 'Environment variables' section to CONTRIBUTING.md covering required vs optional vars and where to source testnet RPC URLs
Verifies that the GitHub and Telegram community links render with the correct href values, open in a new tab, and carry the expected rel="noopener noreferrer" attribute so a future refactor cannot silently break these URLs. Closes accesslayerorg#428
…in XLM with correct decimal places
…on-test Add integration tests for MarketingPage community links
…-add-helper-for-formatting-key-price-display-in-xlm-with-correct-decimal-places feat: accesslayerorg#420 Add helper for formatting key price display in XLM with co…
- Add computePriceChange(current: bigint, previous: bigint) in src/utils/priceChange.utils.ts
- Returns { percent: number, direction: 'up' | 'down' | 'flat' }
- Returns flat when previous is zero or current equals previous
- 7 unit tests covering: price up, price down, no change, zero previous, both zero
Closes accesslayerorg#429
…rorg#444 accesslayerorg#445 - Add copy-to-clipboard button to ConnectWalletButton with 2s feedback and screen-reader announcement (accesslayerorg#442) - Add src/lib/queryKeys.ts factory-style React Query key constants with unit tests (accesslayerorg#443) - Add LandingPage.holdings.test.tsx integration tests asserting portfolio totals and per-holding values (accesslayerorg#444) - Add docs/api-layer.md documenting service conventions, error handling, and a worked end-to-end example (accesslayerorg#445)
…cesslayerorg#437 - Add ledgerToTimestamp helper for converting Stellar ledger sequence numbers to estimated timestamps - Add transaction status badge legend tooltip for user-friendly status explanations - Add creator card keyboard shortcut hint (press 'B' to quick buy) with desktop-only display - Add integration test for creator card price update on snapshot data change
…elper-tx-tooltip-keyboard-shortcut-price-test Add ledger timestamp helper, transaction status tooltip, keyboard shortcuts, and price update tests
…-address feat: add shortenAddress helper for wallet address display — Close accesslayerorg#423
Closes accesslayerorg#438 by formatting counts under 1K as plain strings and larger values with one-decimal K/M suffixes, with unit tests for each range and boundary values. Co-authored-by: Cursor <cursoragent@cursor.com>
Documents the standard pattern contributors should follow when writing new useQuery and useMutation hooks — covering the onError callback convention, when to show a toast vs inline error vs error boundary, how to distinguish 4xx client errors from 5xx server errors and network failures, and a worked example hook that handles all three cases. Closes accesslayerorg#460
…-holder-count Add formatHolderCount helper for compact holder display.
closes accesslayerorg#460 - docs: add error handling guide for React Query hooks
Closes accesslayerorg#424 Add a React error boundary scoped to creator detail pages so a render error shows a fallback UI instead of crashing the whole app to a blank screen. Follows the existing SectionErrorBoundary class pattern. - Fallback shows a short message and a "Back to creators" link (/creators) - Logs the error to console only in development (import.meta.env.DEV) - Add tests covering normal render, fallback on error, and the list link
…d layout - Add new CreatorCardSkeleton component that mirrors CreatorCard's dimensions (avatar, name + verified/change/supply/recent-activity badges, handle, bio, sparkline placeholder, 3 mini stat chips, 3 meta rows, social links, action row, helper text) so it acts as a layout-stable placeholder while the creator list is fetching. - Use the existing dark-theme .skeleton-shimmer animation and CREATOR_CARD_MEDIA_RADIUS_CLASS token so the skeleton visually matches the rest of the marketplace. - Respect prefers-reduced-motion via the shared CSS rule and a disableShimmer prop, matching CreatorSkeleton's API. - Add a CreatorCardGridSkeleton helper that defaults to count = 6 to satisfy the acceptance criterion. - Wire CreatorCardGridSkeleton into LandingPage's initial-loading branch so the marketplace shows 6 stable skeleton cards instead of the generic grid skeleton. - Cover the new component with vitest tests asserting role/aria coverage, 6-by-default grid, disableShimmer propagation, className merging, and shimmer-vs-static block toggling.
Closes accesslayerorg#426. Adds docs/adding-page-routes.md covering where routes are registered in src/App.tsx, the file naming convention for page components, the recommended pattern for auth-protected routes (with a RequireAuth wrapper example), and a four-step worked example adding a public AboutPage at /about. Adds a one-line pointer in CONTRIBUTING.md under Frontend conventions so contributors can find the guide.
…ice-change feat: add computePriceChange helper for key price percentage change
…imestamp-test test: add integration test for ledgerToTimestamp (accesslayerorg#461)
…rage-preferences feat: add generic localStorage preference helpers (accesslayerorg#458)
…-component Feat/error boundary component
…e-contributing-folder-structure docs: update CONTRIBUTING.md with folder structure and conventions
…tion/test test: add integration test for trade panel submit button disabled while transaction is in flight (accesslayerorg#622)
…onnectionLogger (accesslayerorg#599) Adds a debug-level structured log emitted the moment a wallet connection succeeds, so developers can trace wallet session activity without relying on browser extension logs. - New useWalletConnectionLogger hook watches wagmi's useAccount state and logs truncated_address (first 4 + last 4), connection_method (from the active connector), and connected_at once per connection event, deduped on the connected address so re-renders and cache updates never re-log. - Mounted once at the Web3Provider boundary so the log fires exactly once app-wide regardless of which UI (connect button, reconnect banner) initiated the connection. - Suppressed in the test environment by default, matching the cache-invalidation logging convention already used in useWallet.ts. - Full wallet address is never logged under any field name.
…ptimistic buy updates
…gination without duplicates
…eview fetch failure with creator and quantity context
…ation with result data
…og-for-trade-panel-price-preview-fetch-failure-with-creator-and-quantity-context Add structured log for trade panel price preview fetch failure
…tion-log feat(observability): log successful wallet connections via useWalletConnectionLogger (accesslayerorg#599)
…sconnect log coverage
…60-accesslayer test(wallet): cover creator 404, activity ordering, holdings total updates, and disconnect session logging
…verage - accesslayerorg#639: integration test for creator list page/scroll restoration after navigating to a profile and back. Also fixes a real bug found while writing it: visibleCount (infinite-scroll load-more progress) had no sessionStorage persistence, and two mount-time effects unconditionally reset page/visibleCount to defaults on every mount, clobbering the restored values. Both are now guarded to skip their first run. - accesslayerorg#642: end-to-end buy flow test (quantity input -> success toast -> holdings cache update), mirroring the existing sell-flow (accesslayerorg#644) pattern. Trading in this app is scoped to a single featured-creator panel with no per-card or profile-page trade UI, so the test targets the real buy surface instead of the issue's literal "profile page" wording. - accesslayerorg#643: coverage for CreatorCardSkeleton's no-layout-shift properties (pulse class on every region, no real content rendered, root sizing constraints) against its current design, which already exceeds the issue's minimal 4-region ask (it mirrors all ~10+ CreatorCard regions, per accesslayerorg#421). Redesigning down to 4 regions would regress the accesslayerorg#421 suite. - accesslayerorg#646: extends the existing holdings empty-state coverage (accesslayerorg#539) with the one assertion it didn't have: skeleton placeholders visible during loading, not just "empty state absent". closes accesslayerorg#639 closes accesslayerorg#642 closes accesslayerorg#643 closes accesslayerorg#646
…aniel/feat/623-empty-state-unit-tests feat(components): add unit tests and CTA/message support for EmptySta…
…alidation - Add integration test for creator discovery list card rendering - Add contributing guide for new pages and data fetching - Add structured logging for failed wallet transactions - Add unit tests for trade panel quantity input validation
…roll-restore-buy-flow-skeleton-empty-state-639-642-643-646 Add scroll/page restore, buy flow, skeleton, and empty-state test coverage
…ue-batch-1 feat: Add integration tests, contributing guide, transaction logs, and quantity validation
…e-integration-629 test: add creator profile page integration test
…yerorg#677) Adds the supporting infrastructure for a paginated wallet activity feed and the integration test that verifies it loads older trades as the user scrolls. * src/services/walletActivity.service.ts (NEW): exposes fetchWalletActivityPage so React Query useInfiniteQuery can fetch per-page activity for a wallet address; cacheManager-backed. * src/hooks/useWallet.ts (MODIFIED): useWalletActivity now uses useInfiniteQuery with initialPageParam=1 and getNextPageParam wired to lastPage.nextPage. Query key (queryKeys.wallet.activity(address)) is unchanged so the existing queryKeyIntegration.test.tsx continues to pass. * src/components/common/WalletActivityFeed.tsx (NEW): aggregates useInfiniteQuery pages, deduplicates trades by id, renders existing TransactionHistory with the accumulated list, and drives a sentinel via useInfiniteScroll to trigger fetchNextPage when the bottom of the feed scrolls into view. * src/components/common/__tests__/WalletActivityFeed.infiniteScroll. integration.test.tsx (NEW): four integration tests covering acceptance criteria - page 1 visible on initial load, scroll triggers next page fetch, page 2 appended below page 1, no duplicate trades when pages overlap.
Implements accesslayerorg#686. Two of the four assigned issues describe components that do not exist in this repository — see the note below and the PR body. The nav bar's CTA was a bare "Connect Wallet" link that stayed there whether or not a wallet was connected, so there was no persistent indication of which account or which network was active. WalletStatusChip replaces it: - Truncated address via the existing shortenAddress, which already formats first-4/last-4 exactly as the issue specifies. - Network badge, green for mainnet and yellow for testnet. - Dropdown with the full address, copy, and disconnect. - The same Connect link rendered from inside the component when no wallet is connected, so the nav slot is never empty and Header does not need to branch. The chip reads useAccount and useChainId directly rather than taking props. Passing the address down would leave it stale until whatever owns that prop happened to re-render; reading wagmi state means a network switch in the extension updates the badge immediately, which is one of the acceptance criteria. describeNetwork is a separate module so the classification is testable without rendering. Anything that is not Ethereum mainnet is treated as a testnet, and an unrecognised chain gets its own "unsupported" state rather than being shown as a testnet — labelling a chain the app cannot talk to as "testnet" implies the app works there. That default also means a chain added to supportedChains later shows yellow until someone deliberately promotes it, instead of silently rendering a green "you are on mainnet". Copy keeps the menu open so the copied-state tick is visible, and reverts after 2s so the confirmation is unambiguous rather than permanent. Verified: tsc -b --noEmit clean, 7 tests passing. Not implemented — the underlying features are absent: - accesslayerorg#687 asks for an optimistic update in a useFollowCreator mutation. There is no follow feature anywhere in src: no hook, no service call, no isFollowing state, no button. - accesslayerorg#689 asks for tests of a transaction history filter with a type dropdown, date range and Reset. TransactionHistory.tsx renders a list from props and has no filter controls at all. Both need the feature built first, which is a different change from the one they describe.
…ptimistic-skeletons-tests feat(nav): wallet status chip with address and network badge
… sell validation tests, trade-shortcut unmount test Fixes four Stellar Wave issues in one batch: accesslayerorg#684 test: bonding curve price preview component - computeBuyCost() (bonding curve total-cost-for-N-keys math) already had full unit test coverage as a pure function, but was never actually wired into any React component -- TradeDialog's buy side only ever showed a flat per-unit price, not a quantity-aware total. Added a new, small, standalone BuyPriceEstimate component that uses computeBuyCost to render the real total XLM cost for the entered quantity, with a debounced "Calculating price..." loading state and no buy button at quantity 0. New BuyPriceEstimate.test.tsx covers quantity 1/0/100, price updates on quantity change, the loading state, and asserts computeBuyCost is called with the correct (currentSupply, quantity, params) arguments (mocked via vi.spyOn on the module namespace). - Scoping note: this does not modify the existing, heavily-tested TradeDialog/LandingPage buy flow (~30 existing test files depend on its current behavior) -- wiring BuyPriceEstimate into that live flow is a reasonable follow-up once it can be done with test coverage run to confirm nothing regresses. accesslayerorg#685 feat: infinite scroll for the creator key marketplace - The marketplace listing (LandingPage) already had an "infinite scroll" mode, but it was client-side only: courseService.getCourses() fetches every creator up front and the "infinite scroll" just reveals more of the already-fully-loaded array -- it doesn't reduce initial page weight at all, which is exactly the problem the issue describes. - Added courseService.getCoursesPage(page, params): a real cursor(page- number)-paginated fetch reading has_more/hasMore from the response (falling back to "page was full" when the backend doesn't send it). - Added useInfiniteCreatorMarketplace(): wraps getCoursesPage in @tanstack/react-query's useInfiniteQuery (initialPageParam/ getNextPageParam), de-duplicating creators across pages by id. - Added CreatorMarketplaceInfiniteList: wires the existing useInfiniteScroll (IntersectionObserver) hook's sentinel to fetchNextPage, shows the existing CreatorGridSkeleton while the first page and subsequent pages load, and stops rendering the sentinel once hasMore is false. - New tests for both the hook (first-page-only fetch, next-page fetch + de-dup, stops at hasMore: false, params passed through) and the component (initial skeleton, rendering, next-page skeleton, sentinel wiring, disabling the observer while a fetch is in flight). - Scoping note: same as accesslayerorg#684 -- built and tested as a new, standalone unit rather than swapping LandingPage's existing pagination live, to avoid risking its ~30 existing test files without being able to run them. accesslayerorg#657 test: sell quantity exceeds-holding validation - TradeDialog's validationError logic already correctly rejects a sell quantity greater than availableHoldings, and already has a distinct "Amount must be greater than zero" message for quantity 0 -- this was a pure test-writing task. New TradeDialog.sellQuantityValidation.test.tsx covers: exceeds-holding error shown/cleared, distinct zero-quantity error, quantity equal to holding accepted, quantity 1 accepted, and the confirm button disabled while the error is present. accesslayerorg#654 test: T trade-shortcut listener cleanup on unmount - The keydown effect that opens the trade dialog on "T" (LandingPage -- its own comment already calls this "the creator profile page") already correctly returns a cleanup function removing the listener. New LandingPage.tradeShortcutUnmount.integration.test.tsx confirms the full cycle end-to-end: T opens the dialog while mounted, unmounting (in place of a stand-in "creator discovery list" page) makes T inert with no console errors, and remounting makes T work again. No install/build/test run was performed for this PR (current task scope). Every new hook/component was written against this repo's real, existing conventions (useInfiniteScroll, CreatorGridSkeleton, the useInfiniteQuery/ QueryClientProvider test pattern from tradeCacheInvalidation.test.ts, the TradeDialog.clamp.integration.test.tsx render helper, and the LandingPage mock block from LandingPage.keyboard.test.tsx) to minimize the risk of something not compiling/working as written. Closes accesslayerorg#684 Closes accesslayerorg#685 Closes accesslayerorg#657 Closes accesslayerorg#654
…ave-batch-684-685-657-654 feat(marketplace),test: bonding curve price preview, infinite scroll, sell validation tests, trade-shortcut unmount test
…ponent-unit-tests-628 feat: add toast component unit tests
…llet-activity-infinite-scroll feat(wallet): add infinite-scroll activity feed + integration test (accesslayerorg#677)
…t fire when focus is in a form element (accesslayerorg#626)
✅ Deploy Preview for accesslayer ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @abimbolaalabi, thanks for your contribution! This PR is targeting Please close this PR and reopen it with Closing this PR automatically. See you in |
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.
Overview
This PR adds unit tests for the \T\ keyboard shortcut hook in \LandingPage, confirming the handler correctly fires when focus is on the document body and is suppressed when focus is on form elements (\input, \ extarea, \select).
Related Issue
Closes #626
Changes
Keyboard Shortcut Tests
Verification Results
\
pnpm vitest run src/pages/tests/LandingPage.tradeShortcut.test.tsx
✅ 4/4 passed
\\