Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

george / rm89648 / add breadcrumb in cashier deposit page #7899

Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e234bbb
feat: add breadcrumbs in cashier deposit page
heorhi-deriv Mar 14, 2023
6983ae2
test: add tests
heorhi-deriv Mar 14, 2023
ffc9f2a
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 14, 2023
266b576
refactor: refactor items array, add css
heorhi-deriv Mar 15, 2023
3df4ceb
Merge branch '90561_Add-breadcrumb-in-cashier-deposit-page' of https:…
heorhi-deriv Mar 15, 2023
dbc3b93
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 15, 2023
55b05a8
test: fix tests
heorhi-deriv Mar 15, 2023
ef454ad
Merge branch '90561_Add-breadcrumb-in-cashier-deposit-page' of https:…
heorhi-deriv Mar 15, 2023
184ed23
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 15, 2023
a9fef90
refactor: incorporate comments
heorhi-deriv Mar 16, 2023
e697037
test: refactor tests
heorhi-deriv Mar 16, 2023
3408664
Merge branch '90561_Add-breadcrumb-in-cashier-deposit-page' of https:…
heorhi-deriv Mar 16, 2023
838ce83
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 16, 2023
3c1773d
fix: add css file
heorhi-deriv Mar 16, 2023
4ed5114
Merge branch '90561_Add-breadcrumb-in-cashier-deposit-page' of https:…
heorhi-deriv Mar 16, 2023
84031ae
fix: fix import breadcrumb for proper appstore build
heorhi-deriv Mar 16, 2023
082ad72
refactor: resolve comments
heorhi-deriv Mar 16, 2023
abc5ea5
fix: fix conflicts
heorhi-deriv Mar 20, 2023
31d393a
fix: applied comments
heorhi-deriv Mar 20, 2023
8989152
fix: breadcrumb visibility in safari in mobile view
heorhi-deriv Mar 21, 2023
498fe13
fix: codecav
heorhi-deriv Mar 21, 2023
bdf41f8
perf: add dependency
heorhi-deriv Mar 21, 2023
7bdb1dc
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 21, 2023
09baeac
fix: update deriv-components version to 0.6.0
heorhi-deriv Mar 24, 2023
1f238b3
Merge branch '90561_Add-breadcrumb-in-cashier-deposit-page' of https:…
heorhi-deriv Mar 24, 2023
918c34e
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 24, 2023
412cb09
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 24, 2023
6eb5a2c
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
heorhi-deriv Mar 24, 2023
1f9904e
Merge branch 'master' into 90561_Add-breadcrumb-in-cashier-deposit-page
jim-deriv Mar 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/appstore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"@deriv/stores": "^1.0.0",
"@deriv/trader": "^3.8.0",
"@deriv/translations": "^1.0.0",
"@deriv/ui": "^0.0.15",
"classnames": "^2.2.6",
"formik": "^2.1.4",
"mobx": "^6.6.1",
Expand Down
1 change: 1 addition & 0 deletions packages/cashier/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@deriv/shared": "^1.0.0",
"@deriv/stores": "^1.0.0",
"@deriv/translations": "^1.0.0",
"@deriv/ui": "^0.4.0",
"classnames": "^2.2.6",
"formik": "^2.1.4",
"loadjs": "^4.2.0",
Expand Down
24 changes: 24 additions & 0 deletions packages/cashier/src/app-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import Routes from 'Containers/routes';
import { observer, useStore } from '@deriv/stores';
import { useTheme } from '@deriv/ui';

const AppContent = observer(() => {
const { ui } = useStore();
const { is_dark_mode_on, notification_messages_ui: Notifications } = ui;
const { setColorMode } = useTheme();

React.useEffect(() => {
const theme = (is_dark_mode_on ? 'dark' : 'light') as Parameters<typeof setColorMode>[0];
setColorMode(theme);
}, [is_dark_mode_on, setColorMode]);

return (
<>
{Notifications && <Notifications />}
<Routes />
</>
);
});

export default AppContent;
7 changes: 2 additions & 5 deletions packages/cashier/src/app.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from 'react';
import { setWebsocket } from '@deriv/shared';
import { init } from 'Utils/server_time';
import Routes from 'Containers/routes';
import CashierProviders from './cashier-providers';
import AppContent from './app-content';

