Skip to content

Remove wallet cookie migration, Update AGENTS about clean code, Improve DateAccordion accessibility#1516

Merged
prxt6529 merged 18 commits intomainfrom
merging-prs-07-10-25
Oct 7, 2025
Merged

Remove wallet cookie migration, Update AGENTS about clean code, Improve DateAccordion accessibility#1516
prxt6529 merged 18 commits intomainfrom
merging-prs-07-10-25

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Oct 7, 2025

Summary by CodeRabbit

  • New Features

    • Image component: added primary-error callback and reset behavior; header search modal now has a labeled search input.
  • Accessibility

    • Accordion toggler converted to a button with aria-expanded/aria-controls and linked content region; search input tied to an accessible label; modal input labeled.
  • Refactor

    • Unified wallet connection state model and debounced account/address syncing.
  • Documentation

    • Added SonarQube clean-code guideline.
  • Tests

    • Expanded accessibility and auth tests, consolidated mocks/imports, and added FallbackImage tests.
  • Chores

    • Removed cookie-to-localStorage migration utility.

…ve DateAccordion accessibility

Signed-off-by: prxt6529 <prxt@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 7, 2025

Warning

Rate limit exceeded

@prxt6529 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 2af0db5 and f2cdf82.

📒 Files selected for processing (1)
  • components/auth/SeizeConnectContext.tsx (22 hunks)

Walkthrough

Unified wallet state machine and address validation with debounced reconciliation; DateAccordion made accessible via a button and ARIA linkage; removed migrateCookiesToLocalStorage; added FallbackImage onPrimaryError and reset behavior; header search input labelled; tests and mocks adjusted; SonarQube note added to AGENTS.md.

Changes

Cohort / File(s) Summary of Changes
SeizeConnectContext state model refactor
components/auth/SeizeConnectContext.tsx, __tests__/components/auth/SeizeConnectContext.test.tsx
Replaced scattered wallet flags with a unified WalletState union (double-quoted status values), added address normalization/validation, debounced account reconciliation, standardized error/event contexts, and updated tests/mocks to the new surface.
Auth utils — migration removal
services/auth/auth.utils.ts, __tests__/services/auth.utils.test.ts, __tests__/components/header/share/HeaderShare.test.tsx
Removed exported migrateCookiesToLocalStorage and its test usage; reordered imports; removed references from mocks and simplified related expectations.
DateAccordion accessibility updates
components/common/DateAccordion.tsx, __tests__/components/common/DateAccordion.test.tsx
Replaced outer wrapper with a button toggler using useId; added aria-expanded and aria-controls linking to content id; moved content id to animated div; tests updated to assert ARIA attributes and linkage.
FallbackImage props & behavior
components/common/FallbackImage.tsx, __tests__/components/common/FallbackImage.test.tsx
Added readonly qualifiers, new onPrimaryError prop, reset internal state when primarySrc changes; call onPrimaryError on first failure and call onError if fallback also fails; tests validate fallback behavior and logging.
Header search & modal accessibility / markup
components/header/header-search/HeaderSearchModal.tsx, __tests__/components/header/HeaderSearchModal.test.tsx
Added a labelled search input (id/label pairing), adjusted markup and imports for accessibility; tests query the textbox by accessible name and stabilize mocked item component.
Drop media component imports / minor JSX tweaks
components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
Reordered imports to use FallbackImage, image-scaling and fullscreen hooks/utilities; small JSX/attribute reformatting; no public API changes.
Test import / mock consolidations
__tests__/components/auth/SeizeConnectContext.test.tsx, __tests__/components/header/share/HeaderShare.test.tsx
Consolidated and reordered imports, removed redundant re-imports, and updated mock setups to reflect removed migration util and new public API shapes.
Docs
AGENTS.md
Added "Adhere to clean code standards as measured by SonarQube." to Coding Conventions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as SeizeConnectProvider
  participant AppKit as AppKit Hooks
  participant Wallet as Wallet Provider
  participant Validator as Address Validator
  participant Logger as Event Logger

  rect rgb(245,248,255)
  note over UI: Initialization & reconciliation
  UI->>AppKit: read account/status
  AppKit-->>UI: account, status
  UI->>UI: set walletState = "initializing"
  end

  User->>UI: Connect wallet
  UI->>Wallet: request connection
  Wallet-->>UI: address (raw)
  UI->>Validator: validate / checksum (getAddress/isAddress)
  alt valid
    Validator-->>UI: normalized address
    UI->>Logger: log "wallet_initialization" success
    UI->>UI: walletState = "connected"
  else invalid
    Validator-->>UI: errorContext
    UI->>Logger: log "wallet_initialization" error
    UI->>UI: walletState = "error"
  end

  AppKit-->>UI: account/status change
  UI->>UI: debounced reconcile -> update walletState

  User->>UI: Disconnect
  UI->>Wallet: disconnect
  UI->>Logger: log "seizeDisconnect"
  UI->>UI: walletState = "disconnected"
