Skip to content

Commit

Permalink
chore(DIA-942): test auth2 login welcome step (#11183)
Browse files Browse the repository at this point in the history
* Listed the things I want to test.

* started implementing tests

* chore(DIA-942): test auth2 login welcome step
  • Loading branch information
iskounen authored Nov 22, 2024
1 parent 33311b8 commit eda9e92
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 8 deletions.
23 changes: 20 additions & 3 deletions src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ const LoginWelcomeStepForm: React.FC = () => {
<Text variant="sm-display">Sign up or log in</Text>

<Input
accessibilityHint="Enter your email address"
autoCapitalize="none"
autoComplete="username"
importantForAutofill="yes"
Expand Down Expand Up @@ -169,6 +170,7 @@ const LoginWelcomeStepForm: React.FC = () => {
onPress={handleSubmit}
loading={isSubmitting}
disabled={!isValid || !values.email}
accessibilityHint="Continue to the next screen"
>
Continue
</Button>
Expand All @@ -179,6 +181,7 @@ const LoginWelcomeStepForm: React.FC = () => {
animate={{ opacity: isModalExpanded ? 0 : 1 }}
transition={{ type: "timing", duration: 400, easing: Easing.linear }}
style={{ display: isModalExpanded ? "none" : "flex" }}
testID="social-signin-and-disclaimers"
>
<Spacer y={2} />

Expand All @@ -191,13 +194,15 @@ const LoginWelcomeStepForm: React.FC = () => {
<LinkText
variant="xxs"
onPress={() => navigation.navigate("OnboardingWebView", { url: "/terms" })}
accessibilityHint="View the Terms and Conditions"
>
Terms and Conditions
</LinkText>{" "}
and{" "}
<LinkText
variant="xxs"
onPress={() => navigation.navigate("OnboardingWebView", { url: "/privacy" })}
accessibilityHint="View the Privacy Policy"
>
Privacy Policy
</LinkText>
Expand Down Expand Up @@ -236,19 +241,31 @@ const SocialLoginButtons: React.FC = () => {

<Flex flexDirection="row" gap={1} justifyContent="center" width="100%">
{Platform.OS === "ios" && osMajorVersion() >= 13 && (
<Button variant="outline" onPress={handleApplePress}>
<Button
variant="outline"
onPress={handleApplePress}
accessibilityHint="Sign in with Apple"
>
<Flex alignItems="center" justifyContent="center">
{/* On iOS, the icons need to be nudged down to be centered in the button. */}
<AppleIcon width={23} height={23} style={{ top: 4 }} />
</Flex>
</Button>
)}
<Button variant="outline" onPress={handleGooglePress}>
<Button
variant="outline"
onPress={handleGooglePress}
accessibilityHint="Sign in with Google"
>
<Flex alignItems="center" justifyContent="center">
<GoogleIcon width={23} height={23} style={Platform.OS === "ios" && { top: 4 }} />
</Flex>
</Button>
<Button variant="outline" onPress={handleFacebookPress}>
<Button
variant="outline"
onPress={handleFacebookPress}
accessibilityHint="Sign in with Facebook"
>
<Flex alignItems="center" justifyContent="center">
<FacebookIcon width={23} height={23} style={Platform.OS === "ios" && { top: 4 }} />
</Flex>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import { useNavigation } from "@react-navigation/native"
import { act, fireEvent, screen } from "@testing-library/react-native"
import { useRecaptcha } from "app/Components/Recaptcha/Recaptcha"
import { AuthContext } from "app/Scenes/Onboarding/Auth2/AuthContext"
import { useAuthNavigation } from "app/Scenes/Onboarding/Auth2/hooks/useAuthNavigation"
import { LoginWelcomeStep } from "app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep"
import { GlobalStore } from "app/store/GlobalStore"
import { osMajorVersion } from "app/utils/platformUtil"
import { renderWithWrappers } from "app/utils/tests/renderWithWrappers"
import { Platform } from "react-native"

jest.mock("@react-navigation/native", () => ({
useNavigation: jest.fn(),
}))
jest.mock("app/Scenes/Onboarding/Auth2/hooks/useAuthNavigation")
jest.mock("app/Scenes/Onboarding/Auth2/hooks/useInputAutofocus")
jest.mock("app/utils/platformUtil")
jest.mock("app/Components/Recaptcha/Recaptcha", () => ({
useRecaptcha: jest.fn().mockReturnValue({ Recaptcha: () => {}, token: "recaptcha-token" }),
}))

describe("LoginWelcomeStep", () => {
const mockUseNavigation = useNavigation as jest.Mock
const mockUseAuthNavigation = useAuthNavigation as jest.Mock
const mockUseRecaptcha = useRecaptcha as jest.Mock
const mockOSMajorVersion = osMajorVersion as jest.Mock

beforeEach(() => {
/**
* This component involves animations, so we need to mock timers to ensure that the animations
* are completed before making assertions.
*/
jest.useFakeTimers()

// Use iOS as the default platform to avoid having to mock the platform in every test.
Platform.OS = "ios"
})

afterEach(() => {
jest.runOnlyPendingTimers()
jest.useRealTimers()
})

it("expands the modal when the input field is tapped", async () => {
renderWelcomeStep()

expect(screen.queryByA11yHint("Go back to the previous screen")).not.toBeOnTheScreen()
expect(screen.queryByA11yHint("Continue to the next screen")).not.toBeOnTheScreen()
expect(screen.getByTestId("social-signin-and-disclaimers")).toHaveAnimatedStyle({ opacity: 1 })

fireEvent(screen.getByA11yHint("Enter your email address"), "focus")

jest.advanceTimersByTime(1000)

expect(screen.getByA11yHint("Go back to the previous screen")).toBeOnTheScreen()
expect(screen.getByA11yHint("Continue to the next screen")).toBeOnTheScreen()
expect(screen.queryByTestId("social-signin-and-disclaimers")).not.toBeOnTheScreen()
})

describe("when the modal is expanded", () => {
it("closes the modal when the back icon is tapped", () => {
renderExpandedWelcomeStep()

fireEvent.press(screen.getByA11yHint("Go back to the previous screen"))

jest.advanceTimersByTime(1000)

expect(screen.queryByA11yHint("Go back to the previous screen")).not.toBeOnTheScreen()
expect(screen.queryByA11yHint("Continue to the next screen")).not.toBeOnTheScreen()
expect(screen.getByTestId("social-signin-and-disclaimers")).toHaveAnimatedStyle({
opacity: 1,
})
})

it("navigates to the sign-up password step if a user account doesn't exist", async () => {
GlobalStore.actions.auth.verifyUser = jest
.fn()
.mockResolvedValue("user_does_not_exist") as any

const navigateSpy = jest.fn()
mockUseAuthNavigation.mockReturnValueOnce({
navigate: navigateSpy,
})

renderExpandedWelcomeStep()

fireEvent.changeText(screen.getByA11yHint("Enter your email address"), "[email protected]")
fireEvent.press(screen.getByA11yHint("Continue to the next screen"))

// eslint-disable-next-line testing-library/no-unnecessary-act
await act(() => fireEvent.press(screen.getByA11yHint("Continue to the next screen")))

expect(navigateSpy).toHaveBeenCalledWith({
name: "SignUpPasswordStep",
params: { email: "[email protected]" },
})
})

it("navigates to the login password step if a user account exists", async () => {
GlobalStore.actions.auth.verifyUser = jest.fn().mockResolvedValue("user_exists") as any

const navigateSpy = jest.fn()
mockUseAuthNavigation.mockReturnValueOnce({
navigate: navigateSpy,
})

renderExpandedWelcomeStep()

fireEvent.changeText(screen.getByA11yHint("Enter your email address"), "[email protected]")
fireEvent.press(screen.getByA11yHint("Continue to the next screen"))

// eslint-disable-next-line testing-library/no-unnecessary-act
await act(() => fireEvent.press(screen.getByA11yHint("Continue to the next screen")))

expect(navigateSpy).toHaveBeenCalledWith({
name: "LoginPasswordStep",
params: { email: "[email protected]" },
})
})

it("navigates to the login password step if recaptcha fails", async () => {
mockUseRecaptcha.mockReturnValueOnce({ Recaptcha: () => {}, token: null })

const navigateSpy = jest.fn()
mockUseAuthNavigation.mockReturnValueOnce({
navigate: navigateSpy,
})

renderExpandedWelcomeStep()

fireEvent.changeText(screen.getByA11yHint("Enter your email address"), "[email protected]")
fireEvent.press(screen.getByA11yHint("Continue to the next screen"))

// eslint-disable-next-line testing-library/no-unnecessary-act
await act(() => fireEvent.press(screen.getByA11yHint("Continue to the next screen")))

expect(navigateSpy).toHaveBeenCalledWith({
name: "LoginPasswordStep",
params: { email: "[email protected]", showSignUpLink: true },
})
})
})

it("shows the Sign in with Apple button on iOS versions >= 13 ", () => {
mockOSMajorVersion.mockReturnValue(13)
renderWelcomeStep()
expect(screen.getByA11yHint("Sign in with Apple")).toBeOnTheScreen()
})

it("shows the Sign in with Apple button on iOS versions < 13", () => {
mockOSMajorVersion.mockReturnValue(12)
renderWelcomeStep()
expect(screen.queryByA11yHint("Sign in with Apple")).not.toBeOnTheScreen()
})

it("hides the Sign in with Apple button on Android", () => {
Platform.OS = "android"
renderWelcomeStep()
expect(screen.queryByA11yHint("Sign in with Apple")).not.toBeOnTheScreen()
})

it("provides a link to the terms and conditions", async () => {
const navigateSpy = jest.fn()
mockUseNavigation.mockReturnValueOnce({
navigate: navigateSpy,
})

renderWelcomeStep()

// eslint-disable-next-line testing-library/no-unnecessary-act
await act(() => fireEvent.press(screen.getByA11yHint("View the Terms and Conditions")))

expect(navigateSpy).toHaveBeenCalledWith("OnboardingWebView", { url: "/terms" })
})

it("provides a link to the privacy policy", async () => {
const navigateSpy = jest.fn()
mockUseNavigation.mockReturnValueOnce({
navigate: navigateSpy,
})

renderWelcomeStep()

// eslint-disable-next-line testing-library/no-unnecessary-act
await act(() => fireEvent.press(screen.getByA11yHint("View the Privacy Policy")))

expect(navigateSpy).toHaveBeenCalledWith("OnboardingWebView", { url: "/privacy" })
})
})

const renderWelcomeStep = () => {
renderWithWrappers(
<AuthContext.Provider>
<LoginWelcomeStep />
</AuthContext.Provider>
)
jest.advanceTimersByTime(400)
}

const renderExpandedWelcomeStep = () => {
renderWelcomeStep()
fireEvent(screen.getByA11yHint("Enter your email address"), "focus")
jest.advanceTimersByTime(1000)
}

0 comments on commit eda9e92

Please sign in to comment.