Skip to content

Commit

Permalink
(PC-32481) feat(culturalSurvey): use needsToFillCulturalSurvey in use…
Browse files Browse the repository at this point in the history
…StepperInfo
  • Loading branch information
Lucasbeneston committed Oct 18, 2024
1 parent b845704 commit 3edef23
Show file tree
Hide file tree
Showing 23 changed files with 308 additions and 144 deletions.
4 changes: 2 additions & 2 deletions src/features/auth/api/useSignIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { useDeviceInfo } from 'features/trustedDevice/helpers/useDeviceInfo'
import { analytics } from 'libs/analytics'
import { LoginRoutineMethod, SSOType } from 'libs/analytics/logEventAnalytics'
import { storage } from 'libs/storage'
import { useShouldShowCulturalSurvey } from 'shared/culturalSurvey/useShouldShowCulturalSurvey'
import { useShouldShowCulturalSurveyForBeneficiaryUser } from 'shared/culturalSurvey/useShouldShowCulturalSurveyForBeneficiaryUser'

export const useSignIn = ({
params,
Expand Down Expand Up @@ -73,7 +73,7 @@ const useHandleSigninSuccess = (
setErrorMessage?: (message: string) => void
) => {
const { navigate } = useNavigation<UseNavigationType>()
const shouldShowCulturalSurvey = useShouldShowCulturalSurvey()
const shouldShowCulturalSurvey = useShouldShowCulturalSurveyForBeneficiaryUser()

const onAddFavoriteSuccess = useCallback((data?: FavoriteResponse) => {
if (data?.offer?.id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { mockServer } from 'tests/mswServer'
import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC'
import { act, fireEvent, render, screen } from 'tests/utils'

jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag').mockReturnValue(true)

jest.mock('libs/monitoring')
jest.mock('libs/react-native-device-info/getDeviceId')
jest.mock('features/identityCheck/context/SubscriptionContextProvider', () => ({
Expand All @@ -24,7 +26,6 @@ jest.mock('features/identityCheck/context/SubscriptionContextProvider', () => ({

jest.mock('libs/network/NetInfoWrapper')

const useFeatureFlagSpy = jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag').mockReturnValue(false)
const apiPostGoogleAuthorize = jest.spyOn(API.api, 'postNativeV1OauthGoogleAuthorize')
const getModelSpy = jest.spyOn(DeviceInfo, 'getModel')
const getSystemNameSpy = jest.spyOn(DeviceInfo, 'getSystemName')
Expand Down Expand Up @@ -56,7 +57,6 @@ describe('<SSOButton />', () => {
})

it('should sign in with device info when sso button is clicked', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
getModelSpy.mockReturnValueOnce('iPhone 13')
getSystemNameSpy.mockReturnValueOnce('iOS')
mockServer.postApi<SigninResponse>('/v1/oauth/google/authorize', {
Expand All @@ -82,7 +82,6 @@ describe('<SSOButton />', () => {
})

it('should call onSignInFailure when signin fails', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
mockServer.postApi<SigninResponse>('/v1/oauth/google/authorize', {
responseOptions: { statusCode: 500 },
})
Expand All @@ -97,7 +96,6 @@ describe('<SSOButton />', () => {
})

it('should log analytics when logging in with sso from signup', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
mockServer.postApi<SigninResponse>('/v1/oauth/google/authorize', {
accessToken: 'accessToken',
refreshToken: 'refreshToken',
Expand All @@ -113,7 +111,6 @@ describe('<SSOButton />', () => {
})

it('should log analytics when logging in with sso from login', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
mockServer.postApi<SigninResponse>('/v1/oauth/google/authorize', {
accessToken: 'accessToken',
refreshToken: 'refreshToken',
Expand All @@ -137,7 +134,6 @@ describe('<SSOButton />', () => {
})

it('should not log to Sentry on SSO login error', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
jest.spyOn(GoogleSignin, 'signIn').mockRejectedValueOnce('GoogleSignIn Error')

renderSSOButton()
Expand All @@ -160,7 +156,6 @@ describe('<SSOButton />', () => {
})

it('should log to Sentry on SSO login error', async () => {
useFeatureFlagSpy.mockReturnValueOnce(true)
jest.spyOn(GoogleSignin, 'signIn').mockRejectedValueOnce('GoogleSignIn Error')

renderSSOButton()
Expand Down
45 changes: 33 additions & 12 deletions src/features/auth/pages/login/Login.native.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import { navigateToHome } from 'features/navigation/helpers/navigateToHome'
import { usePreviousRoute } from 'features/navigation/helpers/usePreviousRoute'
import { StepperOrigin } from 'features/navigation/RootNavigator/types'
import { FAKE_USER_ID } from 'fixtures/fakeUserId'
import { beneficiaryUser } from 'fixtures/user'
import { analytics } from 'libs/analytics'
// eslint-disable-next-line no-restricted-imports
import { firebaseAnalytics } from 'libs/firebase/analytics'
import * as useFeatureFlagAPI from 'libs/firebase/firestore/featureFlags/useFeatureFlag'
import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types'
import { captureMonitoringError } from 'libs/monitoring'
import { NetworkErrorFixture, UnknownErrorFixture } from 'libs/recaptcha/fixtures'
import { storage } from 'libs/storage'
Expand All @@ -36,6 +38,10 @@ import { SUGGESTION_DELAY_IN_MS } from 'ui/components/inputs/EmailInputWithSpell
import { SNACK_BAR_TIME_OUT_LONG } from 'ui/components/snackBar/SnackBarContext'

import { Login } from './Login'

const useFeatureFlagSpy = jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag')
jest.mock('libs/firebase/remoteConfig/remoteConfig.services')

jest.mock('libs/network/NetInfoWrapper')

jest.mock('libs/monitoring')
Expand Down Expand Up @@ -68,7 +74,6 @@ const apiSignInSpy = jest.spyOn(API.api, 'postNativeV1Signin')
const apiPostGoogleAuthorize = jest.spyOn(API.api, 'postNativeV1OauthGoogleAuthorize')
const getModelSpy = jest.spyOn(DeviceInfo, 'getModel')
const getSystemNameSpy = jest.spyOn(DeviceInfo, 'getSystemName')
const useFeatureFlagSpy = jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag').mockReturnValue(false)

jest.useFakeTimers()

Expand All @@ -93,6 +98,7 @@ jest.mock('react-native/Libraries/Animated/createAnimatedComponent', () => {

describe('<Login/>', () => {
beforeEach(() => {
activateFeatureFlags([RemoteStoreFeatureFlags.WIP_ENABLE_GOOGLE_SSO])
mockServer.postApi<FavoriteResponse>('/v1/me/favorites', favoriteResponseSnap)
mockServer.getApi<OauthStateResponse>('/v1/oauth/state', {
oauthStateToken: 'oauth_state_token',
Expand All @@ -110,10 +116,6 @@ describe('<Login/>', () => {
})

it('should render correctly when feature flag is enabled', async () => {
// We use this hook twice but due to multiple rerender we have to mock the return value this way
// eslint-disable-next-line local-rules/independent-mocks
useFeatureFlagSpy.mockReturnValue(true)

renderLogin()

await screen.findByText('Connecte-toi')
Expand Down Expand Up @@ -145,9 +147,6 @@ describe('<Login/>', () => {
})

it('should sign in when SSO button is clicked with device info', async () => {
// We use this hook twice but due to multiple rerender we have to mock the return value this way
// eslint-disable-next-line local-rules/independent-mocks
useFeatureFlagSpy.mockReturnValue(true)
getModelSpy.mockReturnValueOnce('iPhone 13')
getSystemNameSpy.mockReturnValueOnce('iOS')
mockServer.postApi<SigninResponse>('/v1/oauth/google/authorize', {
Expand Down Expand Up @@ -256,6 +255,25 @@ describe('<Login/>', () => {
})

it('should redirect to NATIVE Cultural Survey WHEN signin is successful and user needs to fill cultural survey', async () => {
activateFeatureFlags([RemoteStoreFeatureFlags.WIP_ENABLE_GOOGLE_SSO])
activateFeatureFlags() // disabled ENABLE_CULTURAL_SURVEY_MANDATORY feature flag

mockMeApiCall({
...beneficiaryUser,
needsToFillCulturalSurvey: true,
showEligibleCard: false,
} as UserProfileResponse)
renderLogin()

await fillInputs()
await act(() => fireEvent.press(screen.getByText('Se connecter')))

expect(navigate).toHaveBeenNthCalledWith(1, 'CulturalSurveyIntro')
})

it('should redirect to home WHEN signin is successful and ENABLE_CULTURAL_SURVEY_MANDATORY enabled', async () => {
activateFeatureFlags([RemoteStoreFeatureFlags.WIP_ENABLE_GOOGLE_SSO])
activateFeatureFlags([RemoteStoreFeatureFlags.ENABLE_CULTURAL_SURVEY_MANDATORY])
mockMeApiCall({
needsToFillCulturalSurvey: true,
showEligibleCard: false,
Expand All @@ -265,8 +283,7 @@ describe('<Login/>', () => {
await fillInputs()
await act(() => fireEvent.press(screen.getByText('Se connecter')))

expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith('CulturalSurveyIntro')
expect(navigateToHome).toHaveBeenCalledTimes(1)
})

it('should not redirect to EighteenBirthday WHEN signin is successful and user has already seen eligible card and needs to see it', async () => {
Expand Down Expand Up @@ -482,8 +499,7 @@ describe('<Login/>', () => {

await screen.findByText('Connecte-toi')

expect(analytics.logStepperDisplayed).toHaveBeenCalledTimes(1)
expect(analytics.logStepperDisplayed).toHaveBeenCalledWith(StepperOrigin.PROFILE, 'Login')
expect(analytics.logStepperDisplayed).toHaveBeenNthCalledWith(1, StepperOrigin.PROFILE, 'Login')
})

it('should log analytics when clicking on "Créer un compte" button', async () => {
Expand Down Expand Up @@ -598,6 +614,7 @@ describe('<Login/>', () => {

it('should redirect to CulturalSurveyIntro instead of Offer when user needs to fill it', async () => {
mockMeApiCall({
...beneficiaryUser,
needsToFillCulturalSurvey: true,
showEligibleCard: false,
} as UserProfileResponse)
Expand Down Expand Up @@ -886,3 +903,7 @@ function simulateSigninNetworkFailure() {
function simulateAddToFavorites() {
mockServer.postApi<FavoriteResponse>('/v1/me/favorites', favoriteResponseSnap)
}

const activateFeatureFlags = (activeFeatureFlags: RemoteStoreFeatureFlags[] = []) => {
useFeatureFlagSpy.mockImplementation((flag) => activeFeatureFlags.includes(flag))
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import { ShareAppWrapper } from 'features/share/context/ShareAppWrapper'
import { ShareAppModalType } from 'features/share/types'
import { beneficiaryUser } from 'fixtures/user'
import { analytics } from 'libs/analytics'
import * as useFeatureFlagAPI from 'libs/firebase/firestore/featureFlags/useFeatureFlag'
import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types'
import { BatchUser } from 'libs/react-native-batch'
import { mockAuthContextWithUser } from 'tests/AuthContextUtils'
import { fireEvent, render, screen, waitFor } from 'tests/utils'

import { AccountCreated } from './AccountCreated'

const useFeatureFlagSpy = jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag')
jest.mock('libs/firebase/remoteConfig/remoteConfig.services')
jest.mock('features/profile/api/useResetRecreditAmountToShow')
jest.mock('features/navigation/helpers/navigateToHome')
jest.mock('features/navigation/navigationRef')
Expand All @@ -40,6 +44,10 @@ jest.mock('react-native/Libraries/Animated/createAnimatedComponent', () => {
})

describe('<AccountCreated />', () => {
beforeEach(() => {
activateFeatureFlags()
})

it('should render correctly', async () => {
renderAccountCreated()

Expand All @@ -55,8 +63,20 @@ describe('<AccountCreated />', () => {

await waitFor(() => {
expect(navigateFromRef).not.toHaveBeenCalled()
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith('CulturalSurveyIntro', undefined)
expect(navigate).toHaveBeenNthCalledWith(1, 'CulturalSurveyIntro', undefined)
})
})

it('should redirect to home page WHEN "On y va !" button is clicked BUT feature flag enableCulturalSurveyMandatory is enabled', async () => {
activateFeatureFlags([RemoteStoreFeatureFlags.ENABLE_CULTURAL_SURVEY_MANDATORY])
renderAccountCreated()
fireEvent.press(await screen.findByLabelText('On y va\u00a0!'))
await waitFor(() => {
expect(navigateFromRef).toHaveBeenCalledWith(
navigateToHomeConfig.screen,
navigateToHomeConfig.params
)
expect(navigate).not.toHaveBeenCalledWith('CulturalSurvey', undefined)
})
})

Expand Down Expand Up @@ -105,3 +125,6 @@ const renderAccountCreated = () =>
render(<AccountCreated />, {
wrapper: ShareAppWrapper,
})
const activateFeatureFlags = (activeFeatureFlags: RemoteStoreFeatureFlags[] = []) => {
useFeatureFlagSpy.mockImplementation((flag) => activeFeatureFlags.includes(flag))
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useShareAppContext } from 'features/share/context/ShareAppWrapper'
import { ShareAppModalType } from 'features/share/types'
import { analytics } from 'libs/analytics'
import { BatchEvent, BatchUser } from 'libs/react-native-batch'
import { useShouldShowCulturalSurvey } from 'shared/culturalSurvey/useShouldShowCulturalSurvey'
import { useShouldShowCulturalSurveyForBeneficiaryUser } from 'shared/culturalSurvey/useShouldShowCulturalSurveyForBeneficiaryUser'
import IlluminatedSmileyAnimation from 'ui/animations/lottie_illuminated_smiley.json'
import { ButtonPrimaryWhite } from 'ui/components/buttons/ButtonPrimaryWhite'
import { InternalTouchableLink } from 'ui/components/touchableLink/InternalTouchableLink'
Expand All @@ -17,7 +17,7 @@ import { Typo } from 'ui/theme'
export function AccountCreated() {
const { user } = useAuthContext()
const { showShareAppModal } = useShareAppContext()
const shouldShowCulturalSurvey = useShouldShowCulturalSurvey()
const shouldShowCulturalSurvey = useShouldShowCulturalSurveyForBeneficiaryUser()

const shouldNavigateToCulturalSurvey = shouldShowCulturalSurvey(user)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react'

import * as useFeatureFlagAPI from 'libs/firebase/firestore/featureFlags/useFeatureFlag'
import { checkAccessibilityFor, render, screen } from 'tests/utils/web'

import { AccountCreated } from './AccountCreated'

jest.mock('libs/firebase/analytics/analytics')
jest.spyOn(useFeatureFlagAPI, 'useFeatureFlag').mockReturnValue(false)
jest.mock('libs/firebase/remoteConfig/remoteConfig.services')

jest.mock('libs/firebase/analytics/analytics')

jest.mock('react-native-safe-area-context', () => ({
...(jest.requireActual('react-native-safe-area-context') as Record<string, unknown>),
useSafeAreaInsets: () => ({ bottom: 16, right: 16, left: 16, top: 16 }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ describe('<SetEmail />', () => {

useFeatureFlagSpy.mockReturnValueOnce(true) // first call in SetEmail
useFeatureFlagSpy.mockReturnValueOnce(true) // second call in useOAuthState
useFeatureFlagSpy.mockReturnValueOnce(true) // third call in CulturalSurvey

renderSetEmail()

Expand Down Expand Up @@ -323,6 +324,7 @@ describe('<SetEmail />', () => {

useFeatureFlagSpy.mockReturnValueOnce(true) // first call in SetEmail
useFeatureFlagSpy.mockReturnValueOnce(true) // second call in useOAuthState
useFeatureFlagSpy.mockReturnValueOnce(true) // third call in CulturalSurvey

renderSetEmail()

Expand Down
4 changes: 2 additions & 2 deletions src/features/culturalSurvey/api/useCulturalSurveyQuestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { CulturalSurveyQuestionsResponse } from 'api/gen'
import { useAuthContext } from 'features/auth/context/AuthContext'
import { useNetInfoContext } from 'libs/network/NetInfoWrapper'
import { QueryKeys } from 'libs/queryKeys'
import { useShouldShowCulturalSurvey } from 'shared/culturalSurvey/useShouldShowCulturalSurvey'
import { useShouldShowCulturalSurveyForBeneficiaryUser } from 'shared/culturalSurvey/useShouldShowCulturalSurveyForBeneficiaryUser'

const STALE_TIME_CULTURAL_SURVEY_QUESTIONS = 5 * 60 * 1000

export function useCulturalSurveyQuestions() {
const { user, isLoggedIn } = useAuthContext()
const netInfo = useNetInfoContext()
const shouldShowCulturalSurvey = useShouldShowCulturalSurvey()
const shouldShowCulturalSurvey = useShouldShowCulturalSurveyForBeneficiaryUser()
const shouldRequestCulturalSurveyQuestions = shouldShowCulturalSurvey(user)

return useQuery<CulturalSurveyQuestionsResponse>(
Expand Down
Loading

0 comments on commit 3edef23

Please sign in to comment.