Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:binary-com/deriv-app into fix-pa…
Browse files Browse the repository at this point in the history
…rent
  • Loading branch information
jim-deriv committed Nov 9, 2022
2 parents 9168825 + 228635c commit b9d0f49
Show file tree
Hide file tree
Showing 38 changed files with 433 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,12 @@ const AccountLimits = ({
<Localize i18n_default_text='*Maximum account cash balance' />
</AccountLimitsTableCell>
<AccountLimitsTableCell align='right'>
{formatMoney(currency, account_balance, true)}
{/* null or 0 are expected form BE when max balance limit is not set */}
{account_balance ? (
formatMoney(currency, account_balance, true)
) : (
<Localize i18n_default_text='Not set' />
)}
</AccountLimitsTableCell>
</tr>
<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,28 +306,17 @@ describe('<ApiToken/>', () => {

fireEvent.click(copy_btns_1[0]);
expect(screen.queryByText(warning_msg)).not.toBeInTheDocument();
expect(await screen.findByTestId('dt_token_copied_icon')).toBeInTheDocument();

act(() => jest.advanceTimersByTime(2100));
expect(screen.queryByTestId('dt_token_copied_icon')).not.toBeInTheDocument();

fireEvent.click(copy_btns_1[1]);
expect(await screen.findByText(warning_msg)).toBeInTheDocument();

expect(document.execCommand).toHaveBeenCalledTimes(1);

const ok_btn = screen.getByRole('button', { name: /ok/i });
expect(ok_btn).toBeInTheDocument();

fireEvent.click(ok_btn);
expect(await screen.findByTestId('dt_token_copied_icon')).toBeInTheDocument();
const copy_btns_2 = await screen.findAllByTestId('dt_copy_token_icon');
expect(copy_btns_2.length).toBe(1);

act(() => jest.advanceTimersByTime(2100));
expect(screen.queryByTestId('dt_token_copied_icon')).not.toBeInTheDocument();

expect(document.execCommand).toHaveBeenCalledTimes(2);

jest.clearAllMocks();
});
Expand Down
15 changes: 3 additions & 12 deletions packages/account/src/Components/api-token/api-token-clipboard.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useIsMounted } from '@deriv/shared';
import { Button, Icon, Modal, Text, Popover } from '@deriv/components';
import { Button, Icon, Modal, Text, Popover, useCopyToClipboard } from '@deriv/components';
import { localize } from '@deriv/translations';

const WarningNoteBullet = ({ message }) => (
Expand Down Expand Up @@ -29,7 +29,7 @@ const WarningDialogMessage = () => (
);

const ApiTokenClipboard = ({ scopes, text_copy, info_message, success_message, popover_alignment = 'bottom' }) => {
const [is_copied, setIsCopied] = React.useState(false);
const [is_copied, copyToClipboard, setIsCopied] = useCopyToClipboard();
const [is_modal_open, setIsModalOpen] = React.useState(false);
const [is_popover_open, setIsPopoverOpen] = React.useState(false);
const isMounted = useIsMounted();
Expand All @@ -45,27 +45,18 @@ const ApiTokenClipboard = ({ scopes, text_copy, info_message, success_message, p
if (!is_copied) setIsPopoverOpen(false);
};

const copyToClipboard = text => {
const textField = document.createElement('textarea');
textField.innerText = text;
document.body.appendChild(textField);
textField.select();
document.execCommand('copy');
textField.remove();
};

/* two timeouts help to prevent popup window blinking.
without early hiding the popup we will see shortly the description message like during hovering.
this bug appears when popup is handled outside like here
*/
const onClick = () => {
setIsModalOpen(false);
copyToClipboard(text_copy);
setIsCopied(true);
setIsPopoverOpen(true);
timeout_clipboard = setTimeout(() => {
if (isMounted()) {
setIsPopoverOpen(false);
setIsCopied(false);
}
}, 1900);
timeout_clipboard_2 = setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ describe('<OnRampProviderPopup />', () => {
api_error: '',
deposit_address: 'tb1qhux20f7h42ya9nqdntl6r9p7p264a2ct8t3n6p',
is_deposit_address_loading: false,
is_deposit_address_popover_open: false,
is_requesting_widget_html: false,
selected_provider: {
name: 'Changelly',
Expand All @@ -29,7 +28,6 @@ describe('<OnRampProviderPopup />', () => {
should_show_widget: false,
widget_error: '',
widget_html: 'Widget HTML',
onClickCopyDepositAddress: jest.fn(),
onClickDisclaimerContinue: jest.fn(),
onClickGoToDepositPage: jest.fn(),
setIsOnRampModalOpen: jest.fn(),
Expand Down Expand Up @@ -112,28 +110,13 @@ describe('<OnRampProviderPopup />', () => {
expect(screen.getByRole('button', { name: 'Continue' })).toBeInTheDocument();
});

it('should trigger onClick callback when the user clicks on copy icon', () => {
render(<OnRampProviderPopup {...props} />);

const copy_icon = screen.getByTestId('dti_deposit_address_icon');
fireEvent.click(copy_icon);

expect(props.onClickCopyDepositAddress).toHaveBeenCalledTimes(1);
});

it('should trigger onFocus method when the user clicks on deposit address field', () => {
render(<OnRampProviderPopup {...props} />);

const deposit_address_input = screen.getByRole('textbox');
expect(fireEvent.focus(deposit_address_input)).toBeTruthy();
});

it('should show "Copied!" message', () => {
render(<OnRampProviderPopup {...props} is_deposit_address_popover_open />);

expect(screen.getByText('Copied!')).toBeInTheDocument();
});

it('should trigger onClick calbacks when the user clicks on "Cancel" and "Continue" buttons', () => {
const { rerender } = render(<OnRampProviderPopup {...props} />);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import React from 'react';
import { Button, HintBox, Icon, Loading, Popover, Text } from '@deriv/components';
import { Button, HintBox, Icon, Loading, Popover, Text, useCopyToClipboard } from '@deriv/components';
import { getKebabCase, website_name, isMobile } from '@deriv/shared';
import { localize, Localize } from '@deriv/translations';
import { connect } from 'Stores/connect';
Expand All @@ -11,13 +11,10 @@ type TOnRampProviderPopupProps = {
deposit_address: string;
is_dark_mode_on: TUiStore['is_dark_mode_on'];
is_deposit_address_loading: boolean;
is_deposit_address_popover_open: boolean;
is_requesting_widget_html: boolean;
onClickCopyDepositAddress: () => void;
onClickDisclaimerContinue: () => void;
onClickGoToDepositPage: () => void;
selected_provider: TProviderDetails;
setDepositAddressRef: (ref: HTMLDivElement | null) => void;
setIsOnRampModalOpen: (boolean: boolean) => void;
should_show_dialog: boolean;
should_show_widget: boolean;
Expand All @@ -30,20 +27,31 @@ const OnRampProviderPopup = ({
deposit_address,
is_dark_mode_on,
is_deposit_address_loading,
is_deposit_address_popover_open,
is_requesting_widget_html,
onClickCopyDepositAddress,
onClickDisclaimerContinue,
onClickGoToDepositPage,
selected_provider,
setDepositAddressRef,
setIsOnRampModalOpen,
should_show_dialog,
should_show_widget,
widget_error,
widget_html,
}: TOnRampProviderPopupProps) => {
const el_onramp_widget_container_ref = React.useRef(null);
const [is_copied, copyToClipboard, setIsCopied] = useCopyToClipboard();
let timeout_clipboard: ReturnType<typeof setTimeout>;

const onClickCopyDepositAddress = () => {
copyToClipboard(deposit_address);

timeout_clipboard = setTimeout(() => {
setIsCopied(false);
}, 500);
};

React.useEffect(() => {
return () => clearTimeout(timeout_clipboard);
}, []);

// JS executed after "on-ramp__widget-container" has been added to the DOM.
// Used for providers that require JS to be executed for inclusion of their widget.
Expand Down Expand Up @@ -111,17 +119,11 @@ const OnRampProviderPopup = ({
<Localize i18n_default_text="Please copy the crypto address you see below. You'll need it to deposit your cryptocurrency." />
</Text>
<div className='on-ramp__popup-deposit-address'>
<Popover
zIndex={9998}
alignment='right'
message={localize('Copied!')}
is_open={is_deposit_address_popover_open}
>
<Popover zIndex={9998} alignment='right' message={localize('Copied!')} is_open={is_copied}>
<input
className={classNames('on-ramp__popup-deposit-address-text', {
'on-ramp__popup-deposit-address-text--dark': is_dark_mode_on,
})}
ref={setDepositAddressRef}
defaultValue={deposit_address}
disabled
onFocus={e => e.preventDefault()}
Expand Down Expand Up @@ -197,13 +199,10 @@ export default connect(({ modules, ui }: TRootStore) => ({
deposit_address: modules.cashier.onramp.deposit_address,
is_dark_mode_on: ui.is_dark_mode_on,
is_deposit_address_loading: modules.cashier.onramp.is_deposit_address_loading,
is_deposit_address_popover_open: modules.cashier.onramp.is_deposit_address_popover_open,
is_requesting_widget_html: modules.cashier.onramp.is_requesting_widget_html,
onClickCopyDepositAddress: modules.cashier.onramp.onClickCopyDepositAddress,
onClickDisclaimerContinue: modules.cashier.onramp.onClickDisclaimerContinue,
onClickGoToDepositPage: modules.cashier.onramp.onClickGoToDepositPage,
selected_provider: modules.cashier.onramp.selected_provider,
setDepositAddressRef: modules.cashier.onramp.setDepositAddressRef,
setIsOnRampModalOpen: modules.cashier.onramp.setIsOnRampModalOpen,
should_show_dialog: modules.cashier.onramp.should_show_dialog,
should_show_widget: modules.cashier.onramp.should_show_widget,
Expand Down
42 changes: 0 additions & 42 deletions packages/cashier/src/stores/__tests__/on-ramp-store.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,35 +164,6 @@ describe('OnRampStore', () => {
// expect(spyDisposeGetWidgetHtmlReaction).toBeCalledTimes(1);
// });

// it('should show and hide deposit address popover when deposit address is copied', async () => {
// jest.useFakeTimers();
// jest.spyOn(document, 'createRange').mockImplementation(() => ({
// selectNodeContents: jest.fn(),
// }));
// jest.spyOn(window, 'window', 'get').mockImplementation(() => ({
// getSelection: () => ({
// addRange: jest.fn(),
// removeAllRanges: jest.fn(),
// }),
// }));
// Object.assign(navigator, {
// clipboard: {
// writeText: jest.fn(() => Promise.resolve()),
// },
// });
// const spySetIsDepositAddressPopoverOpen = jest.spyOn(onramp_store, 'setIsDepositAddressPopoverOpen');
// onramp_store.onClickCopyDepositAddress();

// expect(await spySetIsDepositAddressPopoverOpen).toHaveBeenCalledWith(true);
// jest.runAllTimers();
// expect(setTimeout).toHaveBeenCalledTimes(1);
// expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 500);
// expect(await spySetIsDepositAddressPopoverOpen).toHaveBeenCalledWith(false);

// jest.restoreAllMocks();
// jest.useRealTimers();
// });

it('should show widget when onClickDisclaimerContinue method was called', () => {
onramp_store.onClickDisclaimerContinue();

Expand Down Expand Up @@ -277,7 +248,6 @@ describe('OnRampStore', () => {

expect(onramp_store.api_error).toBeNull();
expect(onramp_store.deposit_address).toBeNull();
expect(onramp_store.deposit_address_ref).toBeNull();
expect(onramp_store.is_deposit_address_loading).toBeTruthy();
expect(onramp_store.selected_provider).toBeNull();
expect(onramp_store.should_show_widget).toBeFalsy();
Expand All @@ -303,24 +273,12 @@ describe('OnRampStore', () => {
expect(onramp_store.deposit_address).toBe('deposit address');
});

it('should set deposit address ref', () => {
onramp_store.setDepositAddressRef('deposit address ref');

expect(onramp_store.deposit_address_ref).toBe('deposit address ref');
});

it('should change value of the variable is_deposit_address_loading', () => {
onramp_store.setIsDepositAddressLoading(true);

expect(onramp_store.is_deposit_address_loading).toBeTruthy();
});

it('should change value of the variable is_deposit_address_popover_open', () => {
onramp_store.setIsDepositAddressPopoverOpen(true);

expect(onramp_store.is_deposit_address_popover_open).toBeTruthy();
});

it('should change value of the variable is_onramp_modal_open', () => {
onramp_store.setIsOnRampModalOpen(true);

Expand Down
30 changes: 0 additions & 30 deletions packages/cashier/src/stores/on-ramp-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default class OnRampStore extends BaseStore {
api_error = null;
deposit_address = null;
is_deposit_address_loading = true;
is_deposit_address_popover_open = false;
is_onramp_modal_open = false;
is_requesting_widget_html = false;
onramp_providers = [];
Expand All @@ -17,16 +16,13 @@ export default class OnRampStore extends BaseStore {
widget_error = null;
widget_html = null;

deposit_address_ref = null;

constructor({ WS, root_store }) {
super({ root_store });

makeObservable(this, {
api_error: observable,
deposit_address: observable,
is_deposit_address_loading: observable,
is_deposit_address_popover_open: observable,
is_onramp_modal_open: observable,
is_requesting_widget_html: observable,
onramp_providers: observable.shallow,
Expand All @@ -40,17 +36,14 @@ export default class OnRampStore extends BaseStore {
should_show_dialog: computed,
onMountOnramp: action.bound,
onUnmountOnramp: action.bound,
onClickCopyDepositAddress: action.bound,
onClickDisclaimerContinue: action.bound,
onClickGoToDepositPage: action.bound,
pollApiForDepositAddress: action.bound,
resetPopup: action.bound,
setApiError: action.bound,
setCopyIconRef: action.bound,
setDepositAddress: action.bound,
setDepositAddressRef: action.bound,
setIsDepositAddressLoading: action.bound,
setIsDepositAddressPopoverOpen: action.bound,
setIsOnRampModalOpen: action.bound,
setIsRequestingWidgetHtml: action.bound,
setSelectedProvider: action.bound,
Expand Down Expand Up @@ -182,20 +175,6 @@ export default class OnRampStore extends BaseStore {
}
}

onClickCopyDepositAddress() {
const range = document.createRange();
range.selectNodeContents(this.deposit_address_ref);

const selections = window.getSelection();
selections.removeAllRanges();
selections.addRange(range);

navigator.clipboard.writeText(this.deposit_address).then(() => {
this.setIsDepositAddressPopoverOpen(true);
setTimeout(() => this.setIsDepositAddressPopoverOpen(false), 500);
});
}

onClickDisclaimerContinue() {
this.setShouldShowWidget(true);
}
Expand Down Expand Up @@ -248,7 +227,6 @@ export default class OnRampStore extends BaseStore {
resetPopup() {
this.setApiError(null);
this.setDepositAddress(null);
this.setDepositAddressRef(null);
this.setIsDepositAddressLoading(true);
this.setSelectedProvider(null);
this.setShouldShowWidget(false);
Expand All @@ -268,18 +246,10 @@ export default class OnRampStore extends BaseStore {
this.deposit_address = deposit_address;
}

setDepositAddressRef(ref) {
this.deposit_address_ref = ref;
}

setIsDepositAddressLoading(is_loading) {
this.is_deposit_address_loading = is_loading;
}

setIsDepositAddressPopoverOpen(is_open) {
this.is_deposit_address_popover_open = is_open;
}

setIsOnRampModalOpen(is_open) {
this.is_onramp_modal_open = is_open;
}
Expand Down
Loading

0 comments on commit b9d0f49

Please sign in to comment.