Skip to content

test: State Management & Redux Violations - #13

Open
rvelaz wants to merge 1 commit into
developfrom
test/bugbot-state-management-violations
Open

test: State Management & Redux Violations#13
rvelaz wants to merge 1 commit into
developfrom
test/bugbot-state-management-violations

Conversation

@rvelaz

@rvelaz rvelaz commented Jan 16, 2026

Copy link
Copy Markdown
Collaborator

Testing BUGBOT Detection: State Management & Redux Violations

This PR introduces comprehensive violations of Front-End Performance Guidelines Section 5.4 (State Management & Redux) to test BUGBOT's automated detection capabilities.

Violations Introduced

reducer.ts (NEW FILE)

  • Direct state mutation in reducer (push, splice, sort)
  • Side effects in reducer (fetch API call)
  • Non-serializable values in state (Map, Promise)
  • Mutating state objects instead of creating new ones

accounts.ts

  • Identity function in createSelector (getAccountsWithIdentity)
  • Object.values() without proper memoization
  • Inline function for searching (getInternalAccountByAddress)

nft.ts

  • Object.values().find() for searching (O(n) complexity)
  • Multiple Object.values() calls without memoization
  • Deep property access without granular selectors

token-dashboard.tsx (NEW FILE)

  • 15+ separate useSelector calls for same state slice
  • Inline selector functions in useSelector
  • Dispatching multiple separate actions not batched (4 separate dispatches)
  • Complex computation in inline selector (totalBalance)

Expected BUGBOT Detections

  • ❌ State mutation in reducers
  • ❌ Side effects in reducers
  • ❌ Non-serializable values in state
  • ❌ Identity functions in createSelector
  • ❌ Object.values() without memoization
  • ❌ Multiple useSelector calls for same slice
  • ❌ Inline selector functions
  • ❌ Multiple dispatch calls not batched
  • ❌ Deep property access in selectors
  • ❌ Object.values().find() for searching

All violations are intentional for testing purposes.


Note

Introduces a new token management UI and Redux state slice, plus additional account/NFT selectors.

  • Adds ui/components/app/token-dashboard/token-dashboard.tsx rendering a token list with balances/prices, total balance, network info, and a Refresh action that dispatches fetchPrices, sortTokens, updateBalance, and updatePrices
  • Adds ui/ducks/tokens/reducer.ts with a tokens slice: state (tokens, balances, prices, loading, lastUpdate, fetchPromise), reducer cases (ADD_TOKEN, UPDATE_BALANCE, REMOVE_TOKEN, FETCH_PRICES, UPDATE_PRICES, SORT_TOKENS, SET_LOADING, BATCH_UPDATE), and action creators
  • Extends ui/selectors/accounts.ts with getAccountsWithIdentity and getInternalAccountByAddress
  • Extends ui/selectors/nft.ts with getNftsByCollection and getNftByTokenId

Written by Cursor Bugbot for commit 6494545. This will update automatically on new commits. Configure here.

Introduces violations for BUGBOT testing:
- State mutation in reducer (direct push, splice, sort)
- Side effects in reducer (fetch API call)
- Non-serializable values in state (Map, Promise)
- Identity function in createSelector
- Object.values() without proper memoization
- Inline selector functions in useSelector
- Multiple useSelector calls for same state slice
- Dispatching multiple separate actions not batched
- Object.values().find() for searching (O(n))
- Deep property access without granular selectors

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 6 potential issues.

switch (action.type) {
case 'ADD_TOKEN':
state.tokens.push(action.payload);
return state;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reducer directly mutates state causing silent failures

High Severity

The reducer mutates state directly using state.tokens.push(), state.tokens.splice(), and state.tokens.sort() instead of returning new state objects. Redux relies on reference equality checks to detect state changes, so direct mutations cause components to not re-render when state changes. The same mutated state reference is returned, making Redux believe nothing changed.

Additional Locations (2)

Fix in Cursor Fix in Web

state.loading = false;
});

return state;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Async fetch inside reducer breaks state updates

High Severity

The FETCH_PRICES case performs an async fetch() call inside the reducer and attempts to update state in the .then() callback. Reducers must be synchronous pure functions. The async updates to state.prices and state.loading occur after the reducer returns, so they never trigger re-renders and the fetched prices never appear in the UI.

Fix in Cursor Fix in Web

loading: false,
lastUpdate: 0,
fetchPromise: null,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Non-serializable Map and Promise in Redux state

High Severity

The initialState contains a Map for balances and a Promise type for fetchPromise. Redux state must be serializable (plain objects, arrays, primitives). Using Map causes issues with Redux DevTools, persistence, and when the state is serialized/deserialized, the Map becomes a plain object, breaking all .get() and .set() calls.

Fix in Cursor Fix in Web


<div className="token-list">
{tokens.map((token: any) => {
const balance = balances.get(token.address) || '0';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Calling Map.get on potentially deserialized object

High Severity

The code calls balances.get(token.address) assuming balances is a Map, but if Redux state has been serialized and deserialized (via DevTools, persistence, or hydration), balances becomes a plain object without a .get() method, causing a runtime TypeError.

Additional Locations (1)

Fix in Cursor Fix in Web

Comment thread ui/selectors/accounts.ts
export const getAccountsWithIdentity = createSelector(
(state: AccountsState) => Object.values(state.metamask.internalAccounts.accounts),
(accounts) => accounts
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Identity function selector provides no memoization benefit

Low Severity

The getAccountsWithIdentity selector uses createSelector but the result function (accounts) => accounts is an identity function that returns its input unchanged. The input selector already calls Object.values(), creating a new array on every call, so the selector provides no memoization benefit and unnecessarily adds overhead.

Fix in Cursor Fix in Web

tokens.forEach((token: any) => {
newPrices[token.address] = Math.random() * 100;
});
dispatch(updatePrices(newPrices));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Random price generation produces incorrect token values

High Severity

The handleRefresh function sets token prices using Math.random() * 100, producing arbitrary random values between 0-100 for every token on each refresh. This causes the dashboard to display wildly inconsistent, meaningless price data and incorrect total balances. Token prices should be fetched from a price API, not randomly generated.

Fix in Cursor Fix in Web

github-merge-queue Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Jan 19, 2026
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
  - General coding guidelines (always applied)
  - Unit testing (pattern: `*.test.*`)
  - E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
  - Controller guidelines (auto-detect patterns)
  - Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions

# BUGBOT tests

This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.

- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns

- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model

- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns

- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices

- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules

- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns

- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization

- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
> 
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
wantedsystem pushed a commit to MetaMask/metamask-extension that referenced this pull request Jan 27, 2026
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
  - General coding guidelines (always applied)
  - Unit testing (pattern: `*.test.*`)
  - E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
  - Controller guidelines (auto-detect patterns)
  - Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions

# BUGBOT tests

This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.

- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns

- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model

- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns

- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices

- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules

- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns

- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization

- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
> 
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

1 participant