Skip to content

Comments

add unit tests on feat/PRO-3638/sell-feature-pulse#394

Merged
RanaBug merged 1 commit intostagingfrom
feat/PRO-3638/sell-feature-pulse
Sep 11, 2025
Merged

add unit tests on feat/PRO-3638/sell-feature-pulse#394
RanaBug merged 1 commit intostagingfrom
feat/PRO-3638/sell-feature-pulse

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Sep 10, 2025

Description

  • Unit tests for feat/PRO-3638/sell-feature-pulse

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • Refactor

    • Added invisible test attributes to key views and controls (Home, Buy, Sell, Search) and minor structural wrappers to improve UI testability without changing behavior.
  • Tests

    • Expanded automated coverage for app navigation, Home, Buy/Sell flows (including preview and buttons), Search and portfolio lists, and core hooks. Scenarios include rendering, interactions, edge cases, loading/error states, and calculations to enhance reliability.
  • Note

    • No user-facing changes.

@RanaBug RanaBug requested a review from IAmKio September 10, 2025 15:05
@RanaBug RanaBug self-assigned this Sep 10, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds data-testid attributes and minor wrapper divs to HomeScreen, Buy, Sell, and Search for testability. Introduces comprehensive unit/integration tests across App, Buy, Sell, Search components and several hooks (useChainSelect, useRelaySdk, useRelaySell). No public API or logic changes; functional behavior remains unchanged.

Changes

Cohort / File(s) Summary
UI instrumentation (test IDs/wrappers)
src/apps/pulse/components/App/HomeScreen.tsx, src/apps/pulse/components/Search/Search.tsx, src/apps/pulse/components/Buy/Buy.tsx, src/apps/pulse/components/Sell/Sell.tsx
Added data-testid attributes; Buy/Sell root fragments replaced with div wrappers carrying test IDs; no logic changes.
App-level tests
src/apps/pulse/components/App/tests/AppWrapper.test.tsx, src/apps/pulse/components/App/tests/HomeScreen.test.tsx
New test suites covering AppWrapper routing/query handling and HomeScreen UI, toggles, and interactions; extensive mocks and snapshot tests.
Buy feature tests
src/apps/pulse/components/Buy/tests/Buy.test.tsx, src/apps/pulse/components/Buy/tests/BuyButton.test.tsx, src/apps/pulse/components/Buy/tests/PreviewBuy.test.tsx
Added comprehensive tests for Buy flow, button states, preview calculations/interactions, debounced behaviors, module install paths, and edge cases.
Sell feature tests
src/apps/pulse/components/Sell/tests/Sell.test.tsx, src/apps/pulse/components/Sell/tests/SellButton.test.tsx, src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx
New tests for Sell UI, percentage controls, offers, button enablement, preview and execution flows, error handling, and copy-to-clipboard.
Search feature tests
src/apps/pulse/components/Search/tests/PortfolioTokenList.test.tsx, src/apps/pulse/components/Search/tests/Search.test.tsx
Added tests for Search UI, filters, input handling, portfolio rendering/sorting/filtering, and resilience to loading/error states.
Hooks tests
src/apps/pulse/hooks/tests/useChainSelect.test.tsx, src/apps/pulse/hooks/tests/useRelaySdk.test.tsx, src/apps/pulse/hooks/tests/useRelaySell.test.tsx
Introduces unit tests validating initialization, state transitions, configuration, and API behaviors for chain selection and relay SDK/sell hook.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • IAmKio
  • vignesha22

Pre-merge checks (1 passed, 2 warnings)

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description uses the required headings and indicates that unit tests were added, but it lacks any details under “How Has This Been Tested?” and does not provide context on the testing environment or steps taken to verify the test suite. Additionally, while the Types of changes section is filled, the Screenshots section remains empty without clarification whether none are applicable, leaving the template only partially completed. Please provide detailed information in the “How Has This Been Tested?” section, describing your testing environment and the specific commands or test runs performed, and confirm in “Screenshots” that no visual changes apply or remove the section if none are needed.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title indicates that unit tests are being added, which reflects the main change of this pull request as it introduces numerous test suites across the codebase. While it includes the branch name “feat/PRO-3638/sell-feature-pulse,” the core action—adding unit tests—is accurately described.

