From 3fc2cf20bf9e799937b66b6784a025d6e6d86bb9 Mon Sep 17 00:00:00 2001 From: Maryia <103177211+maryia-deriv@users.noreply.github.com> Date: Fri, 3 Nov 2023 13:11:12 +0300 Subject: [PATCH] Maryia/OPT-591/fix: Total profit/loss in Multipliers contract card with Deal Cancellation (#11057) * fix: pnl in multipliers card * test: add tests + make indicator the same as in reports --- .../__tests__/multiplier-card-body.spec.tsx | 126 ++++++++++++++++++ .../multiplier-card-body.jsx | 19 +-- 2 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 packages/components/src/components/contract-card/contract-card-items/__tests__/multiplier-card-body.spec.tsx diff --git a/packages/components/src/components/contract-card/contract-card-items/__tests__/multiplier-card-body.spec.tsx b/packages/components/src/components/contract-card/contract-card-items/__tests__/multiplier-card-body.spec.tsx new file mode 100644 index 000000000000..a06f646db83f --- /dev/null +++ b/packages/components/src/components/contract-card/contract-card-items/__tests__/multiplier-card-body.spec.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import MultiplierCardBody from '../multiplier-card-body'; + +type TMockedMultiplierCardBodyProps = Partial>; + +describe('MultiplierCardBody', () => { + let mock_props: TMockedMultiplierCardBodyProps = {}; + const red_indicative_movement_testid = 'dt_indicative_movement_loss'; + const green_indicative_movement_testid = 'dt_indicative_movement_profit'; + const progress_slider = 'progress_slider'; + + beforeEach(() => { + mock_props = { + addToast: jest.fn(), + contract_info: { + // 'Total profit/loss' equals to bid_price - buy_price; + buy_price: 10.44, + bid_price: 10, + cancellation: { ask_price: 0.44 }, + is_valid_to_cancel: 0, + is_valid_to_sell: 0, + limit_order: { + stop_out: { + display_name: 'Stop out', + order_amount: -10, + order_date: 1698680866, + value: '1942.71', + }, + }, + sell_price: '10', + status: 'cancelled', + profit: 0, + underlying: '1HZ100V', + }, + contract_update: {}, + currency: 'USD', + current_focus: '', + getCardLabels: () => ({ + BUY_PRICE: 'Buy price:', + CURRENT_STAKE: 'Current stake:', + DEAL_CANCEL_FEE: 'Deal cancel. fee:', + NOT_AVAILABLE: 'N/A', + STAKE: 'Stake:', + STOP_LOSS: 'Stop loss:', + TAKE_PROFIT: 'Take profit:', + TOTAL_PROFIT_LOSS: 'Total Profit/Loss:', + }), + getContractById: jest.fn(), + has_progress_slider: false, + is_mobile: false, + is_sold: true, + onMouseLeave: jest.fn(), + progress_slider: null, + removeToast: jest.fn(), + setCurrentFocus: jest.fn(), + should_show_cancellation_warning: false, + status: 'profit', + toggleCancellationWarning: jest.fn(), + }; + }); + + const testCardContent = (props: TMockedMultiplierCardBodyProps) => { + expect(screen.getByText(props.getCardLabels().BUY_PRICE)).toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().CURRENT_STAKE)).toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().DEAL_CANCEL_FEE)).toBeInTheDocument(); + expect(screen.queryByText(props.getCardLabels().NOT_AVAILABLE)).not.toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().STAKE)).toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().STOP_LOSS)).toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().TAKE_PROFIT)).toBeInTheDocument(); + expect(screen.getByText(props.getCardLabels().TOTAL_PROFIT_LOSS)).toBeInTheDocument(); + }; + + it('should render the correct content for a Cancelled contract with Deal cancel.fee and negative Total profit/loss', () => { + render(); + + testCardContent(mock_props); + expect(screen.getByTestId(red_indicative_movement_testid)).toBeInTheDocument(); + }); + it('should render a green price movement indicator when Won with positive Total profit/loss', () => { + mock_props.contract_info.bid_price = 10.03; + mock_props.contract_info.buy_price = 10; + mock_props.contract_info.profit = 0.03; + mock_props.contract_info.sell_price = 10.03; + mock_props.contract_info.status = 'sold'; + delete mock_props.contract_info.cancellation; + + render(); + + testCardContent(mock_props); + expect(screen.getByTestId(green_indicative_movement_testid)).toBeInTheDocument(); + }); + it('should render correct content for an open contract with negative Total profit/loss in mobile', () => { + mock_props.is_mobile = true; + mock_props.contract_info.bid_price = 10.2; + mock_props.contract_info.buy_price = 10.44; + mock_props.contract_info.is_sold = 0; + mock_props.contract_info.is_valid_to_cancel = 1; + mock_props.contract_info.is_valid_to_sell = 1; + mock_props.contract_info.profit = 0.2; + mock_props.contract_info.status = 'open'; + mock_props.status = 'profit'; + mock_props.is_sold = false; + delete mock_props.contract_info.sell_price; + + render(); + + testCardContent(mock_props); + expect(screen.getByTestId(red_indicative_movement_testid)).toBeInTheDocument(); + }); + it('should render progress_slider and N/A in Deal Cancel.fee when contract is open for a crypto asset in mobile', () => { + mock_props.is_mobile = true; + mock_props.contract_info.status = 'open'; + mock_props.contract_info.underlying = 'cryBTCUSD'; + mock_props.is_sold = false; + mock_props.has_progress_slider = true; + mock_props.progress_slider = progress_slider; + delete mock_props.contract_info.cancellation; + delete mock_props.contract_info.sell_price; + + render(); + + expect(screen.getByText(mock_props.getCardLabels().NOT_AVAILABLE)).toBeInTheDocument(); + expect(screen.getByText(progress_slider)).toBeInTheDocument(); + }); +}); diff --git a/packages/components/src/components/contract-card/contract-card-items/multiplier-card-body.jsx b/packages/components/src/components/contract-card/contract-card-items/multiplier-card-body.jsx index d21097a2f06c..5a1dff2f4fac 100644 --- a/packages/components/src/components/contract-card/contract-card-items/multiplier-card-body.jsx +++ b/packages/components/src/components/contract-card/contract-card-items/multiplier-card-body.jsx @@ -5,6 +5,7 @@ import { isCryptocurrency, getCancellationPrice, getLimitOrderAmount, + getTotalProfit, isValidToCancel, isValidToSell, shouldShowCancellation, @@ -35,12 +36,12 @@ const MultiplierCardBody = ({ status, toggleCancellationWarning, }) => { - const { buy_price, bid_price, profit, limit_order, underlying } = contract_info; - + const { buy_price, bid_price, limit_order, underlying } = contract_info; const { take_profit, stop_loss } = getLimitOrderAmount(contract_update || limit_order); const cancellation_price = getCancellationPrice(contract_info); const is_valid_to_cancel = isValidToCancel(contract_info); const is_valid_to_sell = isValidToSell(contract_info); + const total_profit = getTotalProfit(contract_info); const { BUY_PRICE, CURRENT_STAKE, @@ -67,8 +68,8 @@ const MultiplierCardBody = ({
0, - 'dc-contract-card--loss': +profit < 0, + 'dc-contract-card--profit': total_profit > 0, + 'dc-contract-card--loss': total_profit < 0, })} > @@ -127,17 +128,17 @@ const MultiplierCardBody = ({ className='dc-contract-card-item__total-profit-loss' header={TOTAL_PROFIT_LOSS} is_crypto={isCryptocurrency(currency)} - is_loss={+profit < 0} - is_won={+profit > 0} + is_loss={total_profit < 0} + is_won={total_profit > 0} > - +
0 ? 'profit' : 'loss'}`} > - {status === 'profit' && } - {status === 'loss' && } + {total_profit > 0 ? : }