Skip to content

Commit 0ef5a5d

Browse files
authored
feat(deposit): fixes routing after user is authenticated (#17393)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Updates the `useDepositRouting` hook to correctly follow the rules needed for maintaining user state when routing. Pages now call `routeAfterAuthentication` when they are routing which will take care of fetching forms for updated kyc status. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent 19ef567 commit 0ef5a5d

File tree

14 files changed

+457
-487
lines changed

14 files changed

+457
-487
lines changed

app/components/UI/Ramp/Deposit/Views/BasicInfo/BasicInfo.test.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ describe('BasicInfo Component', () => {
123123
mobileNumber: '+1234567890',
124124
ssn: '123456789',
125125
},
126-
kycUrl: undefined,
127126
quote: mockQuote,
128127
}),
129128
);

app/components/UI/Ramp/Deposit/Views/BasicInfo/BasicInfo.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import useAnalytics from '../../../hooks/useAnalytics';
3636

3737
export interface BasicInfoParams {
3838
quote: BuyQuote;
39-
kycUrl?: string;
4039
}
4140

4241
export const createBasicInfoNavDetails =
@@ -54,7 +53,7 @@ const BasicInfo = (): JSX.Element => {
5453
const navigation = useNavigation();
5554
const { styles, theme } = useStyles(styleSheet, {});
5655
const trackEvent = useAnalytics();
57-
const { quote, kycUrl } = useParams<BasicInfoParams>();
56+
const { quote } = useParams<BasicInfoParams>();
5857
const { selectedRegion } = useDepositSDK();
5958

6059
const firstNameInputRef = useRef<TextInput>(null);
@@ -152,7 +151,6 @@ const BasicInfo = (): JSX.Element => {
152151
: '',
153152
},
154153
quote,
155-
kycUrl,
156154
}),
157155
);
158156
}
@@ -161,7 +159,6 @@ const BasicInfo = (): JSX.Element => {
161159
validateFormData,
162160
formData,
163161
quote,
164-
kycUrl,
165162
selectedRegion?.isoCode,
166163
trackEvent,
167164
]);

app/components/UI/Ramp/Deposit/Views/EnterAddress/EnterAddress.test.tsx

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,20 @@ const mockUseDepositSdkMethodInitialState = {
4444
};
4545

4646
let mockKycFunction = jest.fn().mockResolvedValue(undefined);
47-
let mockPurposeFunction = jest.fn().mockResolvedValue(undefined);
47+
4848
let mockSsnFunction = jest.fn().mockResolvedValue(undefined);
4949
let mockKycValues = [mockUseDepositSdkMethodInitialState, mockKycFunction];
50-
let mockPurposeValues = [
51-
mockUseDepositSdkMethodInitialState,
52-
mockPurposeFunction,
53-
];
50+
5451
let mockSsnValues = [
5552
{ ...mockUseDepositSdkMethodInitialState },
5653
mockSsnFunction,
5754
];
5855

59-
const mockNavigateToKycProcessing = jest.fn();
60-
const mockNavigateToAdditionalVerification = jest.fn();
56+
const mockRouteAfterAuthentication = jest.fn();
6157

6258
jest.mock('../../hooks/useDepositRouting', () => ({
6359
useDepositRouting: jest.fn(() => ({
64-
navigateToKycProcessing: mockNavigateToKycProcessing,
65-
navigateToAdditionalVerification: mockNavigateToAdditionalVerification,
60+
routeAfterAuthentication: mockRouteAfterAuthentication,
6661
})),
6762
}));
6863