Poem

In burrows of code I twitch my nose,
New test IDs where the UI grows.
Buy or Sell, I hop and see,
Search fields bloom for QA’s glee.
Hooks all snug, assertions tight—
Thump! The suite now passes night.
(\/)\n> ( ••)\n> /︻🍃 QA delight

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PRO-3638/sell-feature-pulse

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8f64079
Status: ✅  Deploy successful!
Preview URL: https://ec378753.x-e62.pages.dev
Branch Preview URL: https://feat-pro-3638-sell-feature-p.x-e62.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/apps/pulse/components/Sell/Sell.tsx (1)

93-107: Make balance lookup robust across APIs (evm:/eip155:) and by address-first.

Current lookup may miss balances if symbol collides or chainId prefix differs. Prefer matching the contract address and support both prefixes.

Apply:

-  // Find the asset in the portfolio
-  const assetData = walletPortfolioData.result.data.assets.find(
-    (asset) => asset.asset.symbol === token.symbol
-  );
+  // Find the asset by matching contract address (most precise), tolerate evm:/eip155: prefixes
+  const assetData = walletPortfolioData.result.data.assets.find((asset) =>
+    asset.contracts_balances?.some(
+      (contract) =>
+        contract.address?.toLowerCase() === token.address.toLowerCase() &&
+        (contract.chainId === `evm:${token.chainId}` ||
+          contract.chainId === `eip155:${token.chainId}`)
+    )
+  );
@@
-  const contractBalance = assetData.contracts_balances.find(
-    (contract) =>
-      contract.address.toLowerCase() === token.address.toLowerCase() &&
-      contract.chainId === `evm:${token.chainId}`
-  );
+  const contractBalance = assetData.contracts_balances.find(
+    (contract) =>
+      contract.address?.toLowerCase() === token.address.toLowerCase() &&
+      (contract.chainId === `evm:${token.chainId}` ||
+        contract.chainId === `eip155:${token.chainId}`)
+  );
src/apps/pulse/components/Search/Search.tsx (1)

286-333: Active filter highlight is wrong for “Top Gainers” and “My Holdings”.

item.includes(searchType) won’t match “Top Gainers” or “My Holdings” (spaces/emojis). Compare against the enum instead and expose stable testids/aria-pressed.

-        <div className="flex gap-1.5" data-testid="pulse-search-filter-buttons">
+        <div className="flex gap-1.5" data-testid="pulse-search-filter-buttons">
           {(isBuy
             ? ['🔥 Trending', '🌱 Fresh', '🚀 Top Gainers', '💰My Holdings']
             : ['My Holdings']
           ).map((item, index) => {
             // For sell screen, always map to MyHoldings index (3)
             const actualIndex = isBuy ? index : 3;
+            const typeOrder = [
+              SearchType.Trending,
+              SearchType.Fresh,
+              SearchType.TopGainers,
+              SearchType.MyHoldings,
+            ];
+            const currentType = typeOrder[actualIndex];
+            const isActive = searchType === currentType;
 
             if (!isBuy) {
               return (
                 <div key={item} className="flex items-center">
                   <p className="text-[13px] font-normal text-white tracking-[-0.26px] px-3">
                     {item}
                   </p>
                 </div>
               );
             }
 
             return (
               <div
                 key={item}
                 className="flex bg-black w-[100px] h-10 rounded-[10px]"
               >
                 <button
-                  className={`flex-1 items-center justify-center rounded-[6px] m-0.5 mb-1 ${ 
-                    searchType && item.includes(searchType)
-                      ? 'bg-[#2E2A4A]'
-                      : 'bg-[#1E1D24]'
-                  }`}
+                  className={`flex-1 items-center justify-center rounded-[6px] m-0.5 mb-1 ${
+                    isActive ? 'bg-[#2E2A4A]' : 'bg-[#1E1D24]'
+                  }`}
+                  data-testid={`pulse-search-filter-${currentType}`}
+                  aria-pressed={isActive}
                   type="button"
                   onClick={() => {
                     handleSearchTypeChange(actualIndex);
                   }}
                 >
                   <p
-                    className={`text-xs font-normal text-center ${ 
-                      searchType && item.includes(searchType)
-                        ? 'text-white'
-                        : 'text-white opacity-50'
-                    }`}
+                    className={`text-xs font-normal text-center ${
+                      isActive ? 'text-white' : 'text-white opacity-50'
+                    }`}
                   >
                     {item}
                   </p>
                 </button>
               </div>
             );
           })}
         </div>
