Test different cases for Facebook login

Viewed 673

I am implementing Facebook login in a React Native app using https://github.com/facebook/react-native-fbsdk .

In my code, I have different outcomes depending on what permissions the user grants & based on whether or not an error occurs:

handleFacebookLogin = async () => {
  const result = await LoginManager.logInWithPermissions([
    "public_profile",
    "email"
  ]);
  if (result.isCancelled) {
    //do nothing, the user cancelled
  } else {
    const data = await AccessToken.getCurrentAccessToken();
    if (!data) {
      this.showAlert(
        strings.onboarding.fb_login.error_title,
        strings.onboarding.fb_login.error_body,
        strings.onboarding.fb_login.ok_button
      );
    } else {
      if (result.grantedPermissions.toString().contains("user_email")) {
        //navigate to screen A
      } else {
        //navigate to screen B
      }
    }
  }
};

showAlert = (title, body, button) => {
  //show alert
};

I want to write a test for each case (e.g. an error occurs, the user grants email permission, the user does NOT grant email permission).

I started writing a test for showing the alert when the error occurs, but I am stuck at mocking the actual error (the if (!data) scenario from the code above).

it("Shows an alert when an error occurs", () => {
  const errorMock = jest.fn();
  const loginMock = jest.fn();
  let ageScreen = renderer
    .create(<AgeScreen showAlert={errorMock} handleFacebookLogin={loginMock} />)
    .getInstance();

  const spy = jest
    .spyOn(ageScreen, "showAlert")
    .mockImplementation(/*TODO: mock fb library error */);

  ageScreen.handleFacebookLogin();
  expect(spy).toHaveBeenCalled();
});

My questions are:

  1. How do I finish this test case so that I reliably test that the Alert will be displayed in case of an error?

  2. How do I test the other scenarios (e.g. navigation to screen A if the user grants email permission)?

Thank you in advance! :)

1 Answers

First you need to mock LoginManager and AccessToken

jest.mock('react-native-fbsdk', () => ({
  ...jest.requireActual('react-native-fbsdk'),
  LoginManager: {
    logInWithPermissions: jest.fn(),
  },
  AccessToken: {
    getCurrentAccessToken: jest.fn(),
  }
}));

Then in every test case, mock the result that will lead to the scenario your are verifying

it("Shows an alert when an error occurs", () => {
  const errorMock = jest.fn();
  const loginMock = jest.fn();
  // put what result will get
  LoginManager.logInWithPermissions.mockReturnValue(...);
  // put what data will get
  AccessToken.getCurrentAccessToken.mockReturnValue(...);

  let ageScreen = renderer
    .create(<AgeScreen showAlert={errorMock} handleFacebookLogin={loginMock} />)
    .getInstance();

  const spy = jest
    .spyOn(ageScreen, "showAlert")

  ageScreen.handleFacebookLogin();
  expect(spy).toHaveBeenCalled();
});

and regarding your second questions it would be the same: mock dependencies and verify that the corresponding calls are being made

Related