Loading
sequenceDiagram
  autonumber
  actor User
  participant Accordion as DateAccordion
  participant DOM as DOM/ARIA

  User->>Accordion: Click toggle button
  Accordion->>DOM: set aria-expanded true/false
  Accordion->>DOM: set aria-controls -> contentId
  DOM-->>User: animated region with id=contentId shown/hidden
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Full NFT Picker UI #1498 — large feature PR touching NFT picker components, hooks, and react-query keys that may overlap on imports or utilities used here.
  • Memes Loading optimizations #1497 — PR changing image-loading/rendering behavior; likely related to the new FallbackImage and image component changes.

Suggested reviewers

  • ragnep
  • simo6529
  • GelatoGenesis

Poem

Hop-hop, I nudge the state in tune,
Buttons sing ARIA under the moon,
Cookies hopped off — no crumbs remain,
Addresses checked, connections regain.
Tests clap paws — another green lane! 🐰✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly reflects the three primary changes in the pull request—removing wallet cookie migration, updating the AGENTS coding conventions, and improving DateAccordion accessibility—so it accurately summarizes the main scope of the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 0

Caution

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

⚠️ Outside diff range comments (2)
services/auth/auth.utils.ts (1)

18-21: Ensure cookie removal always succeeds by fixing attributes

Explicitly set path so remove matches set. Without consistent path, WALLET_AUTH_COOKIE may not be deleted across routes.

Apply this diff:

 const COOKIE_OPTIONS = {
   secure: true,
   sameSite: "strict" as const,
+  path: "/",
 };
components/auth/SeizeConnectContext.tsx (1)

1-625: Remove inline code comments in TS/TSX files

The code contains numerous inline comments; project guidelines specify no comments in TypeScript/TSX. Move explanations to docs or keep minimal JSDoc in .md.

As per coding guidelines

🧹 Nitpick comments (7)
services/auth/auth.utils.ts (2)

40-49: Guard against already‑expired JWTs before setting cookie

If exp <= now, you’ll set an immediately expired cookie. Prefer skipping set and clearing auth or short‑circuiting.

Example:

   const expiresInSeconds = jwtExpiration - now;
   const expiresInDays = expiresInSeconds / 86400;

+  if (expiresInSeconds <= 0) {
+    // Token expired; ensure no stale cookie remains.
+    Cookies.remove(WALLET_AUTH_COOKIE, COOKIE_OPTIONS);
+    return;
+  }

9-13: Remove legacy cookie constants and TODO

Migration is done; these are unused. Drop the TODO and constants to avoid confusion.

-// TODO: remove these cookies once migration is complete
-const WALLET_ADDRESS_COOKIE = "wallet-address";
-const WALLET_REFRESH_TOKEN_COOKIE = "wallet-refresh-token";
-const WALLET_ROLE_COOKIE = "wallet-role";
components/common/DateAccordion.tsx (1)

31-36: Strengthen accordion a11y: add region + labelled‑by

Current pattern links button→content via aria-controls. Also label the content region via aria-labelledby for assistive tech.

-      <button
+      <button
         type="button"
         onClick={onToggle}
         aria-expanded={isExpanded}
