department-of-veterans-affairs/vets-website

View on GitHub
src/applications/vaos/routes.unit.spec.js

Summary

Maintainability
D
3 days
Test Coverage
import React from 'react';
import { expect } from 'chai';
import Sinon from 'sinon';
import * as RequiredLoginView from '@department-of-veterans-affairs/platform-user/RequiredLoginView';
import { render } from '@testing-library/react';
import createRoutesWithStore, { handleLoadError } from './routes';
import { createTestStore, renderWithStoreAndRouter } from './tests/mocks/setup';
import * as EnrolledRoute from './components/EnrolledRoute';
import * as VAOSApp from './components/VAOSApp';
import * as NewAppointment from './new-appointment';
import * as AppointmentList from './appointment-list';
import * as NewBookingSection from './covid-19-vaccine';

describe('VAOS Routes', () => {
  const sandbox = Sinon.createSandbox();
  const store = { ...createTestStore(), injectReducer: () => {} };
  const initialState = {
    user: {
      profile: {
        facilities: [{ facilityId: '000', isCerner: false }],
      },
    },
  };

  let AppointmentListStub;
  let EnrolledRouteSpy;
  let NewAppointmentStub;
  let NewBookingSectionStub;
  let RequiredLoginViewStub;
  let VAOSAppStub;

  before(() => {
    EnrolledRouteSpy = sandbox.spy(EnrolledRoute, 'default');

    // Mock the real pages since they are tested seperately.
    AppointmentListStub = sandbox
      .stub(AppointmentList, 'AppointmentList')
      .returns(<div>Mock Page</div>);
    NewAppointmentStub = sandbox
      .stub(NewAppointment, 'NewAppointment')
      .returns(<div>Mock Page</div>);
    NewBookingSectionStub = sandbox
      .stub(NewBookingSection, 'NewBookingSection')
      .returns(<div>Mock Page</div>);
    RequiredLoginViewStub = sandbox
      .stub(RequiredLoginView, 'RequiredLoginView')
      .callsFake(() => {
        return <div>{[RequiredLoginViewStub.lastCall.args[0].children]}</div>;
      });
    VAOSAppStub = sandbox.stub(VAOSApp, 'default').callsFake(() => {
      return <div>{[VAOSAppStub.lastCall.args[0].children]}</div>;
    });
  });

  after(() => {
    sandbox.restore();
  });

  beforeEach(() => {
    AppointmentListStub.resetHistory();
    NewAppointmentStub.resetHistory();
    NewBookingSectionStub.resetHistory();
  });

  describe('When route is /', () => {
    it('should render page', async () => {
      // Arrange
      const path = '/';

      // Act
      const routes = createRoutesWithStore();
      const screen = renderWithStoreAndRouter(<div>{routes}</div>, {
        initialState,
        path,
      });

      // Assert
      await screen.findByText('Mock Page');
      expect(EnrolledRouteSpy.lastCall.args[0].location.pathname).to.equal(
        path,
      );
    });
  });

  describe('When route is /new-appointment', () => {
    it('should render page', async () => {
      // Arrange
      const path = '/new-appointment';

      // Act
      const routes = createRoutesWithStore(store);
      const screen = renderWithStoreAndRouter(<div>{routes}</div>, {
        initialState,
        path,
      });

      // Assert
      await screen.findByText('Mock Page');
      expect(EnrolledRouteSpy.lastCall.args[0].location.pathname).to.equal(
        path,
      );
    });
  });

  describe('When route is /schedule', () => {
    it('should render page', async () => {
      // Arrange
      const path = '/schedule';

      // Act
      const routes = createRoutesWithStore(store);
      const screen = renderWithStoreAndRouter(<div>{routes}</div>, {
        initialState,
        path,
      });

      // Assert
      await screen.findByText('Mock Page');
      expect(EnrolledRouteSpy.lastCall.args[0].location.pathname).to.equal(
        path,
      );
    });
  });

  describe('When route is /new-covid-19-vaccine-appointment', () => {
    it('should render page', async () => {
      // Arrange
      const path = '/new-covid-19-vaccine-appointment';

      // Act
      const routes = createRoutesWithStore(store);
      const screen = renderWithStoreAndRouter(<div>{routes}</div>, {
        initialState,
        path,
      });

      // Assert
      await screen.findByText('Mock Page');
      expect(EnrolledRouteSpy.lastCall.args[0].location.pathname).to.equal(
        path,
      );
    });
  });

  describe('When route is /schedule/covid-vaccine', () => {
    it('should render page', async () => {
      // Arrange
      const path = '/schedule/covid-vaccine';

      // Act
      const routes = createRoutesWithStore(store);
      const screen = renderWithStoreAndRouter(<div>{routes}</div>, {
        initialState,
        path,
      });

      // Assert
      await screen.findByText('Mock Page');
      expect(EnrolledRouteSpy.lastCall.args[0].location.pathname).to.equal(
        path,
      );
    });
  });
});

describe('VAOS <handleLoadError>', () => {
  let orig;

  beforeEach(() => {
    // This does not working:
    // const stub = Sinon.stub(window.location, 'replace');
    //
    // The following error occurs:
    // TypeError: Cannot redefine property: replace

    // So, doing this instead.
    // Save original location object...
    orig = { ...window.location };

    // Delete location object and redefine it
    delete window.location;
    window.location = {
      pathname: '/',
      replace: Sinon.stub().callsFake(path => {
        window.location.pathname += path;
        window.location.search = path.slice(path.indexOf('?'));
      }),
    };
  });

  afterEach(() => {
    // Restore location object
    window.location = { ...orig };
  });

  describe('When dynamic import loading error: 1st time', () => {
    it('should display reloading page indicator', async () => {
      // Arrange

      // Act
      const webComponent = handleLoadError(new Error('Error'))();
      render(<>{webComponent}</>);

      // Assert
      expect(window.location.replace.lastCall.args[0]).to.equal('/?retry=1');
      expect(webComponent.type).to.equal('va-loading-indicator');
      expect(webComponent.props.message).to.equal('Reloading page');
    });
  });

  describe('When dynamic import loading error: 2nd time', () => {
    it('should display error message', async () => {
      // Arrange

      // Act
      handleLoadError(new Error('Error'));
      const webComponent = handleLoadError(
        new Error('Reloading page error!'),
      )();
      const screen = render(<>{webComponent}</>);

      // Assert
      expect(screen.getByText(/We.re sorry. We.ve run into a problem/i)).to.be
        .ok;
    });
  });
});