-1

I am trying to write the unit test case for the private route we created, using @azure/msal-react

below is the code for the private route

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import {
    AuthenticatedTemplate,
    UnauthenticatedTemplate,
} from '@azure/msal-react';

export const PrivateRoute = (props) => {
    const {
        component: Component,
        ...restProps
    } = props;

    if (!Component) return null;
    return (
        <Route
            exact
            {...restProps}
            render={(routeRenderProps) => (
                <>
                    <AuthenticatedTemplate>
                        <Component
                            {...routeRenderProps}
                            {...restProps}
                        />
                    </AuthenticatedTemplate>
                    <UnauthenticatedTemplate>
                        <Redirect
                            to={{
                                pathname: '/auth/signin',
                                state: { from: routeRenderProps.location },
                            }}
                        />
                    </UnauthenticatedTemplate>
                </>
            )}
        />
    );
};

below is the unit test case I wrote using react testing library

import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalAuthenticationTemplate } from '@azure/msal-react';
import { PrivateRoute } from '../privateRoute';

describe('PrivateRoute', () => {
  test('renders the component when the user is authenticated', () => {
    const Component = () => <div>My Component</div>;
    render(
      <MemoryRouter initialEntries={['/']}>
        <MsalAuthenticationTemplate>
          <PrivateRoute
            path="/"
            component={Component}
          />
        </MsalAuthenticationTemplate>
      </MemoryRouter>,
    );

    const componentElement = screen.getByText('My Component');
    expect(componentElement).toBeInTheDocument();
  });
});

but this test case doesn't work, as it was not able to find the component.

pls refer to the attached image,

enter image description here

Could please help me to resolve this issue?

another test case I tried like this below, here I am setting an authentication status by passing a mockClient to the msal provider

import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalProvider } from '@azure/msal-react';
import { PrivateRoute } from '../privateRoute';

describe('PrivateRoute', () => {
  test('renders the component when the user is authenticated', () => {
    const Component = () => <div>My Component</div>;

    // Create an instance of MsalProvider with a mocked instance
    const mockClient = {
      getAllAccounts: jest.fn(() => [{ name: 'Test User' }]),
    };
    render(
      <MsalProvider instance={mockClient}>
        <MemoryRouter initialEntries={['/']}>
          <PrivateRoute path="/" component={Component} />
        </MemoryRouter>
      </MsalProvider>,
    );

    const componentElement = screen.getByText('My Component');
    expect(componentElement).toBeInTheDocument();
  });

});

but it shows the below error message

enter image description here

SDK
  • 1,356
  • 3
  • 19
  • 44
  • How does your unit test code set the authentication status of the conditions you want to exercise the `PrivateRoute` component with? – Drew Reese May 03 '23 at 18:14
  • I have updated my answer, where I am setting an authentication status by passing a mockClient to the msal provider – SDK May 03 '23 at 18:20

1 Answers1

0

Found the way to set the authentication status

Please find the below code for it. msal-react-tester this library helps to set the authentication status.

import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalProvider } from '@azure/msal-react';
import { MsalReactTester } from 'msal-react-tester';
import { PrivateRoute } from '../privateRoute';

describe('PrivateRoute', () => {
    let msalTester;

    beforeEach(async () => {
        // new instance of msal tester for each test:
        msalTester = new MsalReactTester();

        // Ask msal-react-tester to handle and mock all msal-react processes:
        await msalTester.spyMsal();
    });

    afterEach(async () => {
        // reset msal-react-tester
        await msalTester.resetSpyMsal();
    });

    test('renders the component when the user is authenticated', async () => {
        const Component = () => <div>My Component</div>;

        // Set the user as logged in
        await msalTester.isLogged();

        render(
            <MsalProvider instance={msalTester.client}>
                <MemoryRouter initialEntries={['/']}>
                    <PrivateRoute path="/" component={Component} />
                </MemoryRouter>
            </MsalProvider>,
        );

        // Wait for the authentication redirect to resolve
        await msalTester.waitForRedirect();

        const componentElement = screen.getByText('My Component');
        expect(componentElement).toBeInTheDocument();
    });
       
});
SDK
  • 1,356
  • 3
  • 19
  • 44