@@ -71,9 +66,6 @@ jest.mock('../../hooks/useDepositSdkMethod', () => ({
7166
if (config?.method === 'patchUser') {
7267
return mockKycValues;
7368
}
74-
if (config?.method === 'submitPurposeOfUsageForm') {
75-
return mockPurposeValues;
76-
}
7769
if (config?.method === 'submitSsnDetails') {
7870
return mockSsnValues;
7971
}
@@ -150,22 +142,16 @@ describe('EnterAddress Component', () => {
150142
selectedRegion: { isoCode: 'US', name: 'United States', flag: '🇺🇸' },
151143
};
152144
mockKycFunction = jest.fn().mockResolvedValue(undefined);
153-
mockPurposeFunction = jest.fn().mockResolvedValue(undefined);
154145
mockSsnFunction = jest.fn().mockResolvedValue(undefined);
155146
mockKycValues = [
156147
{ ...mockUseDepositSdkMethodInitialState },
157148
mockKycFunction,
158149
];
159-
mockPurposeValues = [
160-
{ ...mockUseDepositSdkMethodInitialState },
161-
mockPurposeFunction,
162-
];
163150
mockSsnValues = [
164151
{ ...mockUseDepositSdkMethodInitialState },
165152
mockSsnFunction,
166153
];
167-
mockNavigateToKycProcessing.mockClear();
168-
mockNavigateToAdditionalVerification.mockClear();
154+
mockRouteAfterAuthentication.mockClear();
169155
mockTrackEvent.mockClear();
170156
});
171157

@@ -178,7 +164,7 @@ describe('EnterAddress Component', () => {
178164
render(EnterAddress);
179165
fireEvent.press(screen.getByTestId('address-continue-button'));
180166
expect(screen.toJSON()).toMatchSnapshot();
181-
expect(mockNavigateToKycProcessing).not.toHaveBeenCalled();
167+
expect(mockRouteAfterAuthentication).not.toHaveBeenCalled();
182168
});
183169

184170
it('submits form data and navigates to next page when form is valid and continue is pressed', async () => {
@@ -187,13 +173,11 @@ describe('EnterAddress Component', () => {
187173
fillFormAndSubmit();
188174

189175
await waitFor(() => {
190-
expect(mockNavigateToKycProcessing).toHaveBeenCalledWith({
191-
quote: mockQuote,
192-
});
176+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
193177
});
194178
});
195179

196-
it('navigates to additional verification when kycUrl is provided', async () => {
180+
it('submits form data and calls routeAfterAuthentication when kycUrl is provided', async () => {
197181
const kycUrl = 'https://example.com/kyc';
198182

199183
mockUseParamsReturnValue = {
@@ -215,14 +199,7 @@ describe('EnterAddress Component', () => {
215199
});
216200

217201
await waitFor(() => {
218-
expect(mockPurposeFunction).toHaveBeenCalled();
219-
});
220-
221-
await waitFor(() => {
222-
expect(mockNavigateToAdditionalVerification).toHaveBeenCalledWith({
223-
quote: mockQuote,
224-
kycUrl,
225-
});
202+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
226203
});
227204
});
228205

@@ -236,7 +213,7 @@ describe('EnterAddress Component', () => {
236213
expect(mockKycFunction).toHaveBeenCalled();
237214

238215
await waitFor(() => {
239-
expect(mockNavigateToKycProcessing).not.toHaveBeenCalled();
216+
expect(mockRouteAfterAuthentication).not.toHaveBeenCalled();
240217
});
241218
});
242219

@@ -254,9 +231,7 @@ describe('EnterAddress Component', () => {
254231
fillFormAndSubmit();
255232
await waitFor(() => {
256233
expect(mockSsnFunction).toHaveBeenCalledWith('123-45-6789');
257-
expect(mockNavigateToKycProcessing).toHaveBeenCalledWith({
258-
quote: mockQuote,
259-
});
234+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
260235
});
261236
});
262237

@@ -279,9 +254,7 @@ describe('EnterAddress Component', () => {
279254

280255
await waitFor(() => {
281256
expect(mockSsnFunction).not.toHaveBeenCalled();
282-
expect(mockNavigateToKycProcessing).toHaveBeenCalledWith({
283-
quote: mockQuote,
284-
});
257+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
285258
});
286259
});
287260

@@ -294,7 +267,7 @@ describe('EnterAddress Component', () => {
294267

295268
await waitFor(() => {
296269
expect(mockSsnFunction).toHaveBeenCalledWith('123-45-6789');
297-
expect(mockNavigateToKycProcessing).not.toHaveBeenCalled();
270+
expect(mockRouteAfterAuthentication).not.toHaveBeenCalled();
298271
});
299272
});
300273

@@ -333,7 +306,7 @@ describe('EnterAddress Component', () => {
333306
fireEvent.press(screen.getByTestId('address-continue-button'));
334307

335308
expect(screen.getByText('Please enter a valid address')).toBeOnTheScreen();
336-
expect(mockNavigateToKycProcessing).not.toHaveBeenCalled();
309+
expect(mockRouteAfterAuthentication).not.toHaveBeenCalled();
337310
});
338311

339312
it('accepts valid address line 2', async () => {
@@ -342,9 +315,7 @@ describe('EnterAddress Component', () => {
342315
fillFormAndSubmit({ addressLine2: 'Apt 4B' });
343316

344317
await waitFor(() => {
345-
expect(mockNavigateToKycProcessing).toHaveBeenCalledWith({
346-
quote: mockQuote,
347-
});
318+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
348319
});
349320
});
350321

@@ -361,7 +332,7 @@ describe('EnterAddress Component', () => {
361332
fireEvent.press(screen.getByTestId('address-continue-button'));
362333

363334
expect(screen.getByText('State/Region is required')).toBeOnTheScreen();
364-
expect(mockNavigateToKycProcessing).not.toHaveBeenCalled();
335+
expect(mockRouteAfterAuthentication).not.toHaveBeenCalled();
365336
});
366337

367338
it('displays selected region in disabled country field', () => {
@@ -387,7 +358,6 @@ describe('EnterAddress Component', () => {
387358
countryCode: 'US',
388359
});
389360
expect(mockSsnFunction).toHaveBeenCalledWith('123-45-6789');
390-
expect(mockPurposeFunction).toHaveBeenCalled();
391361
});
392362
});
393363

@@ -419,7 +389,6 @@ describe('EnterAddress Component', () => {
419389
countryCode: 'US',
420390
});
421391
expect(mockSsnFunction).not.toHaveBeenCalled();
422-
expect(mockPurposeFunction).toHaveBeenCalled();
423392
});
424393
});
425394

@@ -435,9 +404,7 @@ describe('EnterAddress Component', () => {
435404
});
436405

437406
await waitFor(() => {
438-
expect(mockNavigateToKycProcessing).toHaveBeenCalledWith({
439-
quote: mockQuote,
440-
});
407+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
441408
});
442409
});
443410
});

