From e63a2cdc1e904fcb278c1e4e39185cea2bcd15d1 Mon Sep 17 00:00:00 2001 From: kate-deriv <121025168+kate-deriv@users.noreply.github.com> Date: Fri, 3 Nov 2023 12:13:37 +0300 Subject: [PATCH] Kate / DTRA-436 / Consistency for Responsive for all trade types (except Multipliers) (#10826) * refactor: make cards consistance * refactor: remove some multipliers limitations and commited code * refactor: add unit tests * refactor: unit tests * refactor: apply suggestions --- .../contract-card-header.tsx | 2 - .../contract-card/contract-card.scss | 3 + .../__tests__/position-modal-card.spec.tsx | 194 ++++++++++++++++++ .../PositionsDrawer/positions-modal-card.tsx | 156 +------------- 4 files changed, 203 insertions(+), 152 deletions(-) create mode 100644 packages/trader/src/App/Components/Elements/PositionsDrawer/__tests__/position-modal-card.spec.tsx diff --git a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx index 1ce4c8a311d1..a5a1aabbc4ba 100644 --- a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx +++ b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx @@ -96,8 +96,6 @@ const ContractCardHeader = ({
; + +const default_mock_store = { + modules: { + trade: { + active_symbols: [{ symbol: 'R_10' }] as ActiveSymbols, + }, + }, + ui: { + addToast: jest.fn(), + current_focus: '', + is_mobile: true, + removeToast: jest.fn(), + setCurrentFocus: jest.fn(), + should_show_cancellation_warning: false, + toggleCancellationWarning: jest.fn(), + }, + common: { + server_time: 123254362145 as unknown as moment.Moment, + }, + contract_trade: { + getContractById: jest.fn(), + }, +}; +const PositionsCardLoader = 'PositionsCardLoader'; +const SymbolDisplayName = 'SymbolDisplayName'; + +jest.mock('App/Components/Elements/ContentLoader', () => ({ + ...jest.requireActual('App/Components/Elements/ContentLoader'), + PositionsCardLoader: jest.fn(() =>
{PositionsCardLoader}
), +})); +jest.mock('@deriv/shared', () => ({ + ...jest.requireActual('@deriv/shared'), + getEndTime: jest.fn(() => false), + getTotalProfit: jest.fn(() => 35.6786), + getSymbolDisplayName: jest.fn(() => SymbolDisplayName), +})); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + NavLink: jest.fn(({ children }) =>
{children}
), +})); +jest.mock('App/Components/Routes', () => ({ + ...jest.requireActual('App/Components/Routes'), + BinaryLink: jest.fn(({ children }) =>
{children}
), +})); +jest.mock('@deriv/components', () => ({ + ...jest.requireActual('@deriv/components'), + CurrencyBadge: jest.fn(() =>
CurrencyBadge
), + ProgressSliderMobile: jest.fn(() =>
ProgressSliderMobile
), +})); + +describe('', () => { + const mockPositionsModalCard = ( + mocked_store: TCoreStores, + mocked_params: React.ComponentProps + ) => { + return ( + + + + ); + }; + + it('should render loader if underlying in contract_info is falsy and contract is unsupported', () => { + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.getByText(PositionsCardLoader)).toBeInTheDocument(); + }); + it('should render loader if underlying in contract_info is falsy and contract is supported', () => { + default_mock_props.is_unsupported = false; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.getByText(PositionsCardLoader)).toBeInTheDocument(); + }); + it('should render specific contract card for Vanillas', () => { + default_mock_props.contract_info.underlying = 'test_underlying'; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.queryByText(PositionsCardLoader)).not.toBeInTheDocument(); + expect(screen.getByText(SymbolDisplayName)).toBeInTheDocument(); + expect(screen.getByText('CurrencyBadge')).toBeInTheDocument(); + expect(screen.getByText(/Buy price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,671.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Contract value:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,517.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Entry spot:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,666.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Strike:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,650.00/i)).toBeInTheDocument(); + expect(screen.getByText('ProgressSliderMobile')).toBeInTheDocument(); + expect(screen.getByText(/Total profit\/loss:/i)).toBeInTheDocument(); + expect(screen.getByText(/35.68/i)).toBeInTheDocument(); + }); + it('should render specific contract card for Turbos', () => { + default_mock_props.contract_info.contract_type = TURBOS.LONG; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.queryByText(PositionsCardLoader)).not.toBeInTheDocument(); + expect(screen.getByText(SymbolDisplayName)).toBeInTheDocument(); + expect(screen.getByText('Long')).toBeInTheDocument(); + expect(screen.getByText(/USD/i)).toBeInTheDocument(); + expect(screen.getByText(/Buy price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,671.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Contract value:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,517.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Entry spot:/i)).toBeInTheDocument(); + expect(screen.getByText(/0.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Take profit:/i)).toBeInTheDocument(); + expect(screen.getByText(/-/i)).toBeInTheDocument(); + expect(screen.getByText(/Barrier:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,650/i)).toBeInTheDocument(); + }); + it('should render contract card for Rise/Fall', () => { + default_mock_props.contract_info.contract_type = 'rise_fall'; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.queryByText(PositionsCardLoader)).not.toBeInTheDocument(); + expect(screen.getByText(SymbolDisplayName)).toBeInTheDocument(); + expect(screen.getByText(/USD/i)).toBeInTheDocument(); + expect(screen.getByText(/Potential profit\/loss:/i)).toBeInTheDocument(); + expect(screen.getByText(/Indicative price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,517.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Buy price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,671.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Payout limit:/i)).toBeInTheDocument(); + }); + it('should render the same contract card for Touch/No Touch as for Rise/Fall', () => { + default_mock_props.contract_info.contract_type = 'touch'; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.queryByText(PositionsCardLoader)).not.toBeInTheDocument(); + expect(screen.getByText(SymbolDisplayName)).toBeInTheDocument(); + expect(screen.getByText(/USD/i)).toBeInTheDocument(); + expect(screen.getByText(/Potential profit\/loss:/i)).toBeInTheDocument(); + expect(screen.getByText(/Indicative price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,517.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Buy price:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,671.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Payout limit:/i)).toBeInTheDocument(); + }); + it('should render the contract card for Multipliers', () => { + default_mock_props.contract_info.contract_type = 'multiplier'; + render(mockPositionsModalCard(mockStore(default_mock_store), default_mock_props)); + + expect(screen.queryByText(PositionsCardLoader)).not.toBeInTheDocument(); + expect(screen.getByText(SymbolDisplayName)).toBeInTheDocument(); + expect(screen.getByText(/USD/i)).toBeInTheDocument(); + expect(screen.getByText('Stake:')).toBeInTheDocument(); + expect(screen.getByText(/Current stake:/i)).toBeInTheDocument(); + expect(screen.getByText(/2,517.00/i)).toBeInTheDocument(); + expect(screen.getByText(/Deal cancel. fee:/i)).toBeInTheDocument(); + expect(screen.getByText(/Buy price:/i)).toBeInTheDocument(); + expect(screen.getByText(/Take profit:/i)).toBeInTheDocument(); + expect(screen.getByText(/Stop loss:/i)).toBeInTheDocument(); + expect(screen.getByText(/Total profit\/loss:/i)).toBeInTheDocument(); + }); +}); diff --git a/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.tsx b/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.tsx index 6156593e8baf..226b3ec9ddcb 100644 --- a/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.tsx +++ b/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.tsx @@ -1,7 +1,6 @@ import classNames from 'classnames'; import React from 'react'; import { NavLink } from 'react-router-dom'; -import { CSSTransition } from 'react-transition-group'; import { ContractCard, CurrencyBadge, Icon, Money, ProgressSliderMobile, Text } from '@deriv/components'; import { getContractPath, @@ -10,14 +9,11 @@ import { getSymbolDisplayName, getEndTime, getTotalProfit, - hasContractEntered, isAccumulatorContract, isCryptoContract, isMultiplierContract, isTurbosContract, - isHighLow, isCryptocurrency, - isOpen, isVanillaContract, } from '@deriv/shared'; import { localize } from '@deriv/translations'; @@ -45,11 +41,9 @@ type TPositionsModalCard = TPickPortfolioStore & current_tick?: React.ComponentProps['current_tick']; is_loading?: boolean; result?: React.ComponentProps['result']; - sell_price?: number; status?: string; togglePositions: TUiStore['togglePositionsDrawer']; toggleUnsupportedContractModal: TUiStore['toggleUnsupportedContractModal']; - type?: string; }; const PositionsModalCard = observer( @@ -60,7 +54,6 @@ const PositionsModalCard = observer( currency, current_tick, id, - indicative, is_loading, is_sell_requested, is_unsupported, @@ -68,11 +61,9 @@ const PositionsModalCard = observer( profit_loss, onClickCancel, result, - sell_price, status, togglePositions, toggleUnsupportedContractModal, - type, }: TPositionsModalCard) => { const { ui, common, contract_trade } = useStore(); const { active_symbols } = useTraderStore(); @@ -102,151 +93,15 @@ const PositionsModalCard = observer( const fallback_result = profit_loss >= 0 ? 'won' : 'lost'; const total_profit = getTotalProfit(contract_info); - const should_show_sell = hasContractEntered(contract_info) && isOpen(contract_info); const display_name = getSymbolDisplayName( active_symbols, getMarketInformation(contract_info.shortcode || '').underlying ); - const contract_options_el = ( - -
-
- - - {contract_info.display_name} - -
-
- -
- -
- -
-
-
- -
-
-
- {result ? localize('Profit/Loss:') : localize('Potential profit/loss:')} -
-
- {!result ? localize('Indicative price:') : localize('Payout:')} -
-
0, - })} - > - -
- {status === 'profit' && } - {status === 'loss' && } -
-
-
- -
- {status === 'profit' && } - {status === 'loss' && } -
-
-
-
-
- - {localize('Purchase price:')} - - - - -
-
- - {localize('Potential payout:')} - - - {contract_info.payout ? ( - - ) : ( - -i - )} - -
-
- - {result || !!contract_info.is_sold ? ( - - ) : ( - - )} -
-
- ); - const contract_vanilla_el = ( 0 && !result, - 'dc-contract-card--red': profit_loss < 0 && !result, - })} + className='positions-modal-card' to={{ pathname: `/contract/${contract_info.contract_id}`, }} @@ -404,7 +259,7 @@ const PositionsModalCard = observer( /> ); - const custom_contract_el = ( + const common_contract_el = ( ); - const options_el = is_vanilla ? contract_vanilla_el : contract_options_el; - const contract_el = is_multiplier || is_accumulator || is_turbos ? custom_contract_el : options_el; + const contract_el = is_vanilla ? contract_vanilla_el : common_contract_el; return (
@@ -436,8 +290,10 @@ const PositionsModalCard = observer( 0 && !is_multiplier, + 'dc-contract-card--red': profit_loss < 0 && !is_multiplier, })} to={getContractPath(id)} >