0

I'm trying to test my signin page to verify after a 200 call to the API that it will redirect to our dashboard.

import { render as testRender } from '@testing-library/react';
import { ThemeProvider, Global } from '@emotion/react';
import { MemoryRouter } from 'react-router-dom';
import UserContext from '../user.context';
import { theme } from '../theme/theme';
import { globalStyles } from '../theme/globalstyles';

export const render = (component) => {
    return testRender(
        <UserContext.Provider value={{firstName: 'John', lastName: 'Doe'}}>
            <ThemeProvider theme={theme}>
                <Global styles={globalStyles} />
                <MemoryRouter>{component}</MemoryRouter>
            </ThemeProvider>
        </UserContext.Provider>
    )
}

My test is inserting an email / password and clicking the sign in button

test('Mock signin call and verify you get taken to overview page', async () => {        
    render(<SignIn />);

    userEvent.type(screen.getByTestId('input-email'), '[email protected]');
    userEvent.type(screen.getByTestId('input-password'), 'HowdyP1lgrum!');
    fireEvent.click(screen.getByTestId('button-signin'));

    await screen.findByText('user-name');
    expect(screen.getByText(/John Wayne/i)).toBeInTheDocument();
});

I have code in my Signin.jsx that looks for the status of the completed form and uses a <Redirect/> from React Router Dom to transition pages.

if (status.state === FORMSTATUS.COMPLETED) {
    if (status.resetPassword) {
        return <Redirect to={{ pathname: ROUTES.UPDATEPASSWORD, state: { email: credentials.email } }} />
    } else {
        console.log('************** Got Here ****************');
        return <Redirect to={ROUTES.OVERVIEW} />
    }
}

I can see the logged statement ****Got Here*** However it never finds the DOM in the header with the logged in user. The Redirect never seems to fire and I'm stuck with <body><div /></body>.

Am I missing something in my setup to properly test route transitions?

1 Answer 1

3

you can change your custom render to this:

//other imports
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";

export function render(
  component,
  {
    route = "/",
    history = createMemoryHistory({
      initialEntries: [route]
    }),
    ...options
  } = {}
) {
  const messages = resourceConvertor(resource);
  const userContext = createUserContext({});

  function wrapper({ children }) {
    return (
      <UserContext.Provider value={{ firstName: "John", lastName: "Doe" }}>
        <ThemeProvider theme={theme}>
          <Global styles={globalStyles} />
          <Router history={history}>{children}</Router>
        </ThemeProvider>
      </UserContext.Provider>
    );
  }

  return {
    ...testRender(component, { wrapper, ...options }),
    history
  };
}

now you can check the history to see if it's your desired route or not:

test("Mock signin call and verify you get taken to overview page", async () => {
  const { history } = render(<SignIn />);

  userEvent.type(screen.getByTestId("input-email"), "[email protected]");
  userEvent.type(screen.getByTestId("input-password"), "HowdyP1lgrum!");
  fireEvent.click(screen.getByTestId("button-signin"));

  // I don't know about these two line, usually you want to mock exteranl api call
  await screen.findByText("user-name");
  expect(screen.getByText(/John Wayne/i)).toBeInTheDocument();

  // now check to see if the url has bee redirected or not
  expect(history.location.pathname).toBe(ROUTES.OVERVIEW)
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.