app/components/UI/Ramp/Deposit/Views/EnterAddress/EnterAddress.tsx

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import useAnalytics from '../../../hooks/useAnalytics';
3939
export interface EnterAddressParams {
4040
formData: BasicInfoFormData;
4141
quote: BuyQuote;
42-
kycUrl?: string;
4342
}
4443

4544
export const createEnterAddressNavDetails =
@@ -57,11 +56,8 @@ interface AddressFormData {
5756
const EnterAddress = (): JSX.Element => {
5857
const navigation = useNavigation();
5958
const { styles, theme } = useStyles(styleSheet, {});
60-
const {
61-
formData: basicInfoFormData,
62-
quote,
63-
kycUrl,
64-
} = useParams<EnterAddressParams>();
59+
const { formData: basicInfoFormData, quote } =
60+
useParams<EnterAddressParams>();
6561
const { selectedRegion } = useDepositSDK();
6662
const [loading, setLoading] = useState(false);
6763
const [error, setError] = useState<string | null>(null);
@@ -78,11 +74,10 @@ const EnterAddress = (): JSX.Element => {
7874
quote.network,
7975
);
8076

81-
const { navigateToAdditionalVerification, navigateToKycProcessing } =
82-
useDepositRouting({
83-
cryptoCurrencyChainId: cryptoCurrency?.chainId || '',
84-
paymentMethodId: quote.paymentMethod,
85-
});
77+
const { routeAfterAuthentication } = useDepositRouting({
78+
cryptoCurrencyChainId: cryptoCurrency?.chainId || '',
79+
paymentMethodId: quote.paymentMethod,
80+
});
8681

8782
const initialFormData: AddressFormData = {
8883
addressLine1: '',
@@ -180,15 +175,6 @@ const EnterAddress = (): JSX.Element => {
180175
throws: true,
181176
});
182177

183-
const [, submitPurpose] = useDepositSdkMethod(
184-
{
185-
method: 'submitPurposeOfUsageForm',
186-
onMount: false,
187-
throws: true,
188-
},
189-
['Buying/selling crypto for investments'],
190-
);
191-
192178
const [, submitSsnDetails] = useDepositSdkMethod({
193179
method: 'submitSsnDetails',
194180
onMount: false,
@@ -227,13 +213,7 @@ const EnterAddress = (): JSX.Element => {
227213
await submitSsnDetails(basicInfoFormData.ssn);
228214
}
229215

230-
await submitPurpose();
231-
232-
if (kycUrl) {
233-
navigateToAdditionalVerification({ quote, kycUrl });
234-
} else {
235-
navigateToKycProcessing({ quote });
236-
}
216+
await routeAfterAuthentication(quote);
237217
} catch (submissionError) {
238218
setLoading(false);
239219
setError(
@@ -253,12 +233,9 @@ const EnterAddress = (): JSX.Element => {
253233
basicInfoFormData,
254234
formData,
255235
postKycForm,
256-
submitPurpose,
257236
quote,
258-
kycUrl,
259-
navigateToAdditionalVerification,
260237
submitSsnDetails,
261-
navigateToKycProcessing,
238+
routeAfterAuthentication,
262239
selectedRegion?.isoCode,
263240
trackEvent,
264241
]);

app/components/UI/Ramp/Deposit/Views/KycProcessing/KycProcessing.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const mockGoBack = jest.fn();
1010
const mockSetNavigationOptions = jest.fn();
1111
const mockStopPolling = jest.fn();
1212
const mockStartPolling = jest.fn();
13-
const mockHandleApprovedKycFlow = jest.fn();
13+
const mockRouteAfterAuthentication = jest.fn();
1414

1515
const mockTrackEvent = jest.fn();
1616

@@ -78,7 +78,7 @@ jest.mock('../../../../../UI/Navbar', () => ({
7878

7979
jest.mock('../../hooks/useDepositRouting', () => ({
8080
useDepositRouting: jest.fn(() => ({
81-
handleApprovedKycFlow: mockHandleApprovedKycFlow,
81+
routeAfterAuthentication: mockRouteAfterAuthentication,
8282
})),
8383
}));
8484

@@ -95,7 +95,7 @@ describe('KycProcessing Component', () => {
9595
mockUseUserDetailsPolling.userDetails = null;
9696
mockUseUserDetailsPolling.loading = false;
9797
mockUseUserDetailsPolling.error = null;
98-
mockHandleApprovedKycFlow.mockClear();
98+
mockRouteAfterAuthentication.mockClear();
9999
mockTrackEvent.mockClear();
100100
});
101101

@@ -156,15 +156,15 @@ describe('KycProcessing Component', () => {
156156
};
157157
});
158158

159-
it('calls handleApprovedKycFlow when continue button is pressed', async () => {
160-
mockHandleApprovedKycFlow.mockResolvedValueOnce(undefined);
159+
it('calls routeAfterAuthentication when continue button is pressed', async () => {
160+
mockRouteAfterAuthentication.mockResolvedValueOnce(undefined);
161161
render(KycProcessing);
162162

163163
const continueButton = screen.getByText('Complete your order');
164164
fireEvent.press(continueButton);
165165

166166
await waitFor(() => {
167-
expect(mockHandleApprovedKycFlow).toHaveBeenCalledWith(mockQuote);
167+
expect(mockRouteAfterAuthentication).toHaveBeenCalledWith(mockQuote);
168168
});
169169
});
170170
});

app/components/UI/Ramp/Deposit/Views/KycProcessing/KycProcessing.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const KycProcessing = () => {
5454
quote.network,
5555
);
5656

57-
const { handleApprovedKycFlow } = useDepositRouting({
57+
const { routeAfterAuthentication } = useDepositRouting({
5858
cryptoCurrencyChainId: cryptoCurrency?.chainId || '',
5959
paymentMethodId: quote.paymentMethod,
6060
});
@@ -98,14 +98,14 @@ const KycProcessing = () => {
9898

9999
const handleContinue = useCallback(async () => {
100100
try {
101-
await handleApprovedKycFlow(quote);
101+
await routeAfterAuthentication(quote);
102102
} catch (error) {
103103
Logger.error(error as Error, {
104104
message: 'KycProcessing::handleContinue error',
105105
quote,
106106
});
107107
}
108-
}, [handleApprovedKycFlow, quote]);
108+
}, [routeAfterAuthentication, quote]);
109109

110110
const error = userDetailsError || kycFormsError;
111111
const hasPendingForms = kycForms && kycForms.forms.length > 0;

0 commit comments

Comments
 (0)