const App = ({ passthrough: { WS, root_store } }) => {
const { notification_messages_ui: Notifications } = root_store.ui;

React.useEffect(() => {
setWebsocket(WS);
init();
Expand All @@ -15,8 +13,7 @@ const App = ({ passthrough: { WS, root_store } }) => {

return (
<CashierProviders store={root_store}>
{Notifications && <Notifications />}
<Routes />
<AppContent />
</CashierProviders>
);
};
Expand Down
5 changes: 4 additions & 1 deletion packages/cashier/src/cashier-providers.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react';
import { StoreProvider } from '@deriv/stores';
import { ThemeProvider } from '@deriv/ui';
import { CashierStoreProvider } from './stores/useCashierStores';
import { TRootStore } from 'Types';

const CashierProviders = ({ children, store }: React.PropsWithChildren<{ store: TRootStore }>) => {
return (
<StoreProvider store={store}>
<CashierStoreProvider>{children}</CashierStoreProvider>
<CashierStoreProvider>
<ThemeProvider>{children} </ThemeProvider>
</CashierStoreProvider>
</StoreProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import CashierBreadcrumb from '../cashier-breadcrumb';

jest.mock('Stores/useCashierStores', () => ({
...jest.requireActual('Stores/useCashierStores'),
useCashierStore: jest.fn(() => ({
general_store: { setIsDeposit: jest.fn() },
})),
}));

describe('<CashierBreadcrumb />', () => {
it('should render proper crumbs for crypto deposit page', () => {
render(<CashierBreadcrumb is_crypto_deposit />);

expect(screen.getByText(/cashier/i)).toBeInTheDocument();
expect(screen.getByText(/deposit cryptocurrencies/i)).toBeInTheDocument();
});

it('should render proper crumbs for fiat deposit page', () => {
render(<CashierBreadcrumb />);

expect(screen.getByText(/cashier/i)).toBeInTheDocument();
expect(screen.getByText(/deposit via bank wire, credit card, and e-wallet/i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.cashier-breadcrumb {
width: 100%;
margin-bottom: 1.6rem;

ul > *:not(:last-child) {
cursor: pointer;
}

li {
text-align: left;
}

@include mobile {
margin-top: 1.6rem;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { localize } from '@deriv/translations';
import { Breadcrumb } from '@deriv/ui';
import { useCashierStore } from '../../stores/useCashierStores';
import './cashier-breadcrumb.scss';

const CashierBreadcrumb = ({ is_crypto_deposit = false }: { is_crypto_deposit?: boolean }) => {
const {
general_store: { setIsDeposit },
} = useCashierStore();

const crypto_deposit_crumbs: React.ComponentProps<typeof Breadcrumb>['items'] = [
{ value: 0, text: localize('Cashier') },
{ value: 1, text: localize('Deposit cryptocurrencies') },
];

const fiat_deposit_crumbs: React.ComponentProps<typeof Breadcrumb>['items'] = [
{ value: 0, text: localize('Cashier') },
{ value: 1, text: localize('Deposit via bank wire, credit card, and e-wallet') },
];

const onBreadcrumbHandler: React.ComponentProps<typeof Breadcrumb>['handleOnClick'] = item => {
switch (item.value) {
case 0:
setIsDeposit(false);
break;
default:
}
};

// TODO: improve Breadcrumb component in deriv-ui project that it can accept custom classnames
return (
<div className='cashier-breadcrumb'>
<Breadcrumb
items={is_crypto_deposit ? crypto_deposit_crumbs : fiat_deposit_crumbs}
handleOnClick={onBreadcrumbHandler}
/>
</div>
);
};

export default CashierBreadcrumb;
3 changes: 3 additions & 0 deletions packages/cashier/src/components/cashier-breadcrumb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CashierBreadcrumb from './cashier-breadcrumb';

export default CashierBreadcrumb;
Original file line number Diff line number Diff line change
@@ -1,41 +1,144 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { mockStore, StoreProvider } from '@deriv/stores';
import { useCashierStore } from '../../../../stores/useCashierStores';
import userEvent from '@testing-library/user-event';
import Real from '../real';

jest.mock('@deriv/components', () => ({
...(jest.requireActual('@deriv/components') as any),
...jest.requireActual('@deriv/components'),
Loading: () => <div>Loading</div>,
}));

let mocked_cashier_store: DeepPartial<ReturnType<typeof useCashierStore>>;

jest.mock('Stores/useCashierStores', () => ({
...jest.requireActual('Stores/useCashierStores'),
useCashierStore: jest.fn(() => mocked_cashier_store),
}));

describe('<Real />', () => {
const props = {
iframe_url: 'https://www.test_url.com',
clearIframe: jest.fn(),
iframe_height: '',
is_loading: false,
};

it('should render the component with iframe when iframe_url value is passed', () => {
render(<Real {...props} />);
const el_loader = screen.queryByText('Loading');

expect(el_loader).not.toBeInTheDocument();
expect(screen.queryByTestId('dt_doughflow_section')).toBeInTheDocument();
beforeEach(() => {
mocked_cashier_store = {
iframe: {
clearIframe: jest.fn(),
iframe_height: 100,
iframe_url: 'https://www.test_url.com',
},
deposit: {
onMountDeposit: jest.fn(),
},
general_store: {
is_loading: false,
},
};
});

it('should render the loading when is_loading is true', () => {
render(<Real {...props} iframe_url='' is_loading />);
const el_loader = screen.queryByText('Loading');
const mockRootStore = mockStore({});

it('should show loader when is_loading is true or iframe_height is equal to 0', () => {
(useCashierStore as jest.Mock).mockReturnValueOnce({
...mocked_cashier_store,
iframe: { ...mocked_cashier_store.iframe, iframe_height: 0 },
});

const { rerender } = render(
<StoreProvider store={mockRootStore}>
<Real is_deposit />
</StoreProvider>
);

expect(screen.getByText('Loading')).toBeInTheDocument();

expect(el_loader).toBeInTheDocument();
expect(screen.queryByTestId('dt_doughflow_section')).not.toBeInTheDocument();
(useCashierStore as jest.Mock).mockReturnValueOnce({
...mocked_cashier_store,
general_store: { is_loading: true },
});

rerender(
<StoreProvider store={mockRootStore}>
<Real is_deposit />
</StoreProvider>
);

expect(screen.getByText('Loading')).toBeInTheDocument();
});

it('will display doughflow and loader if all props are provided', () => {
render(<Real {...props} is_loading />);
const el_loader = screen.queryByText('Loading');
it('should render an iframe if iframe_url is not an empty string', () => {
render(
<StoreProvider store={mockRootStore}>
<Real is_deposit />
</StoreProvider>
);

expect(el_loader).toBeInTheDocument();
expect(screen.queryByTestId('dt_doughflow_section')).toBeInTheDocument();
});

describe('Breadcrumb visibility', () => {
it('should show breadcrumbs only on deposit page and only for non EU clients', () => {
render(
<StoreProvider store={mockRootStore}>
<Real is_deposit />
</StoreProvider>
);

expect(screen.getByText(/cashier/i)).toBeInTheDocument();
expect(screen.getByText(/deposit via bank wire, credit card, and e-wallet/i)).toBeInTheDocument();
});

it('should not show breadcrumbs on deposit page if iframe_height is equal to 0', () => {
(useCashierStore as jest.Mock).mockReturnValueOnce({
...mocked_cashier_store,
iframe: { ...mocked_cashier_store.iframe, iframe_height: 0 },
});

render(
<StoreProvider store={mockRootStore}>
<Real is_deposit />
</StoreProvider>
);

expect(screen.queryByText(/cashier/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deposit via bank wire, credit card, and e-wallet/i)).not.toBeInTheDocument();
});

it('should not show breadcrumbs on withdraw page', () => {
render(
<StoreProvider store={mockRootStore}>
<Real is_deposit={false} />
</StoreProvider>
);

expect(screen.queryByText(/cashier/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deposit via bank wire, credit card, and e-wallet/i)).not.toBeInTheDocument();
});
});

it('should trigger setIsDeposit callback when the user clicks on Cashier breadcrumb', () => {
render(
<StoreProvider store={mockRootStore}>
<Real is_deposit={false} />
</StoreProvider>
);

const el_breadcrumb_cashier = screen.queryByText(/cashier/i);

if (el_breadcrumb_cashier) {
userEvent.click(el_breadcrumb_cashier);
expect(mocked_cashier_store.general_store?.setIsDeposit).toHaveBeenCalledWith(false);
}
});

it('should trigger clearIframe and onMountDeposit callbacks when <Real /> component is destroyed on deposit page', () => {
const { unmount } = render(
<StoreProvider store={mockRootStore}>
<Real is_deposit={false} />
</StoreProvider>
);

unmount();

expect(mocked_cashier_store.iframe?.clearIframe).toHaveBeenCalled();
expect(mocked_cashier_store.deposit?.onMountDeposit).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.real {
heorhi-deriv marked this conversation as resolved.
Show resolved Hide resolved
&__loader {
width: 100%;
height: 80vh;
}
}
34 changes: 24 additions & 10 deletions packages/cashier/src/components/cashier-container/real/real.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
import React from 'react';
import { Loading } from '@deriv/components';
import { useStore } from '@deriv/stores';
import CashierBreadcrumb from '../../cashier-breadcrumb';
import { useCashierStore } from '../../../stores/useCashierStores';
import './real.scss';

type TRealProps = {
iframe_height: number | string;
iframe_url: string;
clearIframe: VoidFunction;
is_loading: boolean;
};
const Real = ({ is_deposit = false }: { is_deposit?: boolean }) => {
const {
traders_hub: { is_low_risk_cr_eu_real },
} = useStore();

const { iframe, deposit, general_store } = useCashierStore();

const { clearIframe, iframe_height, iframe_url } = iframe;

const { is_loading } = general_store;

const { onMountDeposit } = deposit;

const should_show_breadcrumbs = !is_low_risk_cr_eu_real && is_deposit && Boolean(iframe_height);
const should_show_loader = is_loading || !iframe_height;

const Real = ({ iframe_height, iframe_url, clearIframe, is_loading }: TRealProps) => {
React.useEffect(() => {
return () => {
clearIframe();
onMountDeposit?.();
};
}, [clearIframe]);
}, [clearIframe, onMountDeposit]);

return (
<div className='cashier__wrapper'>
{is_loading && <Loading is_fullscreen />}
<div className='cashier__wrapper real'>
{should_show_loader && <Loading className='real__loader' />}
{should_show_breadcrumbs && <CashierBreadcrumb />}
{iframe_url && (
<iframe
className='cashier__content'
Expand Down
Loading