-        aria-controls={contentId}
+        aria-controls={contentId}
+        id={`${contentId}-button`}
         className="tw-w-full ...
       >
...
-        {isExpanded && (
-          <motion.div
+        {isExpanded && (
+          <motion.div
             initial={{ height: 0, opacity: 0 }}
             animate={{ height: "auto", opacity: 1 }}
             exit={{ height: 0, opacity: 0 }}
             transition={{ duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] }}
-            id={contentId}>
+            id={contentId}
+            role="region"
+            aria-labelledby={`${contentId}-button`}>
             {children}
           </motion.div>
         )}

Also applies to: 64-71

components/auth/SeizeConnectContext.tsx (4)

31-60: Avoid duplicating error classes; import from a single module

WalletConnectionError/WalletDisconnectionError are defined here but also live in src/errors/wallet.ts. Centralize to prevent instanceof/type divergence.


361-361: Use cross‑platform timer type

NodeJS.Timeout can mismatch in browser TS configs. Prefer ReturnType.

-  const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);
+  const debounceTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

519-523: Use centralized logger instead of console.error

For consistency and sanitization, replace console.error with logError.

-              console.error(
-                "Failed to reopen wallet connection after logout:",
-                openError
-              );
+              logError("seizeDisconnectAndLogout_reconnect", createWalletError(WalletConnectionError, "reopen wallet connection after logout", openError));

342-344: Add readonly to provider props per guidelines

Aligns with project rule “Always add readonly before props”.