🧹 Nitpick comments (18)
src/apps/pulse/components/Sell/Sell.tsx (2)

142-155: Reset amount on token change to avoid stale state (aligns with product behavior).

Per your past decision, switching tokens should clear the input and related state to prevent stale liquidity/quotes.

Apply:

 useEffect(() => {
   if (tokenAmount && tokenAmount.trim() !== '') {
     const inputAmount = parseFloat(tokenAmount);
     if (!Number.isNaN(inputAmount)) {
       setNotEnoughLiquidity(inputAmount > tokenBalance);
     } else {
       setNotEnoughLiquidity(false);
     }
   } else {
     setNotEnoughLiquidity(false);
   }
 }, [token, tokenBalance, tokenAmount]);
+
+// Clear input and derived state when token changes
+useEffect(() => {
+  setTokenAmount('');
+  setParentTokenAmount('');
+  setDebouncedTokenAmount('');
+  setNotEnoughLiquidity(false);
+  setLocalSellOffer(null);
+}, [token?.address]);

1-1: Drop lodash parseInt to reduce bundle and avoid shadowing globals.

Use the built-in with radix; remove lodash import.

Apply:

-import { parseInt } from 'lodash';
@@
-          const percentage = isMax ? 100 : parseInt(item);
+          const percentage = isMax ? 100 : Number.parseInt(item, 10);

Also applies to: 311-311

src/apps/pulse/components/Search/tests/PortfolioTokenList.test.tsx (4)

164-169: Avoid brittle currency text assertions.

Hardcoding '$1.5', '$2', '$4' breaks with formatting tweaks. Prefer regex or container-scoped assertions.

Example:

-expect(screen.getAllByText('$1.5')).toHaveLength(2);
+expect(screen.getAllByText(/^\$1(\.50)?$/)).toHaveLength(2);

236-241: Selector relies on Tailwind classes (brittle).

Querying by a compound class string is fragile. Expose a test id (e.g., data-testid="avatar-fallback") in the component and assert via that.


300-346: Test name vs. data mismatch: “null price” uses 0.

If you intend to cover null/undefined price, mock that explicitly and assert the fallback formatting. Otherwise rename the test for clarity.


215-221: Ordering test should target token rows, not all buttons.

getAllByRole('button') may capture unrelated buttons. Scope to the list container or add role/test-id to token rows.

src/apps/pulse/components/Sell/tests/SellButton.test.tsx (1)

136-142: Style assertions are fragile.

Checking exact inline colors can yield false negatives on design tweaks. Consider asserting disabled/enabled and text instead.

Also applies to: 154-160, 157-159

src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (1)

168-180: Copy feedback assertion could be more explicit.

Querying for any svg is loose. If feasible, render a data-testid on the checkmark in the component and assert by that id.

src/apps/pulse/components/Buy/tests/BuyButton.test.tsx (1)

232-265: Minor: prefer userEvent for interactions.

userEvent better approximates real user input vs. fireEvent (typing/click delays). Optional for now.

src/apps/pulse/components/Buy/tests/PreviewBuy.test.tsx (1)

186-211: Stabilize async “failure” path assertion.

Use waitForElementToBeRemoved (or waitFor not.toBeInTheDocument) for the spinner removal; current check may race.

Apply:

-import { fireEvent, render, screen, waitFor } from '@testing-library/react';
+import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
@@
-// Should not show tracker on error
-expect(
-  screen.queryByText('Waiting for signature...')
-).not.toBeInTheDocument();
+await waitForElementToBeRemoved(() =>
+  screen.queryByText('Waiting for signature...')
+);
src/apps/pulse/components/App/tests/HomeScreen.test.tsx (1)

64-77: Mock shape mismatch: use assets not tokens.

The queried data structure elsewhere uses result.data.assets; the mock sets tokens. Align to reduce surprises.

