From 910dd011e0c5867e4e12fa6460e6ba9c45892052 Mon Sep 17 00:00:00 2001 From: LucasBeneston Date: Thu, 16 Jan 2025 14:53:15 +0100 Subject: [PATCH 1/5] (PC-33955) feat(creditV3): update onboarding timeline for 17 and 18 years old --- .../OnboardingTimeline.native.test.tsx | 103 ++++++++++++++++++ .../onboarding/OnboardingTimeline.tsx | 53 +++++---- 2 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 src/features/tutorial/components/onboarding/OnboardingTimeline.native.test.tsx diff --git a/src/features/tutorial/components/onboarding/OnboardingTimeline.native.test.tsx b/src/features/tutorial/components/onboarding/OnboardingTimeline.native.test.tsx new file mode 100644 index 00000000000..19e0601724c --- /dev/null +++ b/src/features/tutorial/components/onboarding/OnboardingTimeline.native.test.tsx @@ -0,0 +1,103 @@ +import React from 'react' + +import { OnboardingTimeline } from 'features/tutorial/components/onboarding/OnboardingTimeline' +import { setFeatureFlags } from 'libs/firebase/firestore/featureFlags/__tests__/setFeatureFlags' +import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types' +import { useDepositAmountsByAge } from 'shared/user/useDepositAmountsByAge' +import { render, screen } from 'tests/utils' + +jest.mock('shared/user/useDepositAmountsByAge') +const mockUseDepositAmountsByAge = useDepositAmountsByAge as jest.Mock +mockUseDepositAmountsByAge.mockReturnValue({ eighteenYearsOldDeposit: '300 €' }) + +describe('OnboardingTimeline', () => { + describe('when enableCreditV3 not activated', () => { + beforeEach(() => setFeatureFlags()) + + it('should display fifteen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 15 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display sixteen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 16 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display seventeen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 17 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display eighteen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 18 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display eighteen years old description', () => { + render() + + const description = screen.getByText(`Tu auras 2 ans pour utiliser tes 300 €`) + + expect(description).toBeOnTheScreen() + }) + }) + + describe('when enableCreditV3 activated', () => { + beforeEach(() => setFeatureFlags([RemoteStoreFeatureFlags.ENABLE_CREDIT_V3])) + + it('should not display fifteen years old block', () => { + render() + + const blockTitle = screen.queryByText(`à 15 ans`) + + expect(blockTitle).not.toBeOnTheScreen() + }) + + it('should not display sixteen years old block', () => { + render() + + const blockTitle = screen.queryByText(`à 16 ans`) + + expect(blockTitle).not.toBeOnTheScreen() + }) + + it('should display seventeen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 17 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display eighteen years old block', () => { + render() + + const blockTitle = screen.getByText(`à 18 ans`) + + expect(blockTitle).toBeOnTheScreen() + }) + + it('should display eighteen years old description', () => { + render() + + const description = screen.getByText( + 'Tu as jusqu’à la veille de tes 21 ans pour utiliser ton crédit.' + ) + + expect(description).toBeOnTheScreen() + }) + }) +}) diff --git a/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx b/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx index 49c8d25db3f..3a6f18443b8 100644 --- a/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx +++ b/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx @@ -3,6 +3,8 @@ import styled from 'styled-components/native' import { CreditComponentProps, CreditTimeline } from 'features/tutorial/components/CreditTimeline' import { TutorialTypes } from 'features/tutorial/enums' +import { useFeatureFlag } from 'libs/firebase/firestore/featureFlags/useFeatureFlag' +import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types' import { useDepositAmountsByAge } from 'shared/user/useDepositAmountsByAge' import { Spacer, TypoDS, getSpacing, getSpacingString } from 'ui/theme' @@ -11,37 +13,33 @@ interface Props { } export const OnboardingTimeline: FunctionComponent = ({ age }) => { + const enableCreditV3 = useFeatureFlag(RemoteStoreFeatureFlags.ENABLE_CREDIT_V3) + const stepperPropsMapping = enableCreditV3 ? stepperPropsMappingV2 : stepperPropsMappingV1 + const stepperProps = stepperPropsMapping.get(age) if (!stepperProps) return null return } -const DescriptionText = styled(TypoDS.BodyAccentXs)(({ theme }) => ({ - fontSize: theme.tabBar.fontSize, - lineHeight: getSpacingString(3), - color: theme.colors.greyDark, -})) - -const CreditBlockContent = () => { +const CreditBlockContent: FunctionComponent<{ enableCreditV3: boolean }> = ({ enableCreditV3 }) => { const { eighteenYearsOldDeposit } = useDepositAmountsByAge() + + const description = enableCreditV3 + ? 'Tu as jusqu’à la veille de tes 21 ans pour utiliser ton crédit.' + : `Tu auras 2 ans pour utiliser tes ${eighteenYearsOldDeposit}` + return ( - Tu auras 2 ans pour utiliser tes {eighteenYearsOldDeposit} + {description} ) } const CreditResetBlock = () => Remise à 0 du crédit -const StyledBody = styled(TypoDS.Body)({ - marginVertical: getSpacing(2), - marginLeft: getSpacing(1.5), - justifyContent: 'center', -}) - -const stepperPropsMapping = new Map([ +const stepperPropsMappingV1 = new Map([ [ 15, [ @@ -49,7 +47,7 @@ const stepperPropsMapping = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -59,7 +57,7 @@ const stepperPropsMapping = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -69,7 +67,7 @@ const stepperPropsMapping = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -78,7 +76,24 @@ const stepperPropsMapping = new Map([ { creditStep: 15 }, { creditStep: 16 }, { creditStep: 17 }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], ]) + +const stepperPropsMappingV2 = new Map([ + [17, [{ creditStep: 17 }, { creditStep: 18, children: }]], + [18, [{ creditStep: 17 }, { creditStep: 18, children: }]], +]) + +const StyledBody = styled(TypoDS.Body)({ + marginVertical: getSpacing(2), + marginLeft: getSpacing(1.5), + justifyContent: 'center', +}) + +const DescriptionText = styled(TypoDS.BodyAccentXs)(({ theme }) => ({ + fontSize: theme.tabBar.fontSize, + lineHeight: getSpacingString(3), + color: theme.colors.greyDark, +})) From 46a79d1a28c34daa5e4213801de7b54e1eb3e435 Mon Sep 17 00:00:00 2001 From: LucasBeneston Date: Thu, 16 Jan 2025 14:57:44 +0100 Subject: [PATCH 2/5] (PC-33955) feat(creditV3): update spacer in CreditTimeline --- ...AgeInformation.native.test.tsx.native-snap | 164 +++++++++--------- ...AgeInformation.native.test.tsx.native-snap | 96 +++++----- .../tutorial/components/CreditTimeline.tsx | 13 +- 3 files changed, 134 insertions(+), 139 deletions(-) diff --git a/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap b/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap index d9d604526c9..964e07cacad 100644 --- a/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap +++ b/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap @@ -309,11 +309,11 @@ exports[`OnboardingAgeInformation should render correctly for 15-year-old 1`] = } > - Tu auras 2 ans pour utiliser tes - 300 € + Tu auras 2 ans pour utiliser tes 300 € - Tu auras 2 ans pour utiliser tes - 300 € + Tu auras 2 ans pour utiliser tes 300 € - Tu auras 2 ans pour utiliser tes - 300 € + Tu auras 2 ans pour utiliser tes 300 € - Tu auras 2 ans pour utiliser tes - 300 € + Tu auras 2 ans pour utiliser tes 300 € should display not logged in version } > should display not logged in version should display not logged in version } > should display not logged in version should display not logged in version } > should display not logged in version should display not logged in version } > should display not logged in version } /> should display not logged in version } > should display not logged in version should display not logged in version } > should display not logged in version Tu peux continuer à réserver des offres gratuites autour de chez toi. should render correctly when logged i } > should render correctly when logged i should render correctly when logged i } > should render correctly when logged i should render correctly when logged i } > should render correctly when logged i should render correctly when logged i } > should render correctly when logged i } /> should render correctly when logged i } > should render correctly when logged i should render correctly when logged i } > should render correctly when logged i Tu peux continuer à réserver des offres gratuites autour de chez toi. { [17, seventeenYearsOldDeposit], [18, eighteenYearsOldDeposit], ]) - const SpaceBetweenBlock = type === TutorialTypes.ONBOARDING ? 1 : 3 const CreditBlockTitle = type === TutorialTypes.ONBOARDING ? OnboardingCreditBlockTitle : ProfileTutorialCreditBlockTitle @@ -65,9 +64,9 @@ export const CreditTimeline = ({ stepperProps, age, type, testID }: Props) => { variant={StepVariant.future} isLast={isLast} iconComponent={iconComponent}> - + {props.children} - + ) } @@ -81,9 +80,9 @@ export const CreditTimeline = ({ stepperProps, age, type, testID }: Props) => { variant={StepVariant.complete} isFirst={isFirst} iconComponent={iconComponent}> - + {props.children} - + ) } @@ -97,7 +96,7 @@ export const CreditTimeline = ({ stepperProps, age, type, testID }: Props) => { iconComponent={getStepperIconFromCreditStatus(creditStatus)} isFirst={isFirst} isLast={isLast}> - + { {props.children} - + ) })} From 918655a03ccf9e2b197af2432c4401fa35bee15e Mon Sep 17 00:00:00 2001 From: LucasBeneston Date: Thu, 16 Jan 2025 14:58:19 +0100 Subject: [PATCH 3/5] (PC-33955) feat(creditV3): add credit V3 tests in OnboardingAgeInformation pages --- ...AgeInformation.native.test.tsx.native-snap | 2901 +++++++++++++++++ .../OnboardingAgeInformation.native.test.tsx | 10 + 2 files changed, 2911 insertions(+) diff --git a/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap b/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap index 964e07cacad..91e0df0d83b 100644 --- a/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap +++ b/__snapshots__/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx.native-snap @@ -6359,3 +6359,2904 @@ exports[`OnboardingAgeInformation should render correctly for 18-year-old 1`] = />, ] `; + +exports[`OnboardingAgeInformation when enableCreditV3 activated should render correctly for 15-year-old 1`] = ` +[ + , + + + + + + + icon-back-SVG-Mock + + + + Retour + + + + , + + + + + + À 15 ans, profite de ton pass Culture ! + + + + Comment ça marche ? + + + + + , + + + + + undefined-SVG-Mock + + + + + Créer un compte + + + + + + + + + + button-icon-left-SVG-Mock + + + + + + Plus tard + + + + , + , +] +`; + +exports[`OnboardingAgeInformation when enableCreditV3 activated should render correctly for 16-year-old 1`] = ` +[ + , + + + + + + + icon-back-SVG-Mock + + + + Retour + + + + , + + + + + + À 16 ans, profite de ton pass Culture ! + + + + Comment ça marche ? + + + + + , + + + + + undefined-SVG-Mock + + + + + Créer un compte + + + + + + + + + + button-icon-left-SVG-Mock + + + + + + Plus tard + + + + , + , +] +`; + +exports[`OnboardingAgeInformation when enableCreditV3 activated should render correctly for 17-year-old 1`] = ` +[ + , + + + + + + + icon-back-SVG-Mock + + + + Retour + + + + , + + + + + + À 17 ans, profite de ton pass Culture ! + + + + Comment ça marche ? + + + + + + + + + + undefined-Lottie-Mock + + + + + + + + + + + + + à 17 ans + + + + 30 € + + + + + + cette année + + + + + + + + + + + + + + + + + undefined-SVG-Mock + + + + + + + + + + + + à 18 ans + + + + 300 € + + + + Tu as jusqu’à la veille de tes 21 ans pour utiliser ton crédit. + + + + + + à venir + + + + + + + + + + + , + + + + + undefined-SVG-Mock + + + + + Créer un compte + + + + + + + + + + button-icon-left-SVG-Mock + + + + + + Plus tard + + + + , + , +] +`; + +exports[`OnboardingAgeInformation when enableCreditV3 activated should render correctly for 18-year-old 1`] = ` +[ + , + + + + + + + icon-back-SVG-Mock + + + + Retour + + + + , + + + + + + À 18 ans, profite de ton pass Culture ! + + + + Comment ça marche ? + + + + + + + + + + + undefined-SVG-Mock + + + + + + + + + + + + à 17 ans + + + + 30 € + + + + + + passé + + + + + + + + + + + + + + undefined-Lottie-Mock + + + + + + + + + + + à 18 ans + + + + 300 € + + + + Tu as jusqu’à la veille de tes 21 ans pour utiliser ton crédit. + + + + + + cette année + + + + + + + + + + + , + + + + + undefined-SVG-Mock + + + + + Créer un compte + + + + + + + + + + button-icon-left-SVG-Mock + + + + + + Plus tard + + + + , + , +] +`; diff --git a/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx b/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx index 9ac0b648c62..3da4d72cb14 100644 --- a/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx +++ b/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx @@ -127,6 +127,16 @@ describe('OnboardingAgeInformation', () => { type: 'account_creation_skipped', }) }) + + describe('when enableCreditV3 activated', () => { + beforeEach(() => setFeatureFlags([RemoteStoreFeatureFlags.ENABLE_CREDIT_V3])) + + it.each(AGES)('should render correctly for %s-year-old', (age) => { + renderOnboardingAgeInformation({ age }) + + expect(screen).toMatchSnapshot() + }) + }) }) const renderOnboardingAgeInformation = (navigationParams: { age: number }) => { From defa7d812c59a51e6df40a1a6dcecbb71ab2a773 Mon Sep 17 00:00:00 2001 From: LucasBeneston Date: Thu, 16 Jan 2025 15:12:46 +0100 Subject: [PATCH 4/5] (PC-33955) feat(creditV3): add key in OnboardingTimeline --- .../onboarding/OnboardingTimeline.tsx | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx b/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx index 3a6f18443b8..7916fbbef62 100644 --- a/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx +++ b/src/features/tutorial/components/onboarding/OnboardingTimeline.tsx @@ -47,7 +47,7 @@ const stepperPropsMappingV1 = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -57,7 +57,7 @@ const stepperPropsMappingV1 = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -67,7 +67,7 @@ const stepperPropsMappingV1 = new Map([ { creditStep: 16 }, { creditStep: 17 }, { creditStep: 'information', children: }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], [ @@ -76,14 +76,26 @@ const stepperPropsMappingV1 = new Map([ { creditStep: 15 }, { creditStep: 16 }, { creditStep: 17 }, - { creditStep: 18, children: }, + { creditStep: 18, children: }, ], ], ]) const stepperPropsMappingV2 = new Map([ - [17, [{ creditStep: 17 }, { creditStep: 18, children: }]], - [18, [{ creditStep: 17 }, { creditStep: 18, children: }]], + [ + 17, + [ + { creditStep: 17 }, + { creditStep: 18, children: }, + ], + ], + [ + 18, + [ + { creditStep: 17 }, + { creditStep: 18, children: }, + ], + ], ]) const StyledBody = styled(TypoDS.Body)({ From 9f2196283eabb9a66ba1b9ba71e730e52e184efe Mon Sep 17 00:00:00 2001 From: LucasBeneston Date: Thu, 16 Jan 2025 15:17:26 +0100 Subject: [PATCH 5/5] (PC-33955) feat(creditV3): use userEvent instead fireEvent in OnboardingAgeInformation --- .../OnboardingAgeInformation.native.test.tsx | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx b/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx index 3da4d72cb14..46ed5ff2321 100644 --- a/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx +++ b/src/features/tutorial/pages/onboarding/OnboardingAgeInformation.native.test.tsx @@ -11,7 +11,7 @@ import { analytics } from 'libs/analytics' import { setFeatureFlags } from 'libs/firebase/firestore/featureFlags/__tests__/setFeatureFlags' import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types' import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' -import { fireEvent, render, screen, waitFor } from 'tests/utils' +import { userEvent, render, screen } from 'tests/utils' jest.spyOn(useGoBack, 'useGoBack').mockReturnValue({ goBack: jest.fn(), @@ -28,6 +28,9 @@ jest.mock('react-native/Libraries/Animated/createAnimatedComponent', () => { jest.mock('libs/firebase/firestore/exchangeRates/useGetPacificFrancToEuroRate') +const user = userEvent.setup() +jest.useFakeTimers() + describe('OnboardingAgeInformation', () => { beforeEach(() => { setFeatureFlags([RemoteStoreFeatureFlags.ENABLE_PACIFIC_FRANC_CURRENCY]) @@ -66,23 +69,21 @@ describe('OnboardingAgeInformation', () => { renderOnboardingAgeInformation({ age }) const signupButton = screen.getByTestId('Créer un compte') - fireEvent.press(signupButton) + await user.press(signupButton) - await waitFor(() => { - expect(navigate).toHaveBeenCalledWith('SignupForm', { - from: StepperOrigin.TUTORIAL, - }) + expect(navigate).toHaveBeenCalledWith('SignupForm', { + from: StepperOrigin.TUTORIAL, }) } ) it.each(AGES)( 'should reset navigation on go to Home when pressing "Plus tard" for %s-year-old', - (age) => { + async (age) => { renderOnboardingAgeInformation({ age }) const laterButton = screen.getByTestId('Plus tard') - fireEvent.press(laterButton) + await user.press(laterButton) expect(reset).toHaveBeenCalledWith({ index: 0, @@ -91,22 +92,22 @@ describe('OnboardingAgeInformation', () => { } ) - it.each(AGES)('should log analytics when attempting to click on credit block', (age) => { + it.each(AGES)('should log analytics when attempting to click on credit block', async (age) => { renderOnboardingAgeInformation({ age }) const creditBlock = screen.getByText(`à ${age} ans`) - fireEvent.press(creditBlock) + await user.press(creditBlock) expect(analytics.logTrySelectDeposit).toHaveBeenCalledWith(age) }) - it.each(AGES)('should log analytics when clicking on signup button', (age) => { + it.each(AGES)('should log analytics when clicking on signup button', async (age) => { renderOnboardingAgeInformation({ age }) const signupButton = screen.getByText('Créer un compte') - fireEvent.press(signupButton) + await user.press(signupButton) expect(analytics.logOnboardingAgeInformationClicked).toHaveBeenNthCalledWith(1, { type: 'account_creation', @@ -116,12 +117,12 @@ describe('OnboardingAgeInformation', () => { }) }) - it.each(AGES)('should log analytics when clicking on skip button', (age) => { + it.each(AGES)('should log analytics when clicking on skip button', async (age) => { renderOnboardingAgeInformation({ age }) const laterButton = screen.getByText('Plus tard') - fireEvent.press(laterButton) + await user.press(laterButton) expect(analytics.logOnboardingAgeInformationClicked).toHaveBeenNthCalledWith(1, { type: 'account_creation_skipped',