-export const SeizeConnectProvider: React.FC<{ children: React.ReactNode }> = ({
+export const SeizeConnectProvider: React.FC<{ readonly children: React.ReactNode }> = ({
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a91228f and cee0e70.

📒 Files selected for processing (8)
  • AGENTS.md (1 hunks)
  • __tests__/components/auth/SeizeConnectContext.test.tsx (1 hunks)
  • __tests__/components/common/DateAccordion.test.tsx (1 hunks)
  • __tests__/components/header/share/HeaderShare.test.tsx (0 hunks)
  • __tests__/services/auth.utils.test.ts (4 hunks)
  • components/auth/SeizeConnectContext.tsx (22 hunks)
  • components/common/DateAccordion.tsx (4 hunks)
  • services/auth/auth.utils.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • tests/components/header/share/HeaderShare.test.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript for implementation code

Files:

  • __tests__/services/auth.utils.test.ts
  • components/common/DateAccordion.tsx
  • __tests__/components/common/DateAccordion.test.tsx
  • __tests__/components/auth/SeizeConnectContext.test.tsx
  • components/auth/SeizeConnectContext.tsx
  • services/auth/auth.utils.ts
**/{__tests__/**/*.{ts,tsx},*.test.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/{__tests__/**/*.{ts,tsx},*.test.tsx}: Place tests in tests directories or alongside components as ComponentName.test.tsx
Mock external dependencies and APIs in tests

Files:

  • __tests__/services/auth.utils.test.ts
  • __tests__/components/common/DateAccordion.test.tsx
  • __tests__/components/auth/SeizeConnectContext.test.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/services/auth.utils.test.ts
  • __tests__/components/common/DateAccordion.test.tsx
  • __tests__/components/auth/SeizeConnectContext.test.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks

Files:

  • components/common/DateAccordion.tsx
  • __tests__/components/common/DateAccordion.test.tsx
  • __tests__/components/auth/SeizeConnectContext.test.tsx
  • components/auth/SeizeConnectContext.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/common/DateAccordion.test.tsx
  • __tests__/components/auth/SeizeConnectContext.test.tsx
🧠 Learnings (3)
📚 Learning: 2025-09-28T12:33:30.950Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:30.950Z
Learning: Applies to __tests__/components/**/*.{ts,tsx,js,jsx} : Use `testing-library/react` and `testing-library/user-event` for React component tests

Applied to files:

  • __tests__/components/auth/SeizeConnectContext.test.tsx
  • AGENTS.md
📚 Learning: 2025-09-28T12:32:36.083Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: AGENTS.md:0-0
Timestamp: 2025-09-28T12:32:36.083Z
Learning: Applies to **/*.tsx : Use React functional components with hooks

Applied to files:

  • AGENTS.md
📚 Learning: 2025-09-28T12:32:36.083Z
Learnt from: CR
PR: 6529-Collections/6529seize-frontend#0
File: AGENTS.md:0-0
Timestamp: 2025-09-28T12:32:36.083Z
Learning: Applies to **/{__tests__/**/*.{ts,tsx},*.test.tsx} : Place tests in __tests__ directories or alongside components as ComponentName.test.tsx

Applied to files:

  • AGENTS.md
🧬 Code graph analysis (3)
__tests__/services/auth.utils.test.ts (1)
helpers/safeLocalStorage.ts (1)
  • safeLocalStorage (3-11)
__tests__/components/common/DateAccordion.test.tsx (1)
components/common/DateAccordion.tsx (1)
  • DateAccordion (15-76)
components/auth/SeizeConnectContext.tsx (2)
src/errors/wallet.ts (2)
  • WalletInitializationError (16-26)
  • WalletConnectionError (1-7)
src/utils/security-logger.ts (4)
  • logSecurityEvent (96-116)
  • createValidationEventContext (197-210)
  • logError (125-178)
  • createConnectionEventContext (184-191)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
AGENTS.md (1)

54-54: Docs update LGTM

Clear, actionable addition. No further changes needed.

services/auth/auth.utils.ts (1)

118-136: Verify the JWT claim used for role

You read role from decodedJwt.id. Confirm server issues role in id; if not, switch to the correct claim (e.g., role) or make it configurable.

Would you like a targeted unit test for validateJwtRole covering match/mismatch and missing-claim cases?

__tests__/services/auth.utils.test.ts (1)

10-11: Tests aligned with new API surface

Mocks and assertions look correct; casing/normalization expectations match implementation.

Also applies to: 66-67, 86-87, 134-135

__tests__/components/auth/SeizeConnectContext.test.tsx (1)

1-11: Solid coverage for security logging and error flows

Imports/mocks reflect the new context API and migration removal. Tests exercise init, connect, accept, and logging paths thoroughly.

__tests__/components/common/DateAccordion.test.tsx (1)

16-56: Accessibility tests LGTM

Validates aria-expanded/aria-controls and region presence. Mocks keep DOM deterministic.

Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (2)
components/auth/SeizeConnectContext.tsx (2)

32-52: Consolidate error classes with the errors module.

WalletConnectionError and WalletDisconnectionError are redefined here but also exist in src/errors/wallet.ts. This duplication can lead to version skew and confusion. Consider importing the base classes from the errors module and extending them if you need the additional code property.

Apply this diff to import and extend the base classes:

+import { 
+  WalletConnectionError as BaseWalletConnectionError,
+  WalletDisconnectionError as BaseWalletDisconnectionError
+} from "@/src/errors/wallet";
+
-export class WalletConnectionError extends Error {
-  constructor(
-    message: string,
-    public readonly cause?: unknown,
-    public readonly code?: string
-  ) {
-    super(message);
-    this.name = "WalletConnectionError";
-  }
-}
+export class WalletConnectionError extends BaseWalletConnectionError {
+  constructor(
+    message: string,
+    cause?: unknown,
+    public readonly code?: string
+  ) {
+    super(message, cause);
+  }
+}

-export class WalletDisconnectionError extends Error {
-  constructor(
-    message: string,
-    public readonly cause?: unknown,
-    public readonly code?: string
-  ) {
-    super(message);
-    this.name = "WalletDisconnectionError";
-  }
-}
+export class WalletDisconnectionError extends BaseWalletDisconnectionError {
+  constructor(
+    message: string,
+    cause?: unknown,
+    public readonly code?: string
+  ) {
+    super(message, cause);
+  }
+}

544-561: Consider error handling strategy for public API.

seizeAcceptConnection throws an AuthenticationError when the address is invalid. Since this is part of the public context API, throwing could crash consuming components that don't wrap the call in try-catch. Consider either:

  1. Documenting the throwing behavior clearly in JSDoc (already present at line 93-95, but could be more explicit about the exception type), or
  2. Handling the error internally by setting an error state that consumers can check

The current implementation is acceptable if consumers are expected to handle exceptions, but ensure this is well-documented.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cee0e70 and 0110059.

📒 Files selected for processing (1)
  • components/auth/SeizeConnectContext.tsx (22 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript for implementation code

Files:

  • components/auth/SeizeConnectContext.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks

Files:

  • components/auth/SeizeConnectContext.tsx
🧬 Code graph analysis (1)
components/auth/SeizeConnectContext.tsx (2)
src/errors/wallet.ts (2)
  • WalletInitializationError (16-26)
  • WalletConnectionError (1-7)
src/utils/security-logger.ts (4)
  • logSecurityEvent (96-116)
  • createValidationEventContext (197-210)
  • logError (125-178)
  • createConnectionEventContext (184-191)
🔇 Additional comments (3)
components/auth/SeizeConnectContext.tsx (3)

259-340: LGTM: Clean state machine refactor.

The unified WalletState type eliminates multiple boolean flags and provides a clear state machine with explicit transitions. The initialization logic properly validates stored addresses and handles errors, and the transition methods provide a clean API for state updates.


363-440: LGTM: Proper debounced synchronization.

The debounced effect correctly waits for initialization, validates addresses using isAddress and normalizes them with getAddress, and only updates state when necessary. The 50ms debounce delay and comprehensive dependency array ensure proper synchronization with external wallet state changes.


576-606: LGTM: Proper memoization and API surface.

The context value is properly memoized with a comprehensive dependency array. Exposing both connectionState (string literal) and walletState (full state object) provides backward compatibility while enabling advanced consumers to access the full state machine.

Comment thread components/auth/SeizeConnectContext.tsx
Copy link
Copy Markdown

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
components/common/FallbackImage.tsx (1)

30-39: Remove inline comment.

The inline comment on line 36 violates the coding guideline "Do not include any comments in the code" for **/*.{ts,tsx} files.

As per coding guidelines
Apply this diff:

     if (!usedFallback) {
       onPrimaryError?.(e);
       setSrc(fallbackSrc);
       setUsedFallback(true);
     } else {
-      // If fallback also fails, call the external onError handler
       onError?.(e);
     }
🧹 Nitpick comments (2)
__tests__/components/header/HeaderSearchModal.test.tsx (1)

173-173: Consider using consistent query pattern.

For consistency with other tests (lines 146-148, 160), consider querying by accessible name:

-    const input = screen.getByRole("textbox");
+    const input = screen.getByRole("textbox", { name: "Search" });

This makes the test more robust and explicit about what element it's targeting.

__tests__/components/common/FallbackImage.test.tsx (1)

10-34: Consider adding test coverage for the fallback error scenario.

The test correctly verifies the primary image error handling and callback invocation. However, it would be beneficial to add a test case for when the fallback image also fails, which should trigger the onError prop according to the component implementation (line 37 in FallbackImage.tsx).

Example test case to add:

it("calls onError when both primary and fallback fail", async () => {
  const onPrimaryError = jest.fn();
  const onError = jest.fn();

  render(
    <FallbackImage
      primarySrc="primary.gif"
      fallbackSrc="fallback.gif"
      alt="fallback example"
      onPrimaryError={onPrimaryError}
      onError={onError}
    />
  );

  const image = screen.getByRole("img", { name: "fallback example" });
  
  fireEvent.error(image);
  await waitFor(() => {
    expect(image.getAttribute("src")).toBe("fallback.gif");
  });
  
  fireEvent.error(image);
  
  expect(onPrimaryError).toHaveBeenCalledTimes(1);
  expect(onError).toHaveBeenCalledTimes(1);
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0110059 and 8ef0826.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • __tests__/components/common/FallbackImage.test.tsx (1 hunks)
  • __tests__/components/header/HeaderSearchModal.test.tsx (4 hunks)
  • components/common/FallbackImage.tsx (3 hunks)
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (10 hunks)
  • components/header/header-search/HeaderSearchModal.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript for implementation code

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • components/common/FallbackImage.tsx
  • __tests__/components/header/HeaderSearchModal.test.tsx
  • components/header/header-search/HeaderSearchModal.tsx
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • components/common/FallbackImage.tsx
  • __tests__/components/header/HeaderSearchModal.test.tsx
  • components/header/header-search/HeaderSearchModal.tsx
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
**/{__tests__/**/*.{ts,tsx},*.test.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/{__tests__/**/*.{ts,tsx},*.test.tsx}: Place tests in tests directories or alongside components as ComponentName.test.tsx
Mock external dependencies and APIs in tests

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/header/HeaderSearchModal.test.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/header/HeaderSearchModal.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/header/HeaderSearchModal.test.tsx
🧬 Code graph analysis (1)
__tests__/components/common/FallbackImage.test.tsx (1)
components/common/FallbackImage.tsx (1)
  • FallbackImage (13-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
__tests__/components/header/HeaderSearchModal.test.tsx (2)

52-58: LGTM! Mock component improvements.

The addition of displayName to the mock component and using a named constant improves debuggability and aligns with React best practices.


143-150: LGTM! Accessibility verification added.

This test properly validates the accessible label association introduced in the component, ensuring the search input is accessible to assistive technologies.

components/header/header-search/HeaderSearchModal.tsx (1)

340-344: LGTM! Accessibility improvements properly implemented.

The label-input association using htmlFor and id correctly implements accessibility best practices. The tw-sr-only class ensures the label is available to screen readers while maintaining the visual design with the placeholder.

components/common/FallbackImage.tsx (1)

13-52: LGTM! The error handling logic is well-structured.

The implementation correctly:

  • Calls onPrimaryError on the first failure before falling back
  • Calls onError only when the fallback also fails
  • Resets state when primarySrc changes for retry scenarios
  • Uses forwardRef properly for imperative access
components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (2)

163-221: Excellent accessibility improvements!

The addition of aria-label attributes to buttons (lines 163, 175, 184, 197, 206) and aria-hidden="true" to decorative SVG elements (line 213) significantly improves the accessibility of the modal controls. These changes ensure screen reader users can understand the purpose of each button.


3-19: LGTM! Import reorganization is clean.

The reorganization of imports improves code readability by grouping related imports together. The new imports (FallbackImage, fullScreenSupported, getScaledImageUri, ImageScale, useCapacitor, useInView) are appropriately placed and support the enhanced functionality.

Comment thread components/common/FallbackImage.tsx Outdated
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (2)
__tests__/components/common/FallbackImage.test.tsx (2)

36-61: Test logic is correct.

The test properly verifies that onPrimaryError is called on the first failure and onError is called when the fallback also fails.


Consider using jest-dom matchers here as well.

For consistency with the suggested refactor in the first test, you can use toHaveAttribute instead of getAttribute().toBe().

Apply this diff:

-      expect(image.getAttribute("src")).toBe("fallback.gif");
+      expect(image).toHaveAttribute("src", "fallback.gif");

Based on learnings.


5-62: Consider adding tests for the reset behavior and happy path.

The implementation includes a useEffect that resets state when primarySrc changes, and there's a happy path scenario when images load successfully. Adding test cases for these would improve coverage:

  1. Test primarySrc change reset: Verify that when primarySrc changes after a fallback, the component resets to try the new primary image.
  2. Test successful image load: Verify that when the primary image loads successfully, no callbacks are invoked and the image remains on the primary source.

Example test for reset behavior:

it("resets to primary source when primarySrc changes after fallback", async () => {
  const { rerender } = render(
    <FallbackImage
      primarySrc="primary.gif"
      fallbackSrc="fallback.gif"
      alt="fallback example"
    />
  );

  const image = screen.getByRole("img", { name: "fallback example" });
  
  fireEvent.error(image);
  await waitFor(() => {
    expect(image).toHaveAttribute("src", "fallback.gif");
  });

  rerender(
    <FallbackImage
      primarySrc="new-primary.gif"
      fallbackSrc="fallback.gif"
      alt="fallback example"
    />
  );

  expect(image).toHaveAttribute("src", "new-primary.gif");
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e747ae and 0a69c84.

📒 Files selected for processing (2)
  • __tests__/components/common/FallbackImage.test.tsx (1 hunks)
  • __tests__/components/header/HeaderSearchModal.test.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript for implementation code

Files:

  • __tests__/components/header/HeaderSearchModal.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks

Files:

  • __tests__/components/header/HeaderSearchModal.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
**/{__tests__/**/*.{ts,tsx},*.test.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/{__tests__/**/*.{ts,tsx},*.test.tsx}: Place tests in tests directories or alongside components as ComponentName.test.tsx
Mock external dependencies and APIs in tests

Files:

  • __tests__/components/header/HeaderSearchModal.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/components/header/HeaderSearchModal.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/header/HeaderSearchModal.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
🧬 Code graph analysis (1)
__tests__/components/common/FallbackImage.test.tsx (1)
components/common/FallbackImage.tsx (1)
  • FallbackImage (13-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
__tests__/components/header/HeaderSearchModal.test.tsx (4)

52-58: LGTM! Improved mock component with displayName.

The refactored mock now uses a named constant and sets displayName, which improves debugging and aligns with React best practices for component identification in DevTools and error messages.


143-150: LGTM! Solid accessibility test.

This test validates that the search input is properly associated with an accessible label, ensuring keyboard and screen reader users can identify the input. This aligns with WCAG accessibility guidelines and complements the labeling changes in the component.


160-160: LGTM! More specific and reliable queries.

The updated queries now explicitly target the textbox by its accessible name "Search", making the tests more specific and reducing the risk of false positives. As a bonus, these queries also validate the accessibility of the input across multiple test scenarios.

Also applies to: 173-173, 203-203


212-214: LGTM! Formatting improvement.

The multi-line formatting improves readability without changing behavior.

__tests__/components/common/FallbackImage.test.tsx (1)

1-8: LGTM! Test setup follows best practices.

The imports and cleanup setup are correct, following the coding guidelines for using @testing-library/react in component tests.

Comment thread __tests__/components/common/FallbackImage.test.tsx
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@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: 2

♻️ Duplicate comments (1)
components/auth/SeizeConnectContext.tsx (1)

161-200: Address normalization inconsistency persists (Capacitor vs standard path).

The Capacitor branch (line 169) returns a lowercased address while the standard branch (line 178) returns an EIP-55 checksummed address via getAddress(). This mismatch can lead to comparison failures when the same address is used across Capacitor and non-Capacitor contexts.

As noted in the previous review, apply this fix to unify the format:

   if (isCapacitorPlatform()) {
     if (storedAddress.startsWith("0x") && storedAddress.length === 42) {
       return {
         isValid: true,
-        normalizedAddress: storedAddress.toLowerCase(),
+        normalizedAddress: getAddress(storedAddress),
       };
     }
   }
🧹 Nitpick comments (1)
__tests__/components/common/FallbackImage.test.tsx (1)

10-34: Previous feedback addressed correctly.

The test now spies on console.error instead of console.log (line 11) and uses the idiomatic toHaveAttribute matcher (lines 24, 29), as suggested in the previous review. The test effectively validates the fallback mechanism, the single invocation of onPrimaryError, and the absence of console logging.

Optional: Consider testing primarySrc change behavior.

The component's useEffect resets state when primarySrc changes. Adding a test that renders with one primarySrc, triggers fallback, then updates primarySrc and verifies the reset would provide additional confidence in the retry mechanism.

Example test structure:

it("resets to primary when primarySrc changes after fallback", async () => {
  const { rerender } = render(
    <FallbackImage
      primarySrc="primary1.gif"
      fallbackSrc="fallback.gif"
      alt="test"
    />
  );

  const image = screen.getByRole("img", { name: "test" });
  fireEvent.error(image);
  await waitFor(() => expect(image).toHaveAttribute("src", "fallback.gif"));

  rerender(
    <FallbackImage
      primarySrc="primary2.gif"
      fallbackSrc="fallback.gif"
      alt="test"
    />
  );

  expect(image).toHaveAttribute("src", "primary2.gif");
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a69c84 and 2af0db5.

📒 Files selected for processing (2)
  • __tests__/components/common/FallbackImage.test.tsx (1 hunks)
  • components/auth/SeizeConnectContext.tsx (22 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Use TypeScript for implementation code

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • components/auth/SeizeConnectContext.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Use React functional components with hooks

Files:

  • __tests__/components/common/FallbackImage.test.tsx
  • components/auth/SeizeConnectContext.tsx
**/{__tests__/**/*.{ts,tsx},*.test.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/{__tests__/**/*.{ts,tsx},*.test.tsx}: Place tests in tests directories or alongside components as ComponentName.test.tsx
Mock external dependencies and APIs in tests

Files:

  • __tests__/components/common/FallbackImage.test.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/components/common/FallbackImage.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/common/FallbackImage.test.tsx
🧬 Code graph analysis (2)
__tests__/components/common/FallbackImage.test.tsx (1)
components/common/FallbackImage.tsx (1)
  • FallbackImage (13-52)
components/auth/SeizeConnectContext.tsx (2)
src/errors/wallet.ts (2)
  • WalletInitializationError (16-26)
  • WalletConnectionError (1-7)
src/utils/security-logger.ts (4)
  • logSecurityEvent (96-116)
  • createValidationEventContext (197-210)
  • logError (125-178)
  • createConnectionEventContext (184-191)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
__tests__/components/common/FallbackImage.test.tsx (2)

6-8: LGTM!

The afterEach cleanup ensures test isolation by restoring all mocks between tests, preventing cross-test pollution.


36-61: LGTM!

The test correctly validates the error cascade: onPrimaryError is called once when the primary fails, then onError is called when the fallback also fails. The assertions confirm each callback is invoked exactly once, ensuring proper error handling at both levels.

components/auth/SeizeConnectContext.tsx (6)

1-59: LGTM! Clean error class definitions and organized imports.

The consolidated imports and standardized error classes with double-quoted strings align well with the codebase conventions. The error classes properly extend Error and set prototypes for instanceof checks.


61-155: LGTM! Well-structured type definitions.

The unified state machine types ("initializing" | "disconnected" | "connecting" | "connected" | "error") and the WalletState discriminated union provide clear state transitions. The AddressValidationResult interface properly captures validation outcomes.


203-253: LGTM! Solid state machine and error handling.

The discriminated union WalletState type enables type-safe state transitions. The handleInitializationError function properly logs security events, clears invalid auth state, and creates descriptive error objects.


256-337: LGTM! Excellent state consolidation.

The unified state hook eliminates scattered state variables and provides clear state transitions. The initialization effect properly validates stored addresses and handles both valid and invalid cases. Computed properties maintain backward compatibility.


360-437: LGTM! Robust debounced wallet reconciliation.

The debounced synchronization effect (50ms delay) prevents race conditions from rapid account changes. Address validation using isAddress() and normalization via getAddress() ensures consistent checksummed format. The checks for isAlreadyConnected avoid unnecessary state updates.


535-571: LGTM! Thorough validation in seizeAcceptConnection.

The function properly validates the address format, logs security events (both failures and successes), normalizes to checksummed format via getAddress(), and throws descriptive errors for invalid addresses.

Comment thread components/auth/SeizeConnectContext.tsx
Comment thread components/auth/SeizeConnectContext.tsx Outdated
Signed-off-by: prxt6529 <prxt@6529.io>
ragnep
ragnep previously approved these changes Oct 7, 2025
Signed-off-by: prxt6529 <prxt@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Oct 7, 2025

@prxt6529 prxt6529 merged commit 342bb89 into main Oct 7, 2025
8 checks passed
@prxt6529 prxt6529 deleted the merging-prs-07-10-25 branch October 7, 2025 14:38
This was referenced Oct 31, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Nov 27, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Mar 2, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Mar 10, 2026
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