Skip to content

Commit ab4519f

Browse files
committed
Revert "feat(perps): enable RoE sign toggle on Auto Close TP/SL (#32404)"
This reverts commit 5f89af5.
1 parent 96abde9 commit ab4519f

11 files changed

Lines changed: 88 additions & 882 deletions

File tree

app/components/UI/Perps/Perps.testIds.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,6 @@ export const PerpsTPSLViewSelectorsIDs = {
332332
SET_BUTTON: 'perps-tpsl-set-button',
333333
TAKE_PROFIT_PRICE_INPUT: 'perps-tpsl-tp-input',
334334
STOP_LOSS_PRICE_INPUT: 'perps-tpsl-sl-input',
335-
TAKE_PROFIT_PERCENTAGE_INPUT: 'perps-tpsl-tp-percentage-input',
336-
STOP_LOSS_PERCENTAGE_INPUT: 'perps-tpsl-sl-percentage-input',
337-
TAKE_PROFIT_ROE_SIGN_BADGE: 'perps-tpsl-tp-roe-sign-badge',
338-
STOP_LOSS_ROE_SIGN_BADGE: 'perps-tpsl-sl-roe-sign-badge',
339335
} as const;
340336

341337
export const getPerpsTPSLViewSelector = {

app/components/UI/Perps/Views/PerpsOrderView/PerpsOrderView.test.tsx

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,58 +2383,6 @@ describe('PerpsOrderView', () => {
23832383
expect(placeOrderButton).toBeDefined();
23842384
});
23852385

2386-
it('accepts a signed take profit (negative RoE below current price) after the sheet confirms', async () => {
2387-
// Arrange: long order with a TP at 2000 (below current 3000). Classic
2388-
// side rules reject this, but the Auto Close sheet allows it as a
2389-
// negative take profit. Regression for PR #32404: the order view must
2390-
// accept the signed trigger once the sheet reports its sign.
2391-
(usePerpsOrderContext as jest.Mock).mockReturnValue(
2392-
orderContextWithTPSL({ direction: 'long', takeProfitPrice: '2000' }),
2393-
);
2394-
(usePerpsOrderValidation as jest.Mock).mockReturnValue({
2395-
isValid: true,
2396-
errors: [],
2397-
isValidating: false,
2398-
});
2399-
(usePerpsOrderExecution as jest.Mock).mockReturnValue({
2400-
placeOrder: jest.fn(),
2401-
isPlacing: false,
2402-
});
2403-
2404-
render(<PerpsOrderView />, { wrapper: TestWrapper });
2405-
2406-
// Before the sheet reports a sign, the default + TP shows the warning.
2407-
await waitFor(() => {
2408-
expect(screen.getByText(/Take profit must be above/)).toBeDefined();
2409-
});
2410-
2411-
// Act: open the TP/SL sheet and confirm with a signed (negative) RoE.
2412-
const tpslRow = await screen.findByTestId(
2413-
PerpsOrderViewSelectorsIDs.STOP_LOSS_BUTTON,
2414-
);
2415-
fireEvent.press(tpslRow);
2416-
const { onConfirm } =
2417-
mockNavigate.mock.calls[mockNavigate.mock.calls.length - 1][1];
2418-
await act(async () => {
2419-
await onConfirm(undefined, '2000', undefined, {
2420-
direction: 'long',
2421-
source: 'trade_screen',
2422-
positionSize: 0,
2423-
takeProfitPercentage: -10,
2424-
});
2425-
});
2426-
2427-
// Assert: the signed trigger is accepted — no wrong-side warning and the
2428-
// Place Order button is no longer disabled on TP/SL grounds.
2429-
await waitFor(() => {
2430-
expect(screen.queryByText(/Take profit must be/)).toBeNull();
2431-
});
2432-
const placeOrderButton = await screen.findByTestId(
2433-
PerpsOrderViewSelectorsIDs.PLACE_ORDER_BUTTON,
2434-
);
2435-
expect(placeOrderButton.props.accessibilityState?.disabled).toBeFalsy();
2436-
});
2437-
24382386
describe('limit order TP/SL validates against entry price, not market price', () => {
24392387
const orderContextForLimitOrder = (overrides: {
24402388
direction: 'long' | 'short';

app/components/UI/Perps/Views/PerpsOrderView/PerpsOrderView.tsx

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ import {
8888
type OrderParams,
8989
type OrderType,
9090
type Position,
91-
type TPSLTrackingData,
9291
ORDER_SLIPPAGE_CONFIG,
9392
} from '@metamask/perps-controller';
9493
import {
@@ -200,9 +199,6 @@ interface PerpsOrderViewContentProps {
200199
defaultMaxLeverage?: number;
201200
}
202201

203-
const flipDirection = (direction: 'long' | 'short'): 'long' | 'short' =>
204-
direction === 'long' ? 'short' : 'long';
205-
206202
/**
207203
* PerpsOrderViewContentBase
208204
* Main content component for the Perps order view
@@ -401,14 +397,6 @@ const PerpsOrderViewContentBase: React.FC<PerpsOrderViewContentProps> = ({
401397
const [isInputFocused, setIsInputFocused] = useState(false);
402398
const [shouldOpenLimitPrice, setShouldOpenLimitPrice] = useState(false);
403399

404-
// The Auto Close sheet renders the RoE sign on a badge and persists only the
405-
// trigger price — not the sign. Track the chosen sign here so order-view
406-
// validation can accept a signed trigger (a negative take profit or a
407-
// gain-side stop loss) instead of rejecting it with the classic
408-
// long/short side rules. Defaults match the sheet (+ TP / - SL).
409-
const [takeProfitSign, setTakeProfitSign] = useState<'+' | '-'>('+');
410-
const [stopLossSign, setStopLossSign] = useState<'+' | '-'>('-');
411-
412400
// Max slippage from persisted controller state via hook so the component
413401
// never reaches into PerpsController directly (perps anti-pattern rule).
414402
// The hook also exposes the source (default vs user-configured) for
@@ -947,25 +935,13 @@ const PerpsOrderViewContentBase: React.FC<PerpsOrderViewContentProps> = ({
947935
_position?: Position,
948936
takeProfitPrice?: string,
949937
stopLossPrice?: string,
950-
trackingData?: TPSLTrackingData,
951938
) => {
952939
// Order flow: no position; just persist TP/SL in form state
953940
const tpToSet = takeProfitPrice || undefined;
954941
const slToSet = stopLossPrice || undefined;
955942

956943
setTakeProfitPrice(tpToSet);
957944
setStopLossPrice(slToSet);
958-
959-
// Recover the RoE sign from the signed percentage the sheet reports so
960-
// validation accepts a signed trigger. A negative TP percentage is a
961-
// gain-side flip (-); a positive SL percentage is a gain-side flip (+).
962-
// Absent/zero percentage falls back to the natural sign.
963-
setTakeProfitSign(
964-
(trackingData?.takeProfitPercentage ?? 0) < 0 ? '-' : '+',
965-
);
966-
setStopLossSign(
967-
(trackingData?.stopLossPercentage ?? 0) > 0 ? '+' : '-',
968-
);
969945
},
970946
});
971947
}, [
@@ -1467,26 +1443,12 @@ const PerpsOrderViewContentBase: React.FC<PerpsOrderViewContentProps> = ({
14671443

14681444
const tpslPriceType = isLimitWithPrice ? 'entry' : 'current';
14691445

1470-
// The RoE sign decides which side of the reference price the trigger must
1471-
// sit on, mirroring usePerpsTPSLForm: a + take profit / - stop loss keep the
1472-
// natural side, while a signed flip (- TP / + SL) accepts the opposite side.
1473-
// Passing the effective direction lets the existing price-side checks respect
1474-
// the sign without changing their logic, so a signed trigger isn't rejected.
1475-
const takeProfitEffectiveDirection =
1476-
takeProfitSign === '+'
1477-
? orderForm.direction
1478-
: flipDirection(orderForm.direction);
1479-
const stopLossEffectiveDirection =
1480-
stopLossSign === '-'
1481-
? orderForm.direction
1482-
: flipDirection(orderForm.direction);
1483-
14841446
const isTakeProfitPriceInvalid = Boolean(
14851447
orderForm.takeProfitPrice?.trim() &&
14861448
validationReferencePrice > 0 &&
14871449
!isValidTakeProfitPrice(orderForm.takeProfitPrice, {
14881450
currentPrice: validationReferencePrice,
1489-
direction: takeProfitEffectiveDirection,
1451+
direction: orderForm.direction,
14901452
}),
14911453
);
14921454

@@ -1495,7 +1457,7 @@ const PerpsOrderViewContentBase: React.FC<PerpsOrderViewContentProps> = ({
14951457
validationReferencePrice > 0 &&
14961458
!isValidStopLossPrice(orderForm.stopLossPrice, {
14971459
currentPrice: validationReferencePrice,
1498-
direction: stopLossEffectiveDirection,
1460+
direction: orderForm.direction,
14991461
}),
15001462
);
15011463

app/components/UI/Perps/Views/PerpsTPSLView/PerpsTPSLView.styles.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,4 @@ export const createStyles = (colors: Theme['colors']) =>
217217
footerButton: {
218218
flex: 1,
219219
},
220-
roeSignBadge: {
221-
paddingHorizontal: 8,
222-
paddingVertical: 2,
223-
marginRight: 4,
224-
borderRadius: 6,
225-
backgroundColor: colors.background.default,
226-
alignItems: 'center',
227-
justifyContent: 'center',
228-
},
229220
});

app/components/UI/Perps/Views/PerpsTPSLView/PerpsTPSLView.test.tsx

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,6 @@ describe('PerpsTPSLView', () => {
153153
slPercentInputFocused: false,
154154
tpUsingPercentage: false,
155155
slUsingPercentage: false,
156-
takeProfitSign: '+',
157-
stopLossSign: '-',
158156
},
159157
handlers: {
160158
handleTakeProfitPriceChange: jest.fn(),
@@ -175,8 +173,6 @@ describe('PerpsTPSLView', () => {
175173
handleStopLossPercentageButton: jest.fn(),
176174
handleTakeProfitOff: jest.fn(),
177175
handleStopLossOff: jest.fn(),
178-
handleTakeProfitSignToggle: jest.fn(),
179-
handleStopLossSignToggle: jest.fn(),
180176
},
181177
validation: {
182178
isValid: true,
@@ -591,44 +587,6 @@ describe('PerpsTPSLView', () => {
591587
);
592588
});
593589

594-
it('reports signed RoE percentages in tracking metadata for negative TP and gain-side SL', async () => {
595-
const mockOnConfirm = jest.fn().mockResolvedValue(undefined);
596-
mockRouteParams = { ...defaultRouteParams, onConfirm: mockOnConfirm };
597-
renderView({
598-
formState: {
599-
...defaultMockReturn.formState,
600-
takeProfitPrice: '$2,850.00',
601-
stopLossPrice: '$3,150.00',
602-
takeProfitSign: '-',
603-
stopLossSign: '+',
604-
},
605-
display: {
606-
...defaultMockReturn.display,
607-
formattedTakeProfitPercentage: '10%',
608-
formattedStopLossPercentage: '10%',
609-
},
610-
validation: {
611-
...defaultMockReturn.validation,
612-
hasChanges: true,
613-
},
614-
});
615-
616-
const setButton = screen.getByText('perps.tpsl.set');
617-
await act(async () => {
618-
fireEvent.press(setButton);
619-
});
620-
621-
expect(mockOnConfirm).toHaveBeenCalledWith(
622-
undefined,
623-
'2850.00',
624-
'3150.00',
625-
expect.objectContaining({
626-
takeProfitPercentage: -10,
627-
stopLossPercentage: 10,
628-
}),
629-
);
630-
});
631-
632590
it('calls onConfirm with undefined when values are empty', async () => {
633591
const mockOnConfirm = jest.fn().mockResolvedValue(undefined);
634592
mockRouteParams = { ...defaultRouteParams, onConfirm: mockOnConfirm };
@@ -743,60 +701,4 @@ describe('PerpsTPSLView', () => {
743701
expect(screen.getByTestId('back-button')).toBeOnTheScreen();
744702
});
745703
});
746-
747-
// ==================== RoE Sign Badge ====================
748-
749-
describe('RoE Sign Badge', () => {
750-
it('renders the default + take profit and - stop loss signs', () => {
751-
renderView();
752-
753-
expect(
754-
screen.getByTestId('perps-tpsl-tp-roe-sign-badge'),
755-
).toHaveTextContent('+');
756-
expect(
757-
screen.getByTestId('perps-tpsl-sl-roe-sign-badge'),
758-
).toHaveTextContent('-');
759-
});
760-
761-
it('toggles the take profit sign when the badge is pressed', () => {
762-
const mockToggle = jest.fn();
763-
renderView({
764-
buttons: {
765-
...defaultMockReturn.buttons,
766-
handleTakeProfitSignToggle: mockToggle,
767-
},
768-
});
769-
770-
fireEvent.press(screen.getByTestId('perps-tpsl-tp-roe-sign-badge'));
771-
772-
expect(mockToggle).toHaveBeenCalled();
773-
});
774-
775-
it('toggles the stop loss sign when the badge is pressed', () => {
776-
const mockToggle = jest.fn();
777-
renderView({
778-
buttons: {
779-
...defaultMockReturn.buttons,
780-
handleStopLossSignToggle: mockToggle,
781-
},
782-
});
783-
784-
fireEvent.press(screen.getByTestId('perps-tpsl-sl-roe-sign-badge'));
785-
786-
expect(mockToggle).toHaveBeenCalled();
787-
});
788-
789-
it('reflects the take profit sign provided by the form hook', () => {
790-
renderView({
791-
formState: {
792-
...defaultMockReturn.formState,
793-
takeProfitSign: '-',
794-
},
795-
});
796-
797-
expect(
798-
screen.getByTestId('perps-tpsl-tp-roe-sign-badge'),
799-
).toHaveTextContent('-');
800-
});
801-
});
802704
});

0 commit comments

Comments
 (0)