Apply:

-          data: {
-            tokens: [],
-            total_wallet_balance: 0,
-          },
+          data: {
+            assets: [],
+            total_wallet_balance: 0,
+          },
src/apps/pulse/components/Buy/tests/Buy.test.tsx (1)

205-221: Prefer userEvent for typing/clicks (optional).

Improves realism of input handling and caret behavior.

src/apps/pulse/components/Search/tests/Search.test.tsx (2)

1-2: Consider addressing these ESLint disables.

The broad ESLint disables (jsx-props-no-spreading and no-explicit-any) suggest potential code quality issues that could be addressed instead of suppressed.

-/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable @typescript-eslint/no-explicit-any */

For the jsx-props-no-spreading, consider explicitly destructuring props where needed. For no-explicit-any, consider using proper typing for the mocked functions.


173-185: Filter button interaction test could be more comprehensive.

The test clicks the trending button but only verifies that the button still exists, not that the actual filter state changed or that the component behaves correctly.

  it('handles filter button clicks in buy mode', () => {
+    const mockSetSearchText = vi.fn();
+    (useTokenSearch.useTokenSearch as any).mockReturnValue({
+      ...mockUseTokenSearch,
+      setSearchText: mockSetSearchText,
+    });
+
    render(
      <MemoryRouter>
        <Search {...defaultProps} isBuy />
      </MemoryRouter>
    );

    const trendingButton = screen.getByText('🔥 Trending');
    fireEvent.click(trendingButton);

-    // Should trigger search type change
-    expect(screen.getByText('🔥 Trending')).toBeInTheDocument();
+    // Verify that clicking filter button clears search text
+    expect(mockSetSearchText).toHaveBeenCalledWith('');
+    
+    // Verify the button remains visible after click
+    expect(screen.getByText('🔥 Trending')).toBeInTheDocument();
  });
src/apps/pulse/components/Search/Search.tsx (2)

228-235: Modal needs a11y roles; also verify the new full-screen black backdrop doesn’t regress UX.

Add role/aria to the dialog and confirm the bg-black/min-h-screen wrapper doesn’t unexpectedly darken pages.

-    <div
-      className="flex items-center justify-center min-h-screen bg-black"
+    <div
+      className="flex items-center justify-center min-h-screen bg-black"
       data-testid="pulse-search-view"
     >
-      <div
+      <div
         className="flex flex-col w-full max-w-[446px] max-h-[500px] overflow-y-auto bg-[#1E1D24] p-3 border border-white/[0.05] rounded-2xl shadow-[0px_2px_15px_0px_rgba(18,17,22,0.5)]"
+        role="dialog"
+        aria-modal="true"
+        aria-label="Token search"
         data-testid="pulse-search-modal"
       >

If the backdrop is only for tests, consider dropping bg-black to avoid visual change:

-    className="flex items-center justify-center min-h-screen bg-black"
+    className="flex items-center justify-center min-h-screen"

241-247: Minor a11y/testability: label the input and hint the input type.

Add aria-label and search-friendly attributes; tests continue to use data-testid.

-            <input
+            <input
               ref={inputRef}
               type="text"
               className="flex-1 w-fit ml-4 font-normal text-xs text-gray-500"
               value={searchText}
               data-testid="pulse-search-input"
+              aria-label="Search tokens"
+              inputMode="search"
+              autoComplete="off"
src/apps/pulse/hooks/tests/useChainSelect.test.tsx (1)

1-2: Drop unnecessary ESLint disables.

No JSX spreading or any usage of any here.

-/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable @typescript-eslint/no-explicit-any */
src/apps/pulse/hooks/tests/useRelaySdk.test.tsx (1)

1-2: Remove unused ESLint disables.

They aren’t needed in this test file.

-/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable @typescript-eslint/no-explicit-any */
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f0cf97 and 8f64079.

