Skip to content

Commit 0250e8a

Browse files
committed
feat: addressing cursor bugbot comments
1 parent aa3871f commit 0250e8a

3 files changed

Lines changed: 88 additions & 8 deletions

File tree

app/component-library/components/StepperCard/StepperCard.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useRef } from 'react';
22
import { Image, TouchableOpacity } from 'react-native';
33
import {
44
Box,
@@ -33,11 +33,17 @@ const StepperCard = ({
3333

3434
const isComplete = currentStep >= steps.length;
3535

36+
const onCompleteRef = useRef(onComplete);
37+
onCompleteRef.current = onComplete;
38+
39+
const hasFiredRef = useRef(false);
40+
3641
useEffect(() => {
37-
if (isComplete) {
38-
onComplete?.();
42+
if (isComplete && !hasFiredRef.current) {
43+
hasFiredRef.current = true;
44+
onCompleteRef.current?.();
3945
}
40-
}, [isComplete, onComplete]);
46+
}, [isComplete]);
4147

4248
if (isComplete) {
4349
return null;

app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.test.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,68 @@ describe('MoneyOnboardingCard', () => {
435435
expect(mockIncrementStep).toHaveBeenCalledTimes(1);
436436
});
437437
});
438+
439+
describe('step 2 — cardholder with linked card (auto-skip)', () => {
440+
it('calls incrementStep on mount when cardholder already has a linked card token', () => {
441+
setupDefaultMocks({
442+
currentStep: 1,
443+
isCardholder: true,
444+
moneyAccountCardToken: 'tok_123',
445+
});
446+
447+
render(<MoneyOnboardingCard />);
448+
449+
expect(mockIncrementStep).toHaveBeenCalledTimes(1);
450+
});
451+
452+
it('does not call incrementStep when cardholder has no linked card token', () => {
453+
setupDefaultMocks({
454+
currentStep: 1,
455+
isCardholder: true,
456+
moneyAccountCardToken: null,
457+
});
458+
459+
render(<MoneyOnboardingCard />);
460+
461+
expect(mockIncrementStep).not.toHaveBeenCalled();
462+
});
463+
464+
it('does not call incrementStep when user is not a cardholder', () => {
465+
setupDefaultMocks({
466+
currentStep: 1,
467+
isCardholder: false,
468+
moneyAccountCardToken: 'tok_123',
469+
});
470+
471+
render(<MoneyOnboardingCard />);
472+
473+
expect(mockIncrementStep).not.toHaveBeenCalled();
474+
});
475+
476+
it('does not call incrementStep when currentStep is not 1', () => {
477+
setupDefaultMocks({
478+
currentStep: 0,
479+
isCardholder: true,
480+
moneyAccountCardToken: 'tok_123',
481+
});
482+
483+
render(<MoneyOnboardingCard />);
484+
485+
expect(mockIncrementStep).not.toHaveBeenCalled();
486+
});
487+
});
488+
489+
describe('steps memo guard — card hidden', () => {
490+
it('renders null and shows no step content when currentStep equals MONEY_ONBOARDING_TOTAL_STEPS', () => {
491+
setupDefaultMocks({ currentStep: MONEY_ONBOARDING_TOTAL_STEPS });
492+
493+
const { toJSON, queryByText } = render(<MoneyOnboardingCard />);
494+
495+
expect(toJSON()).toBeNull();
496+
expect(queryByText(strings('money.onboarding.step_1.title'))).toBeNull();
497+
expect(
498+
queryByText(strings('money.onboarding.step_2.no_card_account.title')),
499+
).toBeNull();
500+
});
501+
});
438502
});

app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,21 @@ const MoneyOnboardingCard = () => {
197197
moneyAccountCardToken,
198198
]);
199199

200+
/**
201+
* Auto-skip step 2 ("Get/Link your MetaMask Card") when the user is already
202+
* a cardholder AND has a linked card token
203+
*/
204+
useEffect(() => {
205+
if (currentStep === 1 && isCardholder && !!moneyAccountCardToken) {
206+
incrementStep();
207+
}
208+
}, [currentStep, incrementStep, isCardholder, moneyAccountCardToken]);
209+
200210
// REMINDER: To update MONEY_ONBOARDING_TOTAL_STEPS when the number of steps is changed.
201-
const steps = useMemo(
202-
() => [getStep1Content(), getStep2Content()],
203-
[getStep1Content, getStep2Content],
204-
);
211+
const steps = useMemo(() => {
212+
if (!isOnboardingCardVisible) return [];
213+
return [getStep1Content(), getStep2Content()];
214+
}, [isOnboardingCardVisible, getStep1Content, getStep2Content]);
205215

206216
if (!isOnboardingCardVisible) {
207217
return null;

0 commit comments

Comments
 (0)