diff --git a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.jsx b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.jsx index e437a51bba9e..53867aeb7541 100644 --- a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.jsx +++ b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.jsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; import { CSSTransition } from 'react-transition-group'; -import { isHighLow, getCurrentTick, isBot } from '@deriv/shared'; +import { isHighLow, getCurrentTick, getGrowthRatePercentage, isBot } from '@deriv/shared'; import ContractTypeCell from './contract-type-cell.jsx'; import Button from '../../button'; import Icon from '../../icon'; @@ -40,6 +40,9 @@ const ContractCardHeader = ({ } = contract_info; const is_sold = !!contract_info.is_sold || is_contract_sold; const is_accumulator = contract_type === 'ACCU'; + const displayed_accumulator = growth_rate && `${getGrowthRatePercentage(growth_rate)}%`; + const displayed_multiplier = multiplier && `x${multiplier}`; + const displayed_trade_param = is_accumulator ? displayed_accumulator : displayed_multiplier; return ( <> @@ -55,12 +58,16 @@ const ContractCardHeader = ({ {display_name || contract_info.display_name} -
+
diff --git a/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.jsx b/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.jsx index 5b2866f18a45..9954ebbd2f64 100644 --- a/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.jsx +++ b/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.jsx @@ -1,11 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import IconTradeTypes from '../../icon-trade-types'; -import { getGrowthRatePercentage } from '@deriv/shared'; -import classNames from 'classnames'; -const ContractTypeCell = ({ getContractTypeDisplay, growth_rate, is_high_low, multiplier, type }) => ( -
+const ContractTypeCell = ({ displayed_trade_param, getContractTypeDisplay, is_high_low, type }) => ( +
{getContractTypeDisplay(type, is_high_low) || ''}
- {(multiplier || growth_rate) && ( -
- {multiplier ? `x${multiplier}` : `${getGrowthRatePercentage(growth_rate)}%`} -
+ {displayed_trade_param && ( +
{displayed_trade_param}
)}
); ContractTypeCell.propTypes = { + displayed_trade_param: PropTypes.string, getContractTypeDisplay: PropTypes.func, is_high_low: PropTypes.bool, - multiplier: PropTypes.number, type: PropTypes.string, }; diff --git a/packages/components/src/components/contract-card/contract-card.scss b/packages/components/src/components/contract-card/contract-card.scss index 4ae5dd10d12a..c90113fa78a4 100644 --- a/packages/components/src/components/contract-card/contract-card.scss +++ b/packages/components/src/components/contract-card/contract-card.scss @@ -215,6 +215,24 @@ fill: var(--brand-secondary) !important; } } + &--accumulators { + @include mobile { + justify-content: flex-end; + + .dc-contract-type__type { + &-label { + width: fit-content; + } + &-wrapper { + padding: 0.5em 0.8em 0.5em 0.3em; + } + } + } + .dc-contract-type__type-wrapper .category-type { + width: unset; + height: unset; + } + } } &__symbol { margin-left: 0.4rem; @@ -532,7 +550,6 @@ /** @define dc-contract-type */ .dc-contract-type { - $self: &; display: flex; flex-direction: row; align-items: center; @@ -563,21 +580,6 @@ color: var(--text-less-prominent); } } - &--accumulators { - @include mobile { - #{$self}__type-label { - width: 5.5rem; - } - #{$self}__type-wrapper { - padding: 0.5em 0.8em 0.5em 0.3em; - - .category-type { - width: unset; - height: unset; - } - } - } - } } /** @define dc-btn; */ diff --git a/packages/trader/src/Modules/Trading/Components/Form/TradeParams/Accumulator/__tests__/accumulator.spec.js b/packages/trader/src/Modules/Trading/Components/Form/TradeParams/Accumulator/__tests__/accumulator.spec.js new file mode 100644 index 000000000000..7083b6a810d3 --- /dev/null +++ b/packages/trader/src/Modules/Trading/Components/Form/TradeParams/Accumulator/__tests__/accumulator.spec.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import Accumulator from '../accumulator'; + +const mock_connect_props = { + accumulator_rates_list: [0.01, 0.02, 0.03, 0.04, 0.05], + onChange: jest.fn(), + growth_rate: 0.01, + tick_size_barrier: 0.000409, +}; + +jest.mock('Stores/connect.js', () => ({ + __esModule: true, + default: 'mockedDefaultExport', + connect: () => Component => props => Component({ ...props, ...mock_connect_props }), +})); + +describe('Accumulator', () => { + it('should render with the initially selected 1% growth_rate', () => { + render(); + expect(screen.getByText('Accumulator')).toBeInTheDocument(); + expect(screen.getByText('1%')).toBeInTheDocument(); + expect(screen.getByText('2%')).toBeInTheDocument(); + expect(screen.getByText('3%')).toBeInTheDocument(); + expect(screen.getByText('4%')).toBeInTheDocument(); + expect(screen.getByText('5%')).toBeInTheDocument(); + + expect(screen.getByText('1%').getAttribute('class')).toContain('--selected'); + }); + + it('3% growth_rate should be selected when 0.03 is a currently selected and stored growth_rate value', async () => { + mock_connect_props.growth_rate = 0.03; + render(); + + expect(screen.getByText('3%').getAttribute('class')).toContain('--selected'); + expect(screen.getByText('1%').getAttribute('class')).not.toContain('--selected'); + }); +}); diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/__tests__/accumulator.js b/packages/trader/src/Stores/Modules/Trading/Helpers/__tests__/accumulator.js new file mode 100644 index 000000000000..3edceb6edac6 --- /dev/null +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/__tests__/accumulator.js @@ -0,0 +1,95 @@ +import { expect } from 'chai'; +import { getUpdatedTicksHistoryStats } from '../accumulator'; + +describe('getUpdatedTicksHistoryStats', () => { + const existing_ticks_history_stats = [ + { counter_value: 1, epoch: 1005 }, + { counter_value: 65, epoch: 1004 }, + { counter_value: 1234, epoch: 1003 }, + { counter_value: 675, epoch: 1002 }, + { counter_value: 234, epoch: 1001 }, + ]; + const new_ticks_history_stats = [ + { counter_value: 1573, epoch: 1006 }, + { counter_value: 33, epoch: 1007 }, + { counter_value: 423, epoch: 1008 }, + { counter_value: 2853, epoch: 1009 }, + { counter_value: 131, epoch: 1010 }, + ]; + const current_counter_same_value = { counter_value: 1, epoch: 1005 }; + const current_counter_new_value = { counter_value: 2, epoch: 1006 }; + const next_counter_initial_value = { counter_value: 0, epoch: 1006 }; + const next_counter_latest_value = { counter_value: 1, epoch: 1007 }; + + it('returns a reversed new_ticks_history_stats when new_ticks_history_stats is an array', () => { + const expected_array = [ + { counter_value: 131, epoch: 1010 }, + { counter_value: 2853, epoch: 1009 }, + { counter_value: 423, epoch: 1008 }, + { counter_value: 33, epoch: 1007 }, + { counter_value: 1573, epoch: 1006 }, + ]; + expect(getUpdatedTicksHistoryStats([], new_ticks_history_stats)).to.eql(expected_array); + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, new_ticks_history_stats)).to.eql( + expected_array + ); + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, new_ticks_history_stats)).to.not.eql( + existing_ticks_history_stats + ); + }); + + it('returns the same array when new_ticks_history_stats is undefined', () => { + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats)).to.eql(existing_ticks_history_stats); + }); + + it('returns the same array of objects when received a new_ticks_history_stats object containing the same value of the current counter', () => { + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, current_counter_same_value)).to.eql( + existing_ticks_history_stats + ); + }); + + it('returns a new array of objects with first item replaced with a new_ticks_history_stats object containing a current counter new value', () => { + const expected_array = [ + { counter_value: 2, epoch: 1006 }, + { counter_value: 65, epoch: 1004 }, + { counter_value: 1234, epoch: 1003 }, + { counter_value: 675, epoch: 1002 }, + { counter_value: 234, epoch: 1001 }, + ]; + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, current_counter_new_value)).to.eql( + expected_array + ); + }); + + it('returns a shifted array of the same length with new_ticks_history_stats object placed as 1st item when its a counter_value < a previous counter_value & an epoch > a previous epoch', () => { + const expected_array = [ + { counter_value: 0, epoch: 1006 }, + { counter_value: 1, epoch: 1005 }, + { counter_value: 65, epoch: 1004 }, + { counter_value: 1234, epoch: 1003 }, + { counter_value: 675, epoch: 1002 }, + ]; + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, next_counter_initial_value)).to.eql( + expected_array + ); + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, next_counter_initial_value)).to.have.lengthOf( + existing_ticks_history_stats.length + ); + }); + + it('returns a shifted array of the same length with new_ticks_history_stats object placed as 1st item when its a counter_value === a previous counter_value & an epoch > a previous epoch', () => { + const expected_array = [ + { counter_value: 1, epoch: 1007 }, + { counter_value: 1, epoch: 1005 }, + { counter_value: 65, epoch: 1004 }, + { counter_value: 1234, epoch: 1003 }, + { counter_value: 675, epoch: 1002 }, + ]; + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, next_counter_latest_value)).to.eql( + expected_array + ); + expect(getUpdatedTicksHistoryStats(existing_ticks_history_stats, next_counter_latest_value)).to.have.lengthOf( + existing_ticks_history_stats.length + ); + }); +}); diff --git a/packages/trader/src/Stores/Modules/Trading/Helpers/accumulator.js b/packages/trader/src/Stores/Modules/Trading/Helpers/accumulator.js index 0e5e683856bb..0b5fbef08381 100644 --- a/packages/trader/src/Stores/Modules/Trading/Helpers/accumulator.js +++ b/packages/trader/src/Stores/Modules/Trading/Helpers/accumulator.js @@ -5,13 +5,16 @@ * @returns an array of 100 objects of type: { counter_value: number, epoch: number } starting with the latest counter. */ export const getUpdatedTicksHistoryStats = (ticks_history_stats = [], new_ticks_history_stats = []) => { - // we anticipate that the latest counter object will be the last one in the array: - if (Array.isArray(new_ticks_history_stats)) return [...new_ticks_history_stats].reverse(); + // we anticipate that the latest counter object will be the last one in the received new_ticks_history_stats array: + if (Array.isArray(new_ticks_history_stats)) + return new_ticks_history_stats.length ? [...new_ticks_history_stats].reverse() : ticks_history_stats; else if ( new_ticks_history_stats.counter_value <= ticks_history_stats[0].counter_value && new_ticks_history_stats.epoch > ticks_history_stats[0].epoch ) { return [new_ticks_history_stats, ...ticks_history_stats.slice(0, ticks_history_stats.length - 1)]; + } else if (new_ticks_history_stats.epoch === ticks_history_stats[0].epoch) { + return ticks_history_stats; } return [new_ticks_history_stats, ...ticks_history_stats.slice(1)]; };