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, id: 123, model: 52, idReaction: 're1234', }; const MODEL: MapModel = { ...modelsFixture[FIRST_ARRAY_ELEMENT], id: TARGET_ELEMENT.model, }; const OTHER_MODEL: MapModel = { ...modelsFixture[FIRST_ARRAY_ELEMENT], }; interface Props { target: PublicationElement; } 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 () => { const element = TARGET_ELEMENT; 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], }, }, ); const element = TARGET_ELEMENT; 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({ payload: getSearchQuery(element), 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, }, openedMaps: [ { modelId: TARGET_ELEMENT.model, modelName: MODEL.name, lastPosition: DEFAULT_POSITION, }, ], }, }, ); const element = TARGET_ELEMENT; 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({ payload: getSearchQuery(element), type: 'drawer/openSearchDrawerWithSelectedTab', }), ]), ); // set submap expect(actions).toEqual( expect.arrayContaining([ expect.objectContaining({ payload: { modelId: TARGET_ELEMENT.model, }, type: 'map/setActiveMap', }), ]), ); }); }); }); });