diff --git a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.stories.tsx b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.stories.tsx
index cc70141cc131..a517361209c9 100644
--- a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.stories.tsx
+++ b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.stories.tsx
@@ -7,10 +7,9 @@ const PerpsEmptyStateMeta = {
export default PerpsEmptyStateMeta;
-// Default story
export const Default = {
args: {
- onStartTrading: () => {
+ onAction: () => {
// eslint-disable-next-line no-console
console.log('Start Trading pressed');
},
diff --git a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.test.tsx b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.test.tsx
index 4d9d457146a3..1933ca2030d3 100644
--- a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.test.tsx
+++ b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.test.tsx
@@ -4,7 +4,7 @@ import renderWithProvider from '../../../../../util/test/renderWithProvider';
import { PerpsEmptyState } from './PerpsEmptyState';
describe('PerpsEmptyState', () => {
- const mockOnStartTrading = jest.fn();
+ const mockOnAction = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
@@ -12,7 +12,7 @@ describe('PerpsEmptyState', () => {
it('should render correctly', () => {
const { getByText } = renderWithProvider(
- ,
+ ,
);
expect(
@@ -21,14 +21,14 @@ describe('PerpsEmptyState', () => {
expect(getByText('Start trading')).toBeTruthy();
});
- it('should call onStartTrading when button is pressed', () => {
+ it('should call onAction when button is pressed', () => {
const { getByText } = renderWithProvider(
- ,
+ ,
);
const startTradingButton = getByText('Start trading');
fireEvent.press(startTradingButton);
- expect(mockOnStartTrading).toHaveBeenCalledTimes(1);
+ expect(mockOnAction).toHaveBeenCalledTimes(1);
});
});
diff --git a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.tsx b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.tsx
index 8a2d54cd2b90..0cd1d05bcf7d 100644
--- a/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.tsx
+++ b/app/components/UI/Perps/Views/PerpsEmptyState/PerpsEmptyState.tsx
@@ -11,12 +11,10 @@ import emptyStatePerpsLight from '../../../../../images/empty-state-perps-light.
import emptyStatePerpsDark from '../../../../../images/empty-state-perps-dark.png';
export interface PerpsEmptyStateProps extends TabEmptyStateProps {
- onStartTrading: () => void;
testID?: string;
}
export const PerpsEmptyState: React.FC = ({
- onStartTrading,
testID,
...props
}) => {
@@ -36,7 +34,6 @@ export const PerpsEmptyState: React.FC = ({
}
description={strings('perps.position.list.first_time_description')}
actionButtonText={strings('perps.position.list.start_trading')}
- onAction={onStartTrading}
testID={testID}
{...props}
/>
diff --git a/app/components/UI/Perps/Views/PerpsPositionsView/PerpsPositionsView.tsx b/app/components/UI/Perps/Views/PerpsPositionsView/PerpsPositionsView.tsx
index 92cf80c98d1d..e3f659cc0ce4 100644
--- a/app/components/UI/Perps/Views/PerpsPositionsView/PerpsPositionsView.tsx
+++ b/app/components/UI/Perps/Views/PerpsPositionsView/PerpsPositionsView.tsx
@@ -24,6 +24,7 @@ import type { Position } from '../../controllers/types';
import { usePerpsLivePositions, usePerpsTPSLUpdate } from '../../hooks';
import { usePerpsLiveAccount } from '../../hooks/stream';
import { formatPnl, formatPrice } from '../../utils/formatUtils';
+import { getPositionDirection } from '../../utils/positionCalculations';
import { calculateTotalPnL } from '../../utils/pnlCalculations';
import { createStyles } from './PerpsPositionsView.styles';
import { SafeAreaView } from 'react-native-safe-area-context';
@@ -125,14 +126,7 @@ const PerpsPositionsView: React.FC = () => {
{positions.map((position, index) => {
- const sizeValue = parseFloat(position.size);
- const directionSegment = Number.isFinite(sizeValue)
- ? sizeValue > 0
- ? 'long'
- : sizeValue < 0
- ? 'short'
- : 'unknown'
- : 'unknown';
+ const directionSegment = getPositionDirection(position.size);
return (
({
// Mock PerpsEmptyState component to avoid Redux context issues while preserving testID
jest.mock('../PerpsEmptyState', () => ({
PerpsEmptyState: ({
- onStartTrading,
+ onAction,
testID,
}: {
- onStartTrading: () => void;
+ onAction?: () => void;
testID?: string;
}) => {
const { TouchableOpacity, Text, View } = jest.requireActual('react-native');
return (
Bet on price movements with up to 40x leverage.
-
+
Start trading
diff --git a/app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.tsx b/app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.tsx
index 09e1cb698389..e0478585cbca 100644
--- a/app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.tsx
+++ b/app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.tsx
@@ -38,6 +38,7 @@ import {
usePerpsLivePositions,
usePerpsPerformance,
} from '../../hooks';
+import { getPositionDirection } from '../../utils/positionCalculations';
import { usePerpsLiveAccount, usePerpsLiveOrders } from '../../hooks/stream';
import { selectPerpsEligibility } from '../../selectors/perpsController';
import styleSheet from './PerpsTabView.styles';
@@ -208,14 +209,7 @@ const PerpsTabView: React.FC = () => {
{positions.map((position, index) => {
- const sizeValue = parseFloat(position.size);
- const directionSegment = Number.isFinite(sizeValue)
- ? sizeValue > 0
- ? 'long'
- : sizeValue < 0
- ? 'short'
- : 'unknown'
- : 'unknown';
+ const directionSegment = getPositionDirection(position.size);
return (
= () => {
{!isInitialLoading && hasNoPositionsOrOrders ? (
diff --git a/app/components/UI/Perps/utils/positionCalculations.test.ts b/app/components/UI/Perps/utils/positionCalculations.test.ts
index b7d5ce2031a4..184ac727f7f4 100644
--- a/app/components/UI/Perps/utils/positionCalculations.test.ts
+++ b/app/components/UI/Perps/utils/positionCalculations.test.ts
@@ -5,6 +5,7 @@ import {
calculateCloseValue,
calculatePercentageFromTokenAmount,
calculatePercentageFromUSDAmount,
+ getPositionDirection,
} from './positionCalculations';
describe('Position Calculations Utils', () => {
@@ -193,4 +194,50 @@ describe('Position Calculations Utils', () => {
expect(result).toBe(0);
});
});
+
+ describe('getPositionDirection', () => {
+ it('returns "long" for positive position sizes', () => {
+ expect(getPositionDirection('10.5')).toBe('long');
+ expect(getPositionDirection('0.01')).toBe('long');
+ expect(getPositionDirection('1000')).toBe('long');
+ });
+
+ it('returns "short" for negative position sizes', () => {
+ expect(getPositionDirection('-10.5')).toBe('short');
+ expect(getPositionDirection('-0.01')).toBe('short');
+ expect(getPositionDirection('-1000')).toBe('short');
+ });
+
+ it('returns "unknown" for zero position size', () => {
+ expect(getPositionDirection('0')).toBe('unknown');
+ expect(getPositionDirection('0.0')).toBe('unknown');
+ expect(getPositionDirection('-0')).toBe('unknown');
+ });
+
+ it('returns "unknown" for invalid strings', () => {
+ expect(getPositionDirection('abc')).toBe('unknown');
+ expect(getPositionDirection('not a number')).toBe('unknown');
+ expect(getPositionDirection('')).toBe('unknown');
+ expect(getPositionDirection(' ')).toBe('unknown');
+ });
+
+ it('returns "unknown" for non-finite values', () => {
+ expect(getPositionDirection('Infinity')).toBe('unknown');
+ expect(getPositionDirection('-Infinity')).toBe('unknown');
+ expect(getPositionDirection('NaN')).toBe('unknown');
+ });
+
+ it('handles edge cases correctly', () => {
+ expect(getPositionDirection('1e-10')).toBe('long'); // Very small positive
+ expect(getPositionDirection('-1e-10')).toBe('short'); // Very small negative
+ expect(getPositionDirection('1.23e15')).toBe('long'); // Large positive
+ expect(getPositionDirection('-1.23e15')).toBe('short'); // Large negative
+ });
+
+ it('handles strings with whitespace', () => {
+ expect(getPositionDirection(' 10.5 ')).toBe('long');
+ expect(getPositionDirection(' -10.5 ')).toBe('short');
+ expect(getPositionDirection(' 0 ')).toBe('unknown');
+ });
+ });
});
diff --git a/app/components/UI/Perps/utils/positionCalculations.ts b/app/components/UI/Perps/utils/positionCalculations.ts
index fb2070ddb4a2..a33256da1037 100644
--- a/app/components/UI/Perps/utils/positionCalculations.ts
+++ b/app/components/UI/Perps/utils/positionCalculations.ts
@@ -175,3 +175,28 @@ export function calculatePercentageFromUSDAmount(
const percentage = (usdAmount / totalPositionValue) * 100;
return Math.max(0, Math.min(100, percentage));
}
+
+/**
+ * Helper function to determine position direction based on size value
+ * @param sizeString - The position size as a string
+ * @returns 'long', 'short', or 'unknown'
+ */
+export function getPositionDirection(
+ sizeString: string,
+): 'long' | 'short' | 'unknown' {
+ const sizeValue = parseFloat(sizeString);
+
+ if (!Number.isFinite(sizeValue)) {
+ return 'unknown';
+ }
+
+ if (sizeValue > 0) {
+ return 'long';
+ }
+
+ if (sizeValue < 0) {
+ return 'short';
+ }
+
+ return 'unknown';
+}