Skip to content

Commit 7e704a6

Browse files
authored
fix: check for balance considering different formats (#28382)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> A failed cast from a localized numeric value is preventing the send button from displaying in languages such as Spanish or French. Stop that cast and check for a '0' string instead. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fixed Send button not showing in token details page for certain languages ## **Related issues** Fixes: #27789 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/f0abbe29-630c-488a-96a8-54e26f571830 ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/44dfea66-8a52-4e40-a9a9-fc509995b69f ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I've included tests if applicable - [X] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the `hasBalance` gating for Token Details actions, which controls whether actions like Send are shown/enabled; incorrect string formats (e.g., `'0.00'`) could change behavior. Scope is small and covered by new unit tests for localized formats. > > **Overview** > Fixes Token Details action availability checks to avoid `Number()` parsing failures on localized balance strings (e.g., `1.000,50`), by treating any non-empty balance not equal to `'0'` as having funds. > > Adds a focused test suite that spies on `TokenDetailsActions` and asserts the computed `hasBalance` prop for empty/undefined, `'0'`, and localized numeric balance formats. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c727e9e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 5c404d0 commit 7e704a6

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

app/components/UI/TokenDetails/components/AssetOverviewContent.test.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
} from '@metamask/perps-controller';
1818
import { strings } from '../../../../../locales/i18n';
1919
import type { TokenSecurityData } from '@metamask/assets-controllers';
20+
// eslint-disable-next-line import-x/no-namespace
21+
import * as TokenDetailsActionsModule from './TokenDetailsActions';
2022

2123
const mockHandlePerpsAction = jest.fn();
2224
const mockTrack = jest.fn();
@@ -796,4 +798,59 @@ describe('AssetOverviewContent', () => {
796798
).toBeNull();
797799
});
798800
});
801+
802+
describe('TokenDetailsActions hasBalance prop', () => {
803+
let tokenDetailsActionsSpy: jest.SpyInstance;
804+
805+
beforeEach(() => {
806+
jest.clearAllMocks();
807+
mockBuild.mockReturnValue({ category: 'test-event' });
808+
mockAddProperties.mockReturnValue({ build: mockBuild });
809+
mockCreateEventBuilder.mockReturnValue({
810+
addProperties: mockAddProperties,
811+
});
812+
mockSelectMarketInsightsEnabled.mockReturnValue(false);
813+
mockUseMarketInsights.mockReturnValue({
814+
report: null,
815+
isLoading: false,
816+
error: null,
817+
timeAgo: null,
818+
});
819+
mockUsePerpsPositionForAsset.mockReturnValue({
820+
position: null,
821+
hasFundsInPerps: false,
822+
accountState: null,
823+
isLoading: false,
824+
});
825+
tokenDetailsActionsSpy = jest.spyOn(
826+
TokenDetailsActionsModule,
827+
'TokenDetailsActions',
828+
);
829+
});
830+
831+
afterEach(() => {
832+
tokenDetailsActionsSpy.mockRestore();
833+
});
834+
835+
it.each([
836+
[false, undefined],
837+
[false, ''],
838+
[false, '0'],
839+
[true, '1,000.50'],
840+
[true, '1.000,50'],
841+
])(
842+
'passes hasBalance %s when balance is %s',
843+
(expectedHasBalance, balance) => {
844+
renderWithProvider(
845+
<AssetOverviewContent {...defaultProps} balance={balance} />,
846+
{ state: createState(true) },
847+
);
848+
849+
expect(tokenDetailsActionsSpy).toHaveBeenCalledWith(
850+
expect.objectContaining({ hasBalance: expectedHasBalance }),
851+
expect.anything(),
852+
);
853+
},
854+
);
855+
});
799856
});

app/components/UI/TokenDetails/components/AssetOverviewContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ const AssetOverviewContent: React.FC<AssetOverviewContentProps> = ({
828828
{useNewLayout ? (
829829
<TokenDetailsActions
830830
hasPerpsMarket={hasPerpsMarket}
831-
hasBalance={balance != null && Number(balance) > 0}
831+
hasBalance={Boolean(balance) && balance !== '0'}
832832
isBuyable={isBuyable}
833833
isNativeCurrency={token.isETH || token.isNative || false}
834834
token={token}

0 commit comments

Comments
 (0)