Skip to content

Commit

Permalink
Likhith/kyc 363/onfido sdk updation (binary-com#10560)
Browse files Browse the repository at this point in the history
* refactor: review comments

* refactor: review comments css

* fix: 🐛 incorporated message to display document type

* fix: resolved code smell

* fix: 🐛 incorporated generic error message

* fix: 🐛 added missing dependency

* chore: 🔀 synced with master

* fix: ♻️ incorporated review comments

* fix: resolved un necessary render issue

* fix: 🐛 resolved issue with expired status

* style: fix side container width in poi (#39)

* style: container height fix for POI error messages when content in not overflowing (#40)

* fix: onfido message alignment

* fix: 🐛 incorporated continue trade button

* fix: onfido page mobile

* style: no padding on fields container in idv screen (#41)

* refactor: onfido hint center alignment fix

* fix: odd translate value fix

* fix: 🐛 minor CSS fix

* fix: green message responsive position

* fix: green message full width

* fix: ✅ updated testcases

* fix: failing tests

* refactor: code and ts fixes

* fix: display of IDV error

* chore: add duplication account error

* refactor: added undefined check to response data

* chore: review comments

* chore: review comments

* fix: ⬆️ upgraded SDK and handled language change

* fix: ♻️ incorporated review comments

* fix: ♻️ refactored code to remove useRef

* fix: barriers test fix form master

* fix: barriers test

* chore: refactored object.freeze to as const

* chore: optional chaining to document type

* chore: update spec file for idv-form

* test: update personal-details spec

* chore: review comments

* refactor: ♻️ incorporated hooks to handle business logic

* refactor: css structure

* fix: barriers test

* fix: ⚰️ removed unwanted code

* test: 🔥 removed mocked tokens

* chore: 📝 Added documentation for UseNotificationEvent hook

* fix: 💄 incorporated styling

* fix: ♻️ incorporated review comments

* refactor: rename properties

* refactor: remove is_appstore from tests

* fix: ♻️ incorporated review comments

* refactor: styles refactor

* fix: ⚡ reduced duplicate data

* fix: incorporated review comments

* fix: ♻️ incorporated review comments

* chore: Trigger Build

* fix: 🚚 modified path

* chore: remove unused fila and variable, updated icons

* revert: 🍻 removed icon changes

* refactor: removed formatting

* fix: removed assignment of default values

* fix: 🐛 unable to select a new doc supporting country

* fix: 🐛 resolved re-render issue

* fix: ⚡ resolved message issue

* refactor: 🚚 renamed varibales

* fix: 🧪 failing testcase

* fix: 🐛 resolved issues with failure messages

* fix: 🐛 resolved issue with DIEL accounts

* fix: 🐛 fixed issue for DIEL clients

* fix: styling issues

* fix: ts error for format-response

* build: 📌 updated package-lock after updating onfido-sdk-ui

* fix: 🚚 fixed path

* fix: 🚚 fixed path

* fix: 🐛 resolved styling bugs

* fix: 🐛 resolved styling bugs

* fix: ♻️ removed default values

* fix: 🔥 incorporated new styles to fix icon size

* fix: 🔥 incorporated new styles to fix icon size

* fix: ✅ fixed failing testcase

* fix: 💚 eslint issues

* fix: ⚡ incorporated platform language change

* fix: removed store

* fix: layout styles

* fix: style issues

* fix: styles

* fix: moved common styles to core

* refactor: incorporated review comments

* fix: 💄 updated styles

* fix: 🐛 reverted code

* fix: 🐛 reverted code

* refactor: incorporated review comments

* fix: 🐛 Onfido SDK language code conversion

* fix: migrated hooks

* revert: logic for generating code

* chore: adding missing testcases

* fix: recatored Onfido constants

* fix: onfido screen css issues

* fix: removed package-lock to resolve merge error

* Merge branch 'master' into likhith/KYC-363/onfido-sdk-updation

* chore: added package-lock

* Merge branch 'master' into combined/wall-400/IDV-error-message-handled

* chore: Trigger Build

* fix: bug: /WEBREL-1358/personal-details page and poa page css issue

* fix: layout button

* fix: layout button

* fix: mt5 next button not getting enabled

* fix: resolved issue with button

* fix: resolved issue with button

* fix: resolved missing dropdown

* fix: removed console

* fix: incorporated review comments

* feat: ✨ incorporated new images and merged checkbox feature

* feat: ✨ incorporated new images and merged checkbox feature

* fix: idv failed document type

* fix: removed duplicate import

* fix: incorporated error message scenario

* fix: styling as per new figma

* fix: styling as per new figma

* fix: spacing between fields

* fix: spacing between fields

* fix: spacing between fields

* fix: incorporated new error code and styles as per new figma

* fix: incorporated new error code and styles as per new figma

* Merge branch 'master' into likhith/kyc-195/display-idv-error-messages

* fix: reverted changes

* Incorporate poi context (#55)

* chore: incorporate POIContext to keep track of submission

* chore: reset poi context state upon route change

* refactor: added reset for all path

* fix: changed testcases

---------

Co-authored-by: Likhith Kolayari <likhith@regentmarkets.com>

* fix: code smells

* chore: trigger rebuild

* fix: issue with checkbox

* fix: removed unused import

* fix: added keyboard event

* fix: resolved build failure

* Merge branch 'master' into likhith/KYC-363/onfido-sdk-updation

* fix: Onfido styles

* fix: resolved code-smells

---------

Co-authored-by: “yauheni-kryzhyk-deriv” <“yauheni@deriv.me”>
Co-authored-by: yauheni-deriv <103182683+yauheni-deriv@users.noreply.github.com>
Co-authored-by: Shahzaib <shahzaib@deriv.com>
  • Loading branch information
4 people committed Nov 9, 2023
1 parent f2615da commit 065ed72
Show file tree
Hide file tree
Showing 25 changed files with 1,321 additions and 394 deletions.
2 changes: 1 addition & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@
"eslint-plugin-react-hooks": "^4.2.0",
"history": "^5.0.0",
"mini-css-extract-plugin": "^1.3.4",
"sass": "^1.62.1",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.4.3",
"postcss-scss": "^4.0.6",
"resolve-url-loader": "^3.1.2",
"rimraf": "^3.0.2",
"sass": "^1.62.1",
"sass-loader": "^12.6.0",
"sass-resources-loader": "^2.1.1",
"terser-webpack-plugin": "^5.1.1",
Expand Down
19 changes: 11 additions & 8 deletions packages/account/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import Routes from './Containers/routes';
import ResetTradingPassword from './Containers/reset-trading-password';
import { APIProvider } from '@deriv/api';
import { StoreProvider } from '@deriv/stores';
import type { TCoreStores } from '@deriv/stores/types';
import { TCoreStores } from '@deriv/stores/types';
import { POIProvider } from './Helpers/poi-context';

// TODO: add correct types for WS after implementing them
type TAppProps = {
Expand All @@ -19,13 +20,15 @@ const App = ({ passthrough }: TAppProps) => {
const { notification_messages_ui: Notifications } = root_store.ui;

return (
<APIProvider>
<StoreProvider store={root_store}>
{Notifications && <Notifications />}
<Routes />
<ResetTradingPassword />
</StoreProvider>
</APIProvider>
<StoreProvider store={root_store}>
<APIProvider>
<POIProvider>
{Notifications && <Notifications />}
<Routes />
<ResetTradingPassword />
</POIProvider>
</APIProvider>
</StoreProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const PersonalDetails = ({
residence_list,
real_account_signup_target,
});

const IDV_NOT_APPLICABLE_OPTION = React.useMemo(() => getIDVNotApplicableOption(), []);

const validateIDV = values => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,66 @@ import React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { isDesktop, isMobile } from '@deriv/shared';
import CountrySelector from '../poi-country-selector';
import { APIProvider } from '@deriv/api';
import { StoreProvider, mockStore } from '@deriv/stores';
import { POIContext } from 'Helpers/poi-context';

jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
isDesktop: jest.fn(() => true),
isMobile: jest.fn(() => false),
}));

jest.mock('@deriv/api', () => ({
...jest.requireActual('@deriv/api'),
useResidenceList: jest.fn().mockReturnValue({
data: [
{ value: 'Country 1', text: 'Country 1' },
{ value: 'Country 2', text: 'Country 2' },
{ value: 'Country 3', text: 'Country 3' },
],
}),
}));

describe('<CountrySelector/>', () => {
let mock_props = {
let mock_props: React.ComponentProps<typeof CountrySelector> = {
handleSelectionNext: jest.fn(),
is_from_external: false,
residence_list: [{ value: '', text: '' }],
selected_country: '',
setSelectedCountry: jest.fn(),
};

beforeEach(() => {
mock_props = {
handleSelectionNext: jest.fn(),
is_from_external: false,
residence_list: [
{ value: 'Country 1', text: 'Country 1' },
{ value: 'Country 2', text: 'Country 2' },
{ value: 'Country 3', text: 'Country 3' },
],
selected_country: '',
setSelectedCountry: jest.fn(),
};
});

const store_config = mockStore({});

const poi_context_config = {
setSelectedCountry: jest.fn(),
selected_country: {},
setSubmissionService: jest.fn(),
submission_status: 'selecting',
setSubmissionStatus: jest.fn(),
submission_service: 'idv',
};

const renderComponent = ({ props = mock_props, context = poi_context_config }) =>
render(
<APIProvider>
<StoreProvider store={store_config}>
<POIContext.Provider value={context}>
<CountrySelector {...props} />
</POIContext.Provider>
</StoreProvider>
</APIProvider>
);

it('should render CountrySelector component external', () => {
mock_props.is_from_external = true;

render(<CountrySelector {...mock_props} />);
renderComponent({ props: mock_props });

expect(screen.getByText('Proof of identity')).toBeInTheDocument();
expect(screen.getByText('In which country was your document issued?')).toBeInTheDocument();
Expand All @@ -45,7 +71,7 @@ describe('<CountrySelector/>', () => {
});

it('should show error message after clicking the input without choosing the country', async () => {
render(<CountrySelector {...mock_props} />);
renderComponent({});

const field = screen.getByLabelText('Country');
const next_btn = screen.getByRole('button');
Expand All @@ -63,20 +89,37 @@ describe('<CountrySelector/>', () => {
expect(next_btn).toBeDisabled();
});

it('should render error status and country selector when error is verification failed or expired', () => {
mock_props.mismatch_status = 'POI_FAILED';

renderComponent({ props: mock_props });

expect(screen.getByText('Your identity verification failed because:')).toBeInTheDocument();
expect(
screen.getByText('We were unable to verify the identity document with the details provided.')
).toBeInTheDocument();
expect(screen.getByText('In which country was your document issued?')).toBeInTheDocument();

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

it('should trigger selection functions and next button', async () => {
(isDesktop as jest.Mock).mockReturnValue(false);
(isMobile as jest.Mock).mockReturnValue(true);
mock_props.selected_country = 'Country 2';

render(<CountrySelector {...mock_props} />);
const new_poi_context_config = {
...poi_context_config,
selected_country: { value: 'Country 2', text: 'Country 2' },
};

renderComponent({ context: new_poi_context_config });

const field = screen.getByRole('combobox');

fireEvent.change(field, { target: { value: 'Country 2' } });

const next_btn = screen.getByRole('button');
expect(next_btn).toBeEnabled();
expect(mock_props.setSelectedCountry).toHaveBeenCalledTimes(1);

fireEvent.click(next_btn);
await waitFor(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,18 @@ import { Autocomplete, Button, DesktopWrapper, HintBox, MobileWrapper, Text, Sel
import { idv_error_statuses, isMobile, TIDVErrorStatus } from '@deriv/shared';
import { Localize, localize } from '@deriv/translations';
import FormFooter from 'Components/form-footer';

type TCountry = Record<string, string>;
import { POIContext } from '../../../Helpers/poi-context';
import { useResidenceList } from '@deriv/api';

type TCountrySelector = {
handleSelectionNext: () => void;
is_from_external: boolean;
mismatch_status?: TIDVErrorStatus;
residence_list: TCountry[];
selected_country: string;
setSelectedCountry: (value: TCountry) => void;
};

const CountrySelector = ({
handleSelectionNext,
is_from_external,
mismatch_status,
residence_list,
selected_country,
setSelectedCountry,
}: TCountrySelector) => {
const [country_list, setCountryList] = React.useState<TCountry[]>([]);
const CountrySelector = ({ handleSelectionNext, is_from_external, mismatch_status }: TCountrySelector) => {
const { setSelectedCountry } = React.useContext(POIContext);
const { data: country_list, isLoading } = useResidenceList();

const initial_form_values: FormikValues = {
country_input: '',
Expand All @@ -45,7 +36,7 @@ const CountrySelector = ({
};

const updateSelectedCountry = (country_name: string) => {
const matching_country: TCountry | undefined = country_list.find((c: FormikValues) => c.text === country_name);
const matching_country = country_list?.find((c: FormikValues) => c.text === country_name);
if (matching_country) {
setSelectedCountry?.(matching_country);
}
Expand All @@ -57,10 +48,6 @@ const CountrySelector = ({
handleSelectionNext?.();
};

React.useEffect(() => {
setCountryList(residence_list);
}, [residence_list]);

let failed_message: JSX.Element | null = null;
if (mismatch_status === idv_error_statuses.poi_expired) {
failed_message = <Localize i18n_default_text='Your identity document has expired.' />;
Expand Down Expand Up @@ -187,7 +174,7 @@ const CountrySelector = ({
type='submit'
onClick={() => handleSubmit()}
has_effect
is_disabled={!dirty || isSubmitting || !isValid || !selected_country}
is_disabled={!dirty || isSubmitting || !isValid || isLoading}
is_loading={false}
text={localize('Next')}
large
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { Localize } from '@deriv/translations';

const getOnfidoPhrases = () => ({
//TODO: Check if these phrases are required;
export const getOnfidoPhrases = () => ({
country_select: {
alert_dropdown: {
country_not_found: <Localize i18n_default_text='Country not found' />,
Expand Down Expand Up @@ -341,4 +342,7 @@ const getOnfidoPhrases = () => ({
},
});

export default getOnfidoPhrases;
export const LANGUAGE_CODES = {
ID: 'id_ID',
EN: 'en_US',
};
15 changes: 15 additions & 0 deletions packages/account/src/Helpers/__tests__/utils.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
isFieldImmutable,
preventEmptyClipboardPaste,
shouldShowIdentityInformation,
getOnfidoSupportedLocaleCode,
verifyFields,
} from '../utils';

Expand Down Expand Up @@ -230,6 +231,20 @@ describe('isDocumentNumberValid', () => {
});
});

describe('getOnfidoSupportedLocaleCode', () => {
it('should return the correct language tag for German', () => {
expect(getOnfidoSupportedLocaleCode('DE')).toEqual('de');
});

it('should return the correct language tag for Indonesian', () => {
expect(getOnfidoSupportedLocaleCode('ID')).toEqual('id_ID');
});

it('should return the correct language tag for Chinese', () => {
expect(getOnfidoSupportedLocaleCode('Zh_CN')).toEqual('zh_CN');
});
});

describe('verifyFields', () => {
it('should return date field in the list when the error is date of birth', () => {
expect(verifyFields('POI_DOB_MISMATCH')).toEqual(['date_of_birth']);
Expand Down
56 changes: 56 additions & 0 deletions packages/account/src/Helpers/poi-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import { ResidenceList } from '@deriv/api-types';
import { service_code, submission_status_code } from '../Sections/Verification/ProofOfIdentity/proof-of-identity-utils';

type TSubmissionStatus = keyof typeof submission_status_code;
type TSubmissionService = keyof typeof service_code;

type TPOIContext = {
submission_status: TSubmissionStatus;
setSubmissionStatus: React.Dispatch<React.SetStateAction<TSubmissionStatus>>;
submission_service: TSubmissionService;
setSubmissionService: React.Dispatch<React.SetStateAction<TSubmissionService>>;
selected_country: ResidenceList[number];
setSelectedCountry: React.Dispatch<React.SetStateAction<ResidenceList[number]>>;
};

export const POIContextInitialState: TPOIContext = {
submission_status: submission_status_code.selecting,
setSubmissionStatus: () => submission_status_code.selecting,
submission_service: service_code.idv,
setSubmissionService: () => service_code.idv,
selected_country: {},
setSelectedCountry: () => ({}),
};

export const POIContext = React.createContext<TPOIContext>(POIContextInitialState);

export const POIProvider = ({ children }: React.PropsWithChildren) => {
const [submission_status, setSubmissionStatus] = React.useState<TSubmissionStatus>(
submission_status_code.selecting
);
const [submission_service, setSubmissionService] = React.useState<TSubmissionService>(service_code.idv);
const [selected_country, setSelectedCountry] = React.useState({});
const location = useLocation();

const state = React.useMemo(
() => ({
submission_status,
setSubmissionStatus,
submission_service,
setSubmissionService,
selected_country,
setSelectedCountry,
}),
[selected_country, submission_service, submission_status]
);

React.useEffect(() => {
setSubmissionStatus(submission_status_code.selecting);
setSubmissionService(service_code.idv);
setSelectedCountry({});
}, [location.pathname]);

return <POIContext.Provider value={state}>{children}</POIContext.Provider>;
};
Loading

0 comments on commit 065ed72

Please sign in to comment.