Skip to content
Snippets Groups Projects
ElementLink.component.test.tsx 7.21 KiB
Newer Older
import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { modelsFixture } from '@/models/fixtures/modelsFixture';
import { apiPath } from '@/redux/apiPath';
import { DEFAULT_POSITION } from '@/redux/map/map.constants';
import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
import { AppDispatch, RootState } from '@/redux/store';
import { MapModel, PublicationElement } from '@/types/models';
import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
import {
  InitialStoreState,
  getReduxStoreWithActionsListener,
} from '@/utils/testing/getReduxStoreActionsListener';
import { render, screen, waitFor } from '@testing-library/react';
import { HttpStatusCode } from 'axios';
import { MockStoreEnhanced } from 'redux-mock-store';
import { isReactionElement } from '@/redux/reactions/isReactionElement';
import { ElementLink } from './ElementLink.component';

const mockedAxiosNewClient = mockNetworkNewAPIResponse();

const TARGET_ELEMENT: PublicationElement = {
  ...bioEntityResponseFixture.content[FIRST_ARRAY_ELEMENT].bioEntity,
  model: 52,
  idReaction: 're1234',
};

const MODEL: MapModel = {
  ...modelsFixture[FIRST_ARRAY_ELEMENT],
  id: TARGET_ELEMENT.model,
};

const OTHER_MODEL: MapModel = {
  ...modelsFixture[FIRST_ARRAY_ELEMENT],
const getElementText = (element: PublicationElement): string => {
  const isReaction = isReactionElement(element);
  const prefix = isReaction ? 'Reaction: ' : 'Element: ';

  return prefix + element.elementId;
const getSearchQuery = (element: PublicationElement): string => {
  const isReaction = isReactionElement(element);
  return (isReaction ? 'reaction:' : 'element:') + element.id;
const renderComponent = (
  props: Props,
  initialStoreState: InitialStoreState = {},
): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
  const { Wrapper, store } = getReduxStoreWithActionsListener(initialStoreState);

  return (
    render(
      <Wrapper>
        <ElementLink target={props.target} />
      </Wrapper>,
    ),
    {
      store,
    }
  );
};

describe('ElementLink - component', () => {
  describe('when loaded', () => {
    mockedAxiosNewClient
      .onGet(
        apiPath.getBioEntityContentsStringWithQuery({
          searchQuery: TARGET_ELEMENT.id.toString(),
          isPerfectMatch: true,
        }),
      )
      .reply(HttpStatusCode.Ok, bioEntityResponseFixture);

    beforeEach(() => {
      renderComponent({ target: TARGET_ELEMENT }, INITIAL_STORE_STATE_MOCK);
    });

    it('should should show element id', async () => {

      await waitFor(() => {
        expect(screen.getByText(getElementText(element))).toBeInTheDocument();
      });
    });
  });

  describe('when clicked (currentModel different than target model)', () => {
    mockedAxiosNewClient
      .onGet(
        apiPath.getBioEntityContentsStringWithQuery({
          searchQuery: TARGET_ELEMENT.id.toString(),
          isPerfectMatch: true,
        }),
      )
      .reply(HttpStatusCode.Ok, bioEntityResponseFixture);

    it('should close modal, search for element, open drawer and open submap on link click', async () => {
      const { store } = renderComponent(
        { target: TARGET_ELEMENT },
        {
          ...INITIAL_STORE_STATE_MOCK,
          models: {
            ...INITIAL_STORE_STATE_MOCK.models,
            data: [MODEL],

      await waitFor(() => {
        const link = screen.getByText(getElementText(element));
        link.click();

        const actions = store.getActions();

        // close modal
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: undefined,
              type: 'modal/closeModal',
            }),
          ]),
        );

        // search for element
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: undefined,
              type: 'project/getSearchData/pending',
            }),
          ]),
        );

        // open drawer
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              type: 'drawer/openSearchDrawerWithSelectedTab',
            }),
          ]),
        );

        // open submap
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: {
                modelId: TARGET_ELEMENT.model,
                modelName: MODEL.name,
              },
              type: 'map/openMapAndSetActive',
            }),
          ]),
        );
      });
    });
  });

  describe('when clicked (currentModel the same as target model)', () => {
    mockedAxiosNewClient
      .onGet(
        apiPath.getBioEntityContentsStringWithQuery({
          searchQuery: TARGET_ELEMENT.id.toString(),
          isPerfectMatch: true,
        }),
      )
      .reply(HttpStatusCode.Ok, bioEntityResponseFixture);

    it('should close modal, search for element, open drawer and set submap on link click', async () => {
      const { store } = renderComponent(
        { target: TARGET_ELEMENT },
        {
          ...INITIAL_STORE_STATE_MOCK,
          models: {
            ...INITIAL_STORE_STATE_MOCK.models,
            data: [MODEL, OTHER_MODEL],
          },
          map: {
            ...INITIAL_STORE_STATE_MOCK.map,
            data: {
              ...INITIAL_STORE_STATE_MOCK.map.data,
              modelId: OTHER_MODEL.id,
                modelId: TARGET_ELEMENT.model,
                modelName: MODEL.name,
                lastPosition: DEFAULT_POSITION,
              },
            ],
          },
        },
      );


      await waitFor(() => {
        const link = screen.getByText(getElementText(element));
        link.click();

        const actions = store.getActions();

        // close modal
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: undefined,
              type: 'modal/closeModal',
            }),
          ]),
        );

        // search for element
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: undefined,
              type: 'project/getSearchData/pending',
            }),
          ]),
        );

        // open drawer
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              type: 'drawer/openSearchDrawerWithSelectedTab',
            }),
          ]),
        );

        // set submap
        expect(actions).toEqual(
          expect.arrayContaining([
            expect.objectContaining({
              payload: {
                modelId: TARGET_ELEMENT.model,
              },
              type: 'map/setActiveMap',
            }),
          ]),
        );
      });
    });
  });
});