Skip to content

Commit

Permalink
Merge pull request #86 from utkarsha-deriv/UPM-938/utkarsha/integrate…
Browse files Browse the repository at this point in the history
…-API-for-verification-SMS-Whatsapp

feat: integrate phone number challenge api
  • Loading branch information
suisin-deriv authored May 9, 2024
2 parents 34f30d0 + ae5554d commit bd71427
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import { render, screen } from '@testing-library/react';
import React from 'react';
import ConfirmPhoneNumber from '../confirm-phone-number';
import { StoreProvider, mockStore } from '@deriv/stores';
import { useGetPhoneNumberOTP } from '@deriv/hooks';
import userEvent from '@testing-library/user-event';

jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useGetPhoneNumberOTP: jest.fn(() => ({
requestOnWhatsApp: jest.fn(),
requestOnSMS: jest.fn(),
})),
}));

describe('ConfirmPhoneNumber', () => {
const store = mockStore({
Expand All @@ -25,4 +35,34 @@ describe('ConfirmPhoneNumber', () => {
expect(screen.getByRole('button', { name: 'Get code via SMS' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Get code via WhatsApp' })).toBeInTheDocument();
});
it('should call requestOnWhatsApp when Whatsapp button is clicked', () => {
const mockWhatsappButtonClick = jest.fn();

(useGetPhoneNumberOTP as jest.Mock).mockReturnValueOnce({
requestOnWhatsApp: mockWhatsappButtonClick,
});
render(
<StoreProvider store={store}>
<ConfirmPhoneNumber />
</StoreProvider>
);
const whatsapp_btn = screen.getByRole('button', { name: 'Get code via WhatsApp' });
userEvent.click(whatsapp_btn);
expect(mockWhatsappButtonClick).toHaveBeenCalled();
});
it('should call requestOnSMS when SMS button is clicked', () => {
const mockSmsButtonClick = jest.fn();

(useGetPhoneNumberOTP as jest.Mock).mockReturnValueOnce({
requestOnSMS: mockSmsButtonClick,
});
render(
<StoreProvider store={store}>
<ConfirmPhoneNumber />
</StoreProvider>
);
const sms_btn = screen.getByRole('button', { name: 'Get code via SMS' });
userEvent.click(sms_btn);
expect(mockSmsButtonClick).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@ import { Button, Text } from '@deriv-com/quill-ui';
import { Localize, localize } from '@deriv/translations';
import { Input } from '@deriv/components';
import { observer, useStore } from '@deriv/stores';
import { useGetPhoneNumberOTP } from '@deriv/hooks';

const ConfirmPhoneNumber = observer(() => {
const { requestOnSMS, requestOnWhatsApp, ...rest } = useGetPhoneNumberOTP();
const { client } = useStore();
const { account_settings } = client;
const phoneNumber = account_settings.phone || '';
const phone_number = account_settings.phone || '';

return (
<PhoneVerificationCard>
<Text bold>
<Localize i18n_default_text='Confirm your phone number' />
</Text>
<Input label={localize('Phone number')} value={phoneNumber} />
<Input label={localize('Phone number')} value={phone_number} />
<div className='phone-verification__card--buttons_container'>
<Button variant='secondary' color='black' fullWidth size='lg'>
<Button variant='secondary' color='black' fullWidth size='lg' onClick={requestOnSMS}>
<Text bold>
<Localize i18n_default_text='Get code via SMS' />
</Text>
</Button>
<Button color='black' fullWidth size='lg'>
<Button color='black' fullWidth size='lg' onClick={requestOnWhatsApp}>
<Text color='white' bold>
<Localize i18n_default_text='Get code via WhatsApp' />
</Text>
Expand Down
49 changes: 49 additions & 0 deletions packages/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,51 @@ type PasskeyRegisterResponse = {
[k: string]: unknown;
};

// TODO: remove these mock phone number challenge types after implementing them inside api-types
type PhoneNumberChallengeRequest = {
/**
* Must be `1`
*/
phone_number_challenge: 1;
/**
* The carrier sending the OTP.
*/
carrier: 'whatsapp' | 'sms';
/**
* [Optional] The login id of the user. If left unspecified, it defaults to the initial authorized token's login id.
*/
loginid?: string;
/**
* [Optional] Used to pass data through the websocket, which may be retrieved via the `echo_req` output field.
*/
passthrough?: {
[k: string]: unknown;
};
/**
* [Optional] Used to map request to response.
*/
req_id?: number;
};

type PhoneNumberChallengeResponse = {
phone_number_challenge?: number;
/**
* Echo of the request made.
*/
echo_req: {
[k: string]: unknown;
};
/**
* Action name of the request made.
*/
msg_type: 'phone_number_challenge';
/**
* Optional field sent in request to map to response, present only when request contains `req_id`.
*/
req_id?: number;
[k: string]: unknown;
};

type TSocketEndpoints = {
active_symbols: {
request: ActiveSymbolsRequest;
Expand Down Expand Up @@ -2574,6 +2619,10 @@ type TSocketEndpoints = {
request: PayoutCurrenciesRequest;
response: PayoutCurrenciesResponse;
};
phone_number_challenge: {
request: PhoneNumberChallengeRequest;
response: PhoneNumberChallengeResponse;
};
ping: {
request: PingRequest;
response: PingResponse;
Expand Down
39 changes: 39 additions & 0 deletions packages/hooks/src/__tests__/useGetPhoneNumberOTP.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { renderHook } from '@testing-library/react-hooks';
import { useMutation } from '@deriv/api';
import useGetPhoneNumberOTP from '../useGetPhoneNumberOTP';

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

const mock_response = {
data: {
phone_number_challenge: 1,
},
mutate: jest.fn(),
};

describe('useGetPhoneNumberOTP', () => {
it('should call mutate with correct payload for SMS request and return correct response', () => {
(useMutation as jest.Mock).mockReturnValueOnce(mock_response);
const { result } = renderHook(() => useGetPhoneNumberOTP());

result.current.requestOnSMS();

expect(useMutation).toHaveBeenCalledWith('phone_number_challenge');
expect(result.current.mutate).toHaveBeenCalledWith({ payload: { carrier: 'sms' } });
expect(result.current.data).toEqual(1);
});

it('should call mutate with correct payload for WhatsApp request and return correct response', () => {
(useMutation as jest.Mock).mockReturnValueOnce(mock_response);
const { result } = renderHook(() => useGetPhoneNumberOTP());

result.current.requestOnWhatsApp();

expect(useMutation).toHaveBeenCalledWith('phone_number_challenge');
expect(result.current.mutate).toHaveBeenCalledWith({ payload: { carrier: 'whatsapp' } });
expect(result.current.data).toEqual(1);
});
});
1 change: 1 addition & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export { default as useFiatAccountList } from './useFiatAccountList';
export { default as useFileUploader } from './useFileUploader';
export { default as useGetMFAccountStatus } from './useGetMFAccountStatus';
export { default as useGetPasskeysList } from './useGetPasskeysList';
export { default as useGetPhoneNumberOTP } from './useGetPhoneNumberOTP';
export { default as useHasActiveRealAccount } from './useHasActiveRealAccount';
export { default as useHasCryptoCurrency } from './useHasCryptoCurrency';
export { default as useHasFiatCurrency } from './useHasFiatCurrency';
Expand Down
24 changes: 24 additions & 0 deletions packages/hooks/src/useGetPhoneNumberOTP.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useMutation } from '@deriv/api';
import { VERIFICATION_SERVICES } from '@deriv/shared';

/** A hook for requesting OTP which is sent on whatsapp or sms platforms */
const useGetPhoneNumberOTP = () => {
const { data, mutate, ...rest } = useMutation('phone_number_challenge');

const requestOnSMS = () => {
mutate({ payload: { carrier: VERIFICATION_SERVICES.SMS } });
};
const requestOnWhatsApp = () => {
mutate({ payload: { carrier: VERIFICATION_SERVICES.WHATSAPP } });
};

return {
data: data?.phone_number_challenge,
requestOnWhatsApp,
requestOnSMS,
mutate,
...rest,
};
};

export default useGetPhoneNumberOTP;
1 change: 1 addition & 0 deletions packages/shared/src/utils/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './error';
export * from './poi-failure-codes';
export * from './mt5-login-list-status';
export * from './auth-status-codes';
export * from './phone-number-verification';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const VERIFICATION_SERVICES = {
SMS: 'sms',
WHATSAPP: 'whatsapp',
} as const;

0 comments on commit bd71427

Please sign in to comment.