⛔ Files ignored due to path filters (10)
  • src/apps/pulse/components/App/tests/__snapshots__/AppWrapper.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/App/tests/__snapshots__/HomeScreen.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Buy/tests/__snapshots__/Buy.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Buy/tests/__snapshots__/BuyButton.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Buy/tests/__snapshots__/PreviewBuy.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Search/tests/__snapshots__/PortfolioTokenList.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Search/tests/__snapshots__/Search.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Sell/tests/__snapshots__/PreviewSell.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Sell/tests/__snapshots__/Sell.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Sell/tests/__snapshots__/SellButton.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (17)
  • src/apps/pulse/components/App/HomeScreen.tsx (3 hunks)
  • src/apps/pulse/components/App/tests/AppWrapper.test.tsx (1 hunks)
  • src/apps/pulse/components/App/tests/HomeScreen.test.tsx (1 hunks)
  • src/apps/pulse/components/Buy/Buy.tsx (2 hunks)
  • src/apps/pulse/components/Buy/tests/Buy.test.tsx (1 hunks)
  • src/apps/pulse/components/Buy/tests/BuyButton.test.tsx (1 hunks)
  • src/apps/pulse/components/Buy/tests/PreviewBuy.test.tsx (1 hunks)
  • src/apps/pulse/components/Search/Search.tsx (3 hunks)
  • src/apps/pulse/components/Search/tests/PortfolioTokenList.test.tsx (1 hunks)
  • src/apps/pulse/components/Search/tests/Search.test.tsx (1 hunks)
  • src/apps/pulse/components/Sell/Sell.tsx (7 hunks)
  • src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (1 hunks)
  • src/apps/pulse/components/Sell/tests/Sell.test.tsx (1 hunks)
  • src/apps/pulse/components/Sell/tests/SellButton.test.tsx (1 hunks)
  • src/apps/pulse/hooks/tests/useChainSelect.test.tsx (1 hunks)
  • src/apps/pulse/hooks/tests/useRelaySdk.test.tsx (1 hunks)
  • src/apps/pulse/hooks/tests/useRelaySell.test.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-09T12:40:15.611Z
Learnt from: RanaBug
PR: pillarwallet/x#391
File: src/apps/pulse/components/Sell/Sell.tsx:113-130
Timestamp: 2025-09-09T12:40:15.611Z
Learning: In the Pulse app Sell component, when a user changes/switches tokens, the input amount automatically resets to 0, which means liquidity validation state doesn't become stale when tokens change.

Applied to files:

  • src/apps/pulse/components/Sell/Sell.tsx
🧬 Code graph analysis (13)
src/apps/pulse/hooks/tests/useChainSelect.test.tsx (1)
src/apps/pulse/hooks/useChainSelect.ts (1)
  • useChainSelect (4-11)
src/apps/pulse/components/Search/tests/Search.test.tsx (3)
src/types/api.ts (1)
  • PortfolioData (739-748)
src/apps/pulse/hooks/useTokenSearch.ts (1)
  • useTokenSearch (5-45)
src/apps/pulse/components/Search/Search.tsx (1)
  • Search (57-388)
src/apps/pulse/components/App/tests/HomeScreen.test.tsx (3)
src/apps/pulse/contexts/RefreshContext.tsx (1)
  • RefreshProvider (24-70)
src/apps/pulse/contexts/LoadingContext.tsx (1)
  • LoadingProvider (15-32)
src/apps/pulse/components/App/HomeScreen.tsx (1)
  • HomeScreen (36-266)
src/apps/pulse/components/Sell/tests/Sell.test.tsx (4)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/types/api.ts (1)
  • WalletPortfolioMobulaResponse (750-752)
src/apps/pulse/contexts/RefreshContext.tsx (2)
  • useRefresh (72-78)
  • RefreshProvider (24-70)
src/apps/pulse/contexts/LoadingContext.tsx (1)
  • LoadingProvider (15-32)
src/apps/pulse/hooks/tests/useRelaySdk.test.tsx (1)
src/apps/pulse/hooks/useRelaySdk.ts (1)
  • useRelaySdk (21-64)
src/apps/pulse/components/Sell/tests/SellButton.test.tsx (2)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/apps/pulse/hooks/useRelaySell.ts (1)
  • SellOffer (41-44)
src/apps/pulse/hooks/tests/useRelaySell.test.tsx (6)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/apps/pulse/hooks/useRelaySdk.ts (1)
  • useRelaySdk (21-64)
src/hooks/useTransactionDebugLogger.tsx (1)
  • useTransactionDebugLogger (1-15)
