Reputation: 4946
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?
Upvotes: 0
Views: 2130
Reputation: 6582
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)
});
Upvotes: 3