Skip to content

Commit

Permalink
Shayan | Niloofar | Ameerul / currency issue in the withdrawal crypto…
Browse files Browse the repository at this point in the history
… form (#11665)

* Revert "Revert "Shayan/P2PS-1753/refactor exchange rates hook (#11034)" (#11666)"

This reverts commit 35062e9.

* fix: currency issue in the withdrawal crypto form

* test: fix tests

* fix: add fallback value for current_fiat_currency

* chore: removed unused CookieStorage

---------

Co-authored-by: Ali(Ako) Hosseini <ali.hosseini@deriv.com>
Co-authored-by: shayan khaleghparast <iman@regentmarkets.com>
  • Loading branch information
3 people committed Nov 29, 2023
1 parent 3af6f97 commit 6f36228
Show file tree
Hide file tree
Showing 44 changed files with 488 additions and 403 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isDesktop, isMobile } from '@deriv/shared';
import { splitValidationResultTypes } from '../../real-account-signup/helpers/utils';
import PersonalDetails from '../personal-details';
import { shouldShowIdentityInformation, isDocumentTypeValid, isAdditionalDocumentValid } from 'Helpers/utils';
import { StoreProvider, mockStore } from '@deriv/stores';
import { StoreProvider, mockStore, ExchangeRatesProvider } from '@deriv/stores';

jest.mock('Assets/ic-poi-name-dob-example.svg', () => jest.fn(() => 'PoiNameDobExampleImage'));

Expand Down Expand Up @@ -289,7 +289,9 @@ describe('<PersonalDetails/>', () => {
const mock_store = mockStore({});
render(
<StoreProvider store={mock_store}>
<BrowserRouter>{component}</BrowserRouter>
<ExchangeRatesProvider>
<BrowserRouter>{component}</BrowserRouter>
</ExchangeRatesProvider>
</StoreProvider>
);
};
Expand Down
6 changes: 4 additions & 2 deletions packages/appstore/src/components/app.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import CashierStoreProvider from '@deriv/cashier/src/cashier-providers';
import CFDStoreProvider from '@deriv/cfd/src/cfd-providers';
import { StoreProvider } from '@deriv/stores';
import { StoreProvider, ExchangeRatesProvider } from '@deriv/stores';
import AppContent from './app-content';
import './app.scss';

Expand All @@ -15,7 +15,9 @@ const App: React.FC<TProps> = ({ passthrough: { root_store } }) => (
<CashierStoreProvider store={root_store}>
<CFDStoreProvider store={root_store}>
<StoreProvider store={root_store}>
<AppContent />
<ExchangeRatesProvider>
<AppContent />
</ExchangeRatesProvider>
</StoreProvider>
</CFDStoreProvider>
</CashierStoreProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { StoreProvider, mockStore } from '@deriv/stores';
import { StoreProvider, mockStore, ExchangeRatesProvider } from '@deriv/stores';
import { APIProvider /*useFetch*/ } from '@deriv/api';
import MainTitleBar from '..';

Expand Down Expand Up @@ -58,7 +58,9 @@ describe('MainTitleBar', () => {
const mock_store = mockStore({ feature_flags: { data: { wallet: false } } });
const wrapper = ({ children }: React.PropsWithChildren) => (
<APIProvider>
<StoreProvider store={mock_store_override ?? mock_store}>{children}</StoreProvider>
<StoreProvider store={mock_store_override ?? mock_store}>
<ExchangeRatesProvider>{children}</ExchangeRatesProvider>
</StoreProvider>
</APIProvider>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ const AssetSummary = observer(() => {
const { current_language } = common;
const { real: platform_real_accounts, demo: platform_demo_account } = usePlatformAccounts();
const { real: cfd_real_accounts, demo: cfd_demo_accounts } = useCFDAccounts();

const platform_real_balance = useTotalAccountBalance(platform_real_accounts);
const cfd_real_balance = useTotalAccountBalance(cfd_real_accounts);
const cfd_demo_balance = useTotalAccountBalance(cfd_demo_accounts);

const is_real = selected_account_type === 'real';

const real_total_balance = platform_real_balance.balance + cfd_real_balance.balance;
const demo_total_balance = (platform_demo_account?.balance || 0) + cfd_demo_balance.balance;

Expand Down
15 changes: 9 additions & 6 deletions packages/appstore/src/modules/traders-hub/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import React from 'react';
import { DesktopWrapper, MobileWrapper, ButtonToggle, Div100vhContainer, Text } from '@deriv/components';
import { isDesktop, routes, ContentFlag } from '@deriv/shared';
Expand Down Expand Up @@ -61,7 +62,7 @@ const TradersHub = observer(() => {
};
if (!is_logged_in) return null;

const renderOrderedPlatformSections = (is_cfd_visible = true, is_options_and_multipliers_visible = true) => {
const OrderedPlatformSections = ({ is_cfd_visible = true, is_options_and_multipliers_visible = true }) => {
return (
<div
data-testid='dt_traders_hub'
Expand All @@ -87,7 +88,9 @@ const TradersHub = observer(() => {
{can_show_notify && <Notifications />}
<div id='traders-hub' className='traders-hub' ref={traders_hub_ref}>
<MainTitleBar />
<DesktopWrapper>{renderOrderedPlatformSections()}</DesktopWrapper>
<DesktopWrapper>
<OrderedPlatformSections />
</DesktopWrapper>
<MobileWrapper>
{is_landing_company_loaded ? (
<ButtonToggle
Expand All @@ -102,10 +105,10 @@ const TradersHub = observer(() => {
) : (
<ButtonToggleLoader />
)}
{renderOrderedPlatformSections(
selected_platform_type === 'cfd',
selected_platform_type === 'options'
)}
<OrderedPlatformSections
is_cfd_visible={selected_platform_type === 'cfd'}
is_options_and_multipliers_visible={selected_platform_type === 'options'}
/>
</MobileWrapper>
<ModalManager />
{scrolled && <TourGuide />}
Expand Down
5 changes: 4 additions & 1 deletion packages/cashier/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import AppContent from './app-content';
import CashierProviders from './cashier-providers';
import { ExchangeRatesProvider } from '@deriv/stores';

type TProps = { passthrough: { root_store: React.ComponentProps<typeof CashierProviders>['store'] } };

const App: React.FC<TProps> = ({ passthrough: { root_store } }) => {
return (
<CashierProviders store={root_store}>
<AppContent />
<ExchangeRatesProvider>
<AppContent />
</ExchangeRatesProvider>
</CashierProviders>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import CryptoFiatConverter from '../crypto-fiat-converter';
import { Formik } from 'formik';
import * as formik from 'formik';
import CashierProviders from '../../../cashier-providers';
import { mockStore } from '@deriv/stores';
import { mockStore, ExchangeRatesProvider } from '@deriv/stores';

describe('<CryptoFiatConverter />', () => {
let mockRootStore: ReturnType<typeof mockStore>, mockProps: React.ComponentProps<typeof CryptoFiatConverter>;
Expand All @@ -16,19 +16,20 @@ describe('<CryptoFiatConverter />', () => {
crypto_fiat_converter: {
converter_from_amount: '100',
converter_to_amount: '200',
is_timer_visible: true,
},
},
},
});

mockProps = {
arrow_icon_direction: 'right',
from_currency: 'BTC',
hint: 'Transfer limits',
resetConverter: jest.fn(),
to_currency: 'USD',
onChangeConverterFromAmount: jest.fn(),
onChangeConverterToAmount: jest.fn(),
setArrowIconDirection: jest.fn(),
validateFromAmount: jest.fn(),
validateToAmount: jest.fn(),
};
Expand All @@ -37,9 +38,11 @@ describe('<CryptoFiatConverter />', () => {
const renderCryptoFiatConverter = () => {
return render(
<CashierProviders store={mockRootStore}>
<Formik initialValues={{}} onSubmit={() => Promise.resolve()}>
<CryptoFiatConverter {...mockProps} />
</Formik>
<ExchangeRatesProvider>
<Formik initialValues={{}} onSubmit={() => Promise.resolve()}>
<CryptoFiatConverter {...mockProps} />
</Formik>
</ExchangeRatesProvider>
</CashierProviders>
);
};
Expand All @@ -51,17 +54,6 @@ describe('<CryptoFiatConverter />', () => {
expect(screen.getByText('Amount (USD)')).toBeInTheDocument();
expect(screen.getByText('Transfer limits')).toBeInTheDocument();
expect(screen.getByText('Approximate value')).toBeInTheDocument();
expect(screen.getByText('60s')).toBeInTheDocument();
});

it('should change arrow direction when the focus changes between inputs', () => {
renderCryptoFiatConverter();

const [converter_from_amount_input, converter_to_amount_input] = screen.getAllByRole('textbox');
converter_from_amount_input.focus();
expect(screen.getByTestId('dti_arrow_right_bold')).toBeInTheDocument();
converter_to_amount_input.focus();
expect(screen.getByTestId('dti_arrow_left_bold')).toBeInTheDocument();
});

it('"converter_from_amount" and "converter_to_amount" inputs should show the proper values', () => {
Expand All @@ -74,6 +66,13 @@ describe('<CryptoFiatConverter />', () => {
});

it('should trigger onChange callback when the input field changes', () => {
const mockJson = {
BTC: {
USD: 2.2,
},
};
window.localStorage.setItem('exchange_rates', JSON.stringify(mockJson));

const use_formik_context = jest.spyOn(formik, 'useFormikContext') as any;
use_formik_context.mockReturnValueOnce({ handleChange: jest.fn() });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react';
import { Field, FieldProps, useFormikContext } from 'formik';
import { DesktopWrapper, Input, Icon, MobileWrapper, Text, useInterval } from '@deriv/components';

import { DesktopWrapper, Icon, Input, MobileWrapper, Text, useInterval } from '@deriv/components';
import { useExchangeRate } from '@deriv/hooks';
import { getCurrencyDisplayCode } from '@deriv/shared';
import { localize, Localize } from '@deriv/translations';
import { observer } from '@deriv/stores';
import { TReactChangeEvent } from '../../types';
import { Localize, localize } from '@deriv/translations';

import { useCashierStore } from '../../stores/useCashierStores';
import { useExchangeRate } from '@deriv/hooks';
import { TReactChangeEvent } from '../../types';

import './crypto-fiat-converter.scss';

type TTimerProps = {
Expand All @@ -18,6 +21,7 @@ type TInputGroupProps = React.PropsWithChildren<{
}>;

type TCryptoFiatConverterProps = {
arrow_icon_direction: 'right' | 'left';
from_currency: string;
hint?: React.ReactNode;
onChangeConverterFromAmount: (
Expand All @@ -33,6 +37,7 @@ type TCryptoFiatConverterProps = {
converted_amount?: number
) => void;
resetConverter: VoidFunction;
setArrowIconDirection: React.Dispatch<React.SetStateAction<'right' | 'left'>>;
to_currency: string;
validateFromAmount: VoidFunction;
validateToAmount: VoidFunction;
Expand Down Expand Up @@ -72,28 +77,24 @@ const InputGroup = ({ children, className }: TInputGroupProps) => {

const CryptoFiatConverter = observer(
({
arrow_icon_direction,
from_currency,
hint,
onChangeConverterFromAmount,
onChangeConverterToAmount,
resetConverter,
setArrowIconDirection,
to_currency,
validateFromAmount,
validateToAmount,
}: TCryptoFiatConverterProps) => {
const { crypto_fiat_converter } = useCashierStore();
const { getRate } = useExchangeRate();
const { exchange_rates } = useExchangeRate();

const {
converter_from_amount,
converter_from_error,
converter_to_error,
converter_to_amount,
is_timer_visible,
} = crypto_fiat_converter;
const { converter_from_amount, converter_from_error, converter_to_error, converter_to_amount } =
crypto_fiat_converter;

const { handleChange } = useFormikContext();
const [arrow_icon_direction, setArrowIconDirection] = React.useState<string>('right');

React.useEffect(() => {
return () => resetConverter();
Expand All @@ -115,9 +116,8 @@ const CryptoFiatConverter = observer(
setArrowIconDirection('right');
}}
onChange={(e: TReactChangeEvent) => {
const from_rate = getRate(from_currency || '');
const to_rate = getRate(to_currency || '');
const converted_amount = (Number(e.target.value) * to_rate) / from_rate;
const rate = exchange_rates?.[from_currency]?.[to_currency] ?? 1;
const converted_amount = Number(e.target.value) * rate;
onChangeConverterFromAmount(e, from_currency, to_currency, converted_amount);
handleChange(e);
}}
Expand Down Expand Up @@ -154,9 +154,8 @@ const CryptoFiatConverter = observer(
setArrowIconDirection('left');
}}
onChange={(e: TReactChangeEvent) => {
const from_rate = getRate(from_currency || '');
const to_rate = getRate(to_currency || '');
const converted_amount = (Number(e.target.value) * from_rate) / to_rate;
const rate = exchange_rates?.[to_currency]?.[from_currency] ?? 1;
const converted_amount = Number(e.target.value) * rate;
onChangeConverterToAmount(e, to_currency, from_currency, converted_amount);
handleChange(e);
}}
Expand All @@ -171,21 +170,6 @@ const CryptoFiatConverter = observer(
classNameHint='crypto-fiat-converter__hint'
data-testid='dt_converter_to_amount_input'
/>
{is_timer_visible && (
<Timer
onComplete={() => {
const from_rate = getRate(from_currency || '');
const to_rate = getRate(to_currency || '');
const converted_amount = (Number(converter_from_amount) * to_rate) / from_rate;
onChangeConverterFromAmount(
{ target: { value: converter_from_amount } },
from_currency,
to_currency,
converted_amount
);
}}
/>
)}
</InputGroup>
)}
</Field>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import PercentageSelector from '../percentage-selector';
import { mockStore } from '@deriv/stores';
import { mockStore, ExchangeRatesProvider } from '@deriv/stores';
import CashierProviders from '../../../cashier-providers';
import CryptoFiatConverter from '../../crypto-fiat-converter';

Expand Down Expand Up @@ -34,7 +34,9 @@ describe('<PercentageSelector />', () => {
it('should render the component', () => {
render(
<CashierProviders store={mockRootStore}>
<PercentageSelector {...percentage_selector_props} />
<ExchangeRatesProvider>
<PercentageSelector {...percentage_selector_props} />
</ExchangeRatesProvider>
</CashierProviders>
);

Expand All @@ -44,7 +46,9 @@ describe('<PercentageSelector />', () => {
it('should calculate the percentage amount on click of percentage block', () => {
render(
<CashierProviders store={mockRootStore}>
<PercentageSelector {...percentage_selector_props} />
<ExchangeRatesProvider>
<PercentageSelector {...percentage_selector_props} />
</ExchangeRatesProvider>
</CashierProviders>
);

Expand All @@ -64,7 +68,9 @@ describe('<PercentageSelector />', () => {
it('should reset the percentage block upon clicking twice', () => {
render(
<CashierProviders store={mockRootStore}>
<PercentageSelector {...percentage_selector_props} />
<ExchangeRatesProvider>
<PercentageSelector {...percentage_selector_props} />
</ExchangeRatesProvider>
</CashierProviders>
);

Expand Down Expand Up @@ -92,7 +98,9 @@ describe('<PercentageSelector />', () => {
it('should reset the percentage', () => {
render(
<CashierProviders store={mockRootStore}>
<PercentageSelector {...percentage_selector_props} should_percentage_reset />
<ExchangeRatesProvider>
<PercentageSelector {...percentage_selector_props} should_percentage_reset />
</ExchangeRatesProvider>
</CashierProviders>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const PercentageSelector = ({
to_currency,
}: TPercentageSelectorProps) => {
const [selected_percentage, setSelectedPercentage] = React.useState<number | string>('0');
const { getRate } = useExchangeRate();
const { exchange_rates } = useExchangeRate();
React.useEffect(() => {
if (should_percentage_reset) {
for (let i = 1; i <= 4; i++) {
Expand All @@ -55,9 +55,9 @@ const PercentageSelector = ({
if (is_percentage_selected) new_percentage -= 25;

setSelectedPercentage(new_percentage || 0);
const from_rate = getRate(from_currency || '');
const to_rate = getRate(to_currency || '');
const converted_amount = (amount * (new_percentage / 100) * to_rate) / from_rate;
const rate = exchange_rates?.[from_currency]?.[to_currency] ?? 1;
const converted_amount = amount * (new_percentage / 100) * rate;

getCalculatedAmount(
(amount * (new_percentage / 100)).toFixed(getDecimalPlaces(from_currency)),
converted_amount
Expand Down
Loading

1 comment on commit 6f36228

@vercel
Copy link

@vercel vercel bot commented on 6f36228 Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

deriv-app – ./

binary.sx
deriv-app.vercel.app
deriv-app-git-master.binary.sx
deriv-app.binary.sx

Please sign in to comment.