src/apps/pulse/contexts/LoadingContext.tsx (1)
  • useLoading (34-40)
src/apps/pulse/hooks/useRelaySell.ts (1)
  • useRelaySell (54-924)
src/apps/the-exchange/utils/wrappedTokens.ts (1)
  • getWrappedTokenAddressIfNative (33-44)
src/apps/pulse/components/Buy/tests/PreviewBuy.test.tsx (3)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/apps/pulse/hooks/useIntentSdk.ts (1)
  • useIntentSdk (9-41)
src/apps/pulse/components/Buy/PreviewBuy.tsx (1)
  • PreviewBuy (25-320)
src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (4)
src/apps/pulse/contexts/RefreshContext.tsx (1)
  • RefreshProvider (24-70)
src/apps/pulse/contexts/LoadingContext.tsx (1)
  • LoadingProvider (15-32)
src/apps/pulse/hooks/useRelaySell.ts (1)
  • useRelaySell (54-924)
src/hooks/useTransactionDebugLogger.tsx (1)
  • useTransactionDebugLogger (1-15)
src/apps/pulse/components/Buy/tests/BuyButton.test.tsx (2)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/apps/pulse/components/Buy/BuyButton.tsx (1)
  • BuyButton (57-113)
src/apps/pulse/components/App/tests/AppWrapper.test.tsx (1)
src/apps/pulse/components/App/AppWrapper.tsx (1)
  • AppWrapper (13-79)
src/apps/pulse/components/Search/tests/PortfolioTokenList.test.tsx (1)
src/types/api.ts (1)
  • PortfolioData (739-748)
src/apps/pulse/components/Buy/tests/Buy.test.tsx (7)
src/apps/pulse/types/tokens.ts (1)
  • SelectedToken (1-10)
src/types/api.ts (1)
  • WalletPortfolioMobulaResponse (750-752)
src/apps/pulse/hooks/useIntentSdk.ts (1)
  • useIntentSdk (9-41)
src/apps/pulse/hooks/useModularSdk.ts (1)
  • useModularSdk (17-129)
src/apps/pulse/contexts/RefreshContext.tsx (1)
  • RefreshProvider (24-70)
src/apps/pulse/contexts/LoadingContext.tsx (1)
  • LoadingProvider (15-32)
src/apps/pulse/components/Buy/Buy.tsx (1)
  • Buy (35-442)
🔇 Additional comments (34)
src/apps/pulse/hooks/tests/useRelaySell.test.tsx (5)

134-144: LGTM: Comprehensive environment setup

Good practice to stub environment variables and clean them up in afterEach. The VITE_SWAP_FEE_RECEIVER variable is properly managed.


146-199: LGTM: Initial state validation

The test properly verifies the hook's default state and function signatures. Comprehensive mocking setup ensures isolation.


266-312: LGTM: USDC address retrieval tests

Both positive and negative test cases are covered for USDC address resolution, ensuring proper chain support validation.


486-556: LGTM: Successful quote retrieval test

The test properly mocks the complete flow and validates the expected sell offer structure with correct calculations.


633-687: LGTM: Error state validation

The test correctly verifies error handling when the hook is not properly initialized.

src/apps/pulse/components/App/HomeScreen.tsx (3)

152-152: LGTM: Buy toggle test ID added

The test ID enables reliable testing of buy/sell toggle functionality.


174-174: LGTM: Sell toggle test ID added

Consistent with the buy toggle, this enables testing of the sell mode selection.


261-261: LGTM: Home view test ID added

The root container test ID enables tests to verify the presence of the home screen.

src/apps/pulse/components/Buy/Buy.tsx (2)

183-183: LGTM: Component wrapper with test ID

The replacement of the React Fragment with a styled div container that includes a test ID is appropriate for testing purposes. The flex flex-col classes maintain the expected layout behavior.


440-440: LGTM: Closing div for test wrapper

Properly closes the test wrapper div introduced at the beginning of the component.

src/apps/pulse/components/Sell/tests/Sell.test.tsx (7)

80-88: LGTM: Well-structured mock props

The mock props object provides comprehensive test data matching the expected component interface.


90-105: LGTM: Centralized mocking utilities

