Reputation: 1074
I have created a RestrictedRoute
react typescript component.
It should redirect to /dashboard page when the user is connected and page is restricted. If not it return a Route with the component passed in props.
RestrictedRoute.tsx
:
interface Props {
component: ComponentType;
restricted?: boolean;
}
const RestrictedRoute = ({ component: Component, restricted, ...rest }: Props & RouteProps) => {
const { data: userConnected, error } = useSWR('userConnected', checkUserLogged);
if (userConnected !== undefined) {
return (
<Route
{...rest}
render={(props) =>
userConnected && restricted && !error ? (
<Redirect to={ROUTES.DASHBOARD} />
) : (
<Component {...props} />
)
}
/>
);
}
if (error) return <Redirect to={ROUTES.LOGIN} />;
return <LoadingPage />;
};
export default RestrictedRoute;
I want to test it with jest and enzyme. So I have created the following test. It tests that the render prop return component passed in prop.
RestrictedRoute.test.tsx
:
interface RestrictedRouteProps {
component: ComponentType;
}
describe('RestrictedRoute', () => {
const props: RestrictedRouteProps = {
component: () => <></>,
};
const mockUseSwr = useSWR as jest.Mock;
beforeEach(() => {
mockUseSwr.mockClear();
});
it('should return Component when data fetched and user not connected', () => {
const userConnected = false;
const fakePath = '/youhou';
mockUseSwr.mockReturnValueOnce({ data: userConnected });
const wrapper = shallow(<RestrictedRoute component={props.component} path={fakePath} />)
.find(Route)
.renderProp('render')();
expect(wrapper.find(props.component)).toHaveLength(1);
});
The test is working but I have the following typescript error at compilation :
Argument of type '"render"' is not assignable to parameter of type '"children"'.
When I replace .renderProp('render')();
with .renderProp<RouteProps>('render')();
I see another error : Type 'RouteProps' does not satisfy the constraint '"children"'
Can you help me with this please ?
Upvotes: 0
Views: 279
Reputation: 1074
I found a solution that use RouteProps typing and route components props mock for renderProp argument (mandatory because render function from react-router-dom need this in his typescript definition) :
const routeComponentPropsMock = {
history: {} as any,
location: {} as any,
match: {} as any,
};
it.only('should return Component when data fetched and user not connected', () => {
const userConnected = false;
const fakePath = '/youhou';
mockUseSwr.mockReturnValueOnce({ data: userConnected });
const wrapper = shallow(<RestrictedRoute component={props.component} path={fakePath} />);
const routeWrapper = wrapper.find<RouteProps>(Route).renderProp('render')(
routeComponentPropsMock,
);
expect(routeWrapper.find(props.component)).toHaveLength(1);
});
Upvotes: 0