Skip to content

Commit

Permalink
Merge pull request #94 from amina-deriv/accounts_team/accounts_packag…
Browse files Browse the repository at this point in the history
…e_ts_migration/sprint_6

Accounts team/accounts package ts migration/sprint 6
  • Loading branch information
shaheer-deriv committed Oct 16, 2023
2 parents 8314f9a + 9e0c641 commit 7379fa5
Show file tree
Hide file tree
Showing 886 changed files with 27,116 additions and 11,664 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
extends: ['@deriv/eslint-config-deriv'],
rules: {
'global-require': 'off',
},
overrides: [
{
files: ['*.ts', '*.tsx'],
Expand Down
2 changes: 1 addition & 1 deletion .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"*.{js,jsx,ts,tsx,md,html,css,scss}": "prettier --write",
"*.{js,jsx,ts,tsx}": "eslint --fix --config .eslintrc.js",
"*.{js,jsx,ts,tsx}": "eslint --fix --config .eslintrc.js --rule 'simple-import-sort/imports: 0'",
"*.{css,scss}": "npx stylelint --fix"
}
6 changes: 6 additions & 0 deletions __mocks__/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@
jest.mock('copy-anything', () => ({
copy: jest.fn(),
}));

const mock_onfido = {
init: jest.fn().mockResolvedValue({}),
};

window.Onfido = mock_onfido;
1,701 changes: 99 additions & 1,602 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"dependencies": {
"@binary-com/binary-document-uploader": "^2.4.8",
"@deriv/api": "^1.0.0",
"@deriv/api-types": "^1.0.118",
"@deriv/components": "^1.0.0",
"@deriv/hooks": "^1.0.0",
Expand All @@ -43,7 +44,6 @@
"js-cookie": "^2.2.1",
"mobx": "^6.6.1",
"mobx-react": "^7.5.1",
"onfido-sdk-ui": "^11.0.0",
"prop-types": "^15.7.2",
"qrcode.react": "^1.0.0",
"react": "^17.0.2",
Expand Down
6 changes: 2 additions & 4 deletions packages/account/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import Routes from './Containers/routes';
import ResetTradingPassword from './Containers/reset-trading-password';
import { setWebsocket } from '@deriv/shared';
import { APIProvider } from '@deriv/api';
import { StoreProvider } from '@deriv/stores';
import { TCoreStores } from '@deriv/stores/types';
import APIProvider from '../../api/src/APIProvider';

// TODO: add correct types for WS after implementing them
type TAppProps = {
Expand All @@ -15,8 +14,7 @@ type TAppProps = {
};

const App = ({ passthrough }: TAppProps) => {
const { root_store, WS } = passthrough;
setWebsocket(WS);
const { root_store } = passthrough;

const { notification_messages_ui: Notifications } = root_store.ui;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

import { mockStore, StoreProvider } from '@deriv/stores';
import { render, screen } from '@testing-library/react';
import { StoreProvider, mockStore } from '@deriv/stores';

import BinaryRoutes from '../binary-routes';

jest.mock('../route-with-sub-routes', () => jest.fn(() => <div>RouteWithSubRoutes</div>));
Expand Down
5 changes: 4 additions & 1 deletion packages/account/src/Components/Routes/binary-routes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from 'react';
import { Switch } from 'react-router-dom';
import { Localize } from '@deriv/translations';

import { observer, useStore } from '@deriv/stores';
import { Localize } from '@deriv/translations';

import getRoutesConfig from '../../Constants/routes-config';
import { TBinaryRoutes, TRoute } from '../../Types';

import RouteWithSubRoutes from './route-with-sub-routes';

const BinaryRoutes = observer((props: TBinaryRoutes) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/account/src/Components/Routes/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export const findRouteByPath = (path: string, routes_config?: TRouteConfig[]): R
routes_config?.some(route_info => {
let match_path: match | null = null;
try {
match_path = matchPath(path, route_info);
match_path = matchPath(path, route_info as RouteProps);
} catch (e: unknown) {
if (/undefined/.test((e as Error).message)) {
return undefined;
}
}

if (match_path) {
result = route_info;
result = route_info as RouteProps;
return true;
} else if (route_info.routes) {
result = findRouteByPath(path, route_info.routes);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { StoreProvider, mockStore } from '@deriv/stores';
import { AdditionalKycInfoForm } from '../additional-kyc-info-form';
import userEvent from '@testing-library/user-event';
import { useSettings } from '@deriv/api';

jest.mock('@deriv/api', () => ({
...jest.requireActual('@deriv/api'),
useSettings: jest.fn(),
}));

const mockedUseSettings = useSettings as jest.MockedFunction<typeof useSettings>;

const mock_settings: ReturnType<typeof useSettings> = {
update: jest.fn(),
mutation: { isLoading: false, isSuccess: false, error: null, isError: false },
data: {
tax_identification_number: '',
tax_residence: '',
place_of_birth: '',
account_opening_reason: '',
},
};

jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
generateValidationFunction: jest.fn(),
}));

describe('AdditionalKycInfoForm', () => {
const setError = jest.fn();
const mock_store = mockStore({});

it('should render the form fields', () => {
mockedUseSettings.mockReturnValue(mock_settings);
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoForm setError={setError} />
</StoreProvider>
);

expect(screen.getByTestId('dt_place_of_birth')).toBeInTheDocument();
expect(screen.getByTestId('dt_tax_residence')).toBeInTheDocument();
expect(screen.getByTestId('dt_tax_identification_number')).toBeInTheDocument();
expect(screen.getByTestId('dt_account_opening_reason')).toBeInTheDocument();
});

it('should render loading state upon fetching data', () => {
mockedUseSettings.mockReturnValue({ ...mock_settings, isLoading: true });
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoForm setError={setError} />
</StoreProvider>
);

expect(screen.getByTestId('dt_initial_loader')).toBeInTheDocument();
});

it('should submit the form when all fields are valid', async () => {
mockedUseSettings.mockReturnValue(mock_settings);
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoForm setError={setError} />
</StoreProvider>
);

const submit_btn = screen.getByRole('button', { name: 'Submit' });

userEvent.type(screen.getByTestId('dt_place_of_birth'), 'Ghana');
userEvent.type(screen.getByTestId('dt_tax_residence'), 'Ghana');
userEvent.type(screen.getByTestId('dt_tax_identification_number'), 'GHA-000000000-0');
userEvent.type(screen.getByTestId('dt_account_opening_reason'), 'Speculative');

await waitFor(() => {
expect(submit_btn).toBeEnabled();
});
userEvent.click(screen.getByRole('button', { name: 'Submit' }));

expect(mockedUseSettings).toHaveBeenCalled();
});

it('should be able to submit the form without filling optional fields', async () => {
mockedUseSettings.mockReturnValue(mock_settings);
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoForm setError={setError} />
</StoreProvider>
);

const submit_btn = screen.getByRole('button', { name: 'Submit' });

userEvent.type(screen.getByTestId('dt_place_of_birth'), 'Ghana');
userEvent.type(screen.getByTestId('dt_account_opening_reason'), 'Speculative');

await waitFor(() => {
expect(submit_btn).toBeEnabled();
});
userEvent.click(screen.getByRole('button', { name: 'Submit' }));

expect(mockedUseSettings).toHaveBeenCalled();
});

it('should show an error message if form validation fails', async () => {
mockedUseSettings.mockReturnValue({
...mock_settings,
mutation: {
...mock_settings.mutation,
isError: true,
status: 'error',
error: {
message: 'Invalid TIN format',
},
},
});
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoForm setError={setError} />
</StoreProvider>
);

const submit_btn = screen.getByRole('button', { name: 'Submit' });

userEvent.type(screen.getByTestId('dt_place_of_birth'), 'Ghana');
userEvent.type(screen.getByTestId('dt_tax_residence'), 'Ghana');
userEvent.type(screen.getByTestId('dt_tax_identification_number'), 'GHA-00000000');
userEvent.type(screen.getByTestId('dt_account_opening_reason'), 'Speculative');

userEvent.click(submit_btn);

expect(mockedUseSettings).toHaveBeenCalled();
expect(setError).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { StoreProvider, mockStore } from '@deriv/stores';
import { AdditionalKycInfoModal } from '../additional-kyc-info-modal';

jest.mock('../additional-kyc-info-form.tsx', () => jest.fn(() => <div>AdditionalKycInfoForm</div>));

describe('AdditionalKycInfoModal', () => {
let modal_root_el: HTMLElement;
const mock_store = mockStore({
ui: {
is_additional_kyc_info_modal_open: true,
toggleAdditionalKycInfoModal: jest.fn(),
},
});

beforeAll(() => {
modal_root_el = document.createElement('div');
modal_root_el.setAttribute('id', 'modal_root');
document.body.appendChild(modal_root_el);
});

afterAll(() => {
document.body.removeChild(modal_root_el);
});

it('should render the modal when is_additional_kyc_info_modal_open is true', () => {
render(
<StoreProvider store={mock_store}>
<AdditionalKycInfoModal />
</StoreProvider>
);
expect(screen.getByText(/additional information required/i)).toBeInTheDocument();
expect(screen.getByText(/AdditionalKycInfoForm/i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { GetSettings, ResidenceList } from '@deriv/api-types';
import { getFormFieldsConfig, getFormConfig, TFields } from '../form-config';

const mockAccountSettings: GetSettings = {
immutable_fields: ['place_of_birth'],
place_of_birth: 'UK',
tax_residence: 'UK',
tax_identification_number: '12345',
account_opening_reason: 'Hedging',
};

const mockResidenceList: ResidenceList = [
{ value: 'UK', text: 'United Kingdom' },
{ value: 'US', text: 'United States' },
];

describe('getFormFieldsConfig', () => {
it('should return the correct form fields configuration', () => {
const requiredFields: TFields[] = ['place_of_birth', 'tax_residence'];
const config = getFormFieldsConfig(mockAccountSettings, mockResidenceList, requiredFields);

expect(config.place_of_birth.type).toBe('select');
expect(config.place_of_birth.initial_value).toBe('United Kingdom');
expect(config.place_of_birth.disabled).toBe(true);
expect(config.place_of_birth.required).toBe(true);

expect(config.tax_residence.type).toBe('select');
expect(config.tax_residence.initial_value).toBe('United Kingdom');
expect(config.tax_residence.disabled).toBe(false);
expect(config.tax_residence.required).toBe(true);
});
});

describe('getFormConfig', () => {
it('should return the correct form configuration', () => {
const requiredFields: TFields[] = ['place_of_birth', 'tax_residence'];
const formConfig = getFormConfig({
account_settings: mockAccountSettings,
residence_list: mockResidenceList,
required_fields: requiredFields,
});

expect(formConfig.fields.place_of_birth.disabled).toBe(true);
expect(formConfig.fields.place_of_birth.required).toBe(true);

expect(formConfig.fields.tax_residence.disabled).toBe(false);
expect(formConfig.fields.tax_residence.required).toBe(true);
});

it('should return the correct form configuration with input types', () => {
const requiredFields: TFields[] = ['place_of_birth', 'tax_residence'];
const formConfig = getFormConfig({
account_settings: { ...mockAccountSettings, immutable_fields: ['place_of_birth', 'tax_residence'] },
residence_list: mockResidenceList,
required_fields: requiredFields,
with_input_types: true,
});

expect(formConfig.fields.place_of_birth.type).toBe('select');
expect(formConfig.fields.place_of_birth.disabled).toBe(true);
expect(formConfig.fields.place_of_birth.required).toBe(true);

expect(formConfig.fields.tax_residence.type).toBe('select');
expect(formConfig.fields.tax_residence.disabled).toBe(true);
expect(formConfig.fields.tax_residence.required).toBe(true);
});
});
Loading

0 comments on commit 7379fa5

Please sign in to comment.