The defaultMocks helper function provides consistent mock setup across tests, improving maintainability.


107-115: LGTM: Provider wrapper utility

The renderWithProviders function ensures components are properly wrapped with required context providers for testing.


117-126: LGTM: Snapshot test for regression detection

The snapshot test provides a baseline for detecting unintended UI changes.


128-153: LGTM: Conditional rendering tests

Tests properly validate different UI states based on whether a token is selected, covering both positive and negative scenarios.


155-203: LGTM: User interaction testing

Comprehensive tests for user interactions including input changes, button clicks, and validation of component callbacks.


205-241: LGTM: State-dependent behavior tests

Tests properly validate component behavior in different states including disabled states, error conditions, and missing data scenarios.

src/apps/pulse/components/App/tests/AppWrapper.test.tsx (6)

36-65: LGTM: Comprehensive default mocking setup

The defaultMocks function provides consistent and comprehensive mock data for all required services, ensuring reliable test isolation.


84-102: LGTM: Default rendering validation

The test properly validates that the HomeScreen renders by default when no asset parameter is provided, using appropriate test IDs.


104-145: LGTM: Invalid asset parameter handling

Comprehensive tests for various invalid asset parameter scenarios (invalid address, empty, malformed) ensure robust URL parameter validation.


147-197: LGTM: Valid asset parameter routing

Tests properly validate that valid Ethereum addresses trigger the search view and that query parameters are correctly handled and prefilled.


199-239: LGTM: Service state handling

Tests cover loading and error states for the wallet portfolio service, ensuring the app handles various data fetching states appropriately.


241-266: LGTM: Wallet address change handling

The test validates that the component properly handles wallet address changes through the rerender lifecycle.

src/apps/pulse/components/Sell/Sell.tsx (1)

58-86: Effect deps: confirm getBestSellOffer stability or include in deps.

You’ve disabled exhaustive-deps; ensure getBestSellOffer is referentially stable from useRelaySell or wrap in ref to avoid stale closures.

src/apps/pulse/components/Sell/tests/SellButton.test.tsx (1)

200-214: LGTM — interaction flows and states covered.

Assertions for enabled/disabled and handler invocations look solid.

src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (1)

182-205: LGTM — exec flow and waiting state validated.

Good use of waitFor and argument verification to executeSell.

src/apps/pulse/components/Buy/tests/BuyButton.test.tsx (1)

118-128: LGTM — state matrix is well covered.

Enable/disable permutations and text variants are exercised thoroughly.

Also applies to: 130-139

src/apps/pulse/components/Buy/tests/PreviewBuy.test.tsx (1)

167-183: LGTM — shortlist flow verified end-to-end.

Good coverage of state transition to tracker.

src/apps/pulse/components/App/tests/HomeScreen.test.tsx (1)

189-207: LGTM — core interactions (search, toggles) verified.

Provider stack and callbacks are wired correctly.

src/apps/pulse/components/Search/tests/Search.test.tsx (3)

42-75: Well-structured mock data that matches the expected portfolio structure.

The mock portfolio data correctly implements the PortfolioData interface and provides realistic test data with proper asset structure, contract balances, and wallet information.


96-377: Comprehensive test coverage with good structure.

The test suite provides excellent coverage of the Search component's functionality including:

  • Rendering verification for different modes (buy/sell)
  • User interaction handling (input changes, button clicks)
  • Loading and error states
  • URL parameter handling
  • Component lifecycle behavior

The tests are well-organized and cover the key user flows effectively.


25-35: Mock react-router-dom setup provides good test isolation.

The router mocking correctly isolates the component from actual routing while providing the necessary context and URL parameters for testing the asset parameter handling functionality.

src/apps/pulse/hooks/tests/useChainSelect.test.tsx (1)

11-60: LGTM — tests cover init, updates, and setter stability.

Solid coverage for this simple state hook.

src/apps/pulse/hooks/tests/useRelaySdk.test.tsx (1)

68-117: Overall test flow looks good.

Mocks, initialization assertions, error path, and reinit checks are thorough.

@RanaBug RanaBug merged commit 9ddf921 into staging Sep 11, 2025
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 12, 2025
3 tasks
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.

2 participants