diff --git a/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.test.tsx b/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.test.tsx index bb7c8d1c5e5a3774c11790afd600408ba1b7341e..5a6e2f1a5c873778ae6e824b800a617a6a9761ad 100644 --- a/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.test.tsx +++ b/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.test.tsx @@ -3,11 +3,9 @@ import { InitialStoreState, getReduxStoreWithActionsListener, } from '@/utils/testing/getReduxStoreActionsListener'; -import mockRouter from 'next-router-mock'; import { fireEvent, render, screen } from '@testing-library/react'; import { MockStoreEnhanced } from 'redux-mock-store'; import { FIRST_ARRAY_ELEMENT } from '@/constants/common'; -import { projectFixture } from '@/models/fixtures/projectFixture'; import { LoggedInMenuModal } from './LoggedInMenuModal.component'; const renderComponent = ( @@ -41,22 +39,4 @@ describe('LoggedInMenuModal component', () => { const actions = store.getActions(); expect(actions[FIRST_ARRAY_ELEMENT].type).toBe('modal/closeModal'); }); - - it('redirects to the admin panel when "Go to the admin panel" button is clicked', () => { - const routerPushSpy = jest.spyOn(mockRouter, 'push'); - renderComponent({ - project: { - data: projectFixture, - loading: 'succeeded', - error: { message: '', name: '' }, - projectId: '', - }, - }); - - fireEvent.click(screen.getByText('Go to the admin panel')); - - expect(routerPushSpy).toHaveBeenCalledWith( - `https://lux1.atcomp.pl/minerva/admin.xhtml?id=pdmap_appu_test`, - ); - }); }); diff --git a/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.tsx b/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.tsx index 04c9cd9e6f8ac5170a5bdfcf41f344c49de69f3c..284d998f8dad6185777063462a5e5ee60d5258f4 100644 --- a/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.tsx +++ b/src/components/FunctionalArea/Modal/LoggedInMenuModal/LoggedInMenuModal.component.tsx @@ -2,19 +2,17 @@ import { CURRENT_PROJECT_ADMIN_PANEL_URL } from '@/constants'; import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; import { closeModal } from '@/redux/modal/modal.slice'; import { Button } from '@/shared/Button'; -import { useRouter } from 'next/router'; import React from 'react'; export const LoggedInMenuModal = (): React.ReactNode => { const dispatch = useAppDispatch(); - const router = useRouter(); const closeLoggedInMenuModal = (): void => { dispatch(closeModal()); }; const goToTheAdminPanel = (): void => { - router.push(CURRENT_PROJECT_ADMIN_PANEL_URL); + window.location.href = CURRENT_PROJECT_ADMIN_PANEL_URL; }; return ( <div className="flex justify-center gap-5 border border-t-[#E1E0E6] bg-white p-6"> diff --git a/src/components/FunctionalArea/TopBar/User/User.component.test.tsx b/src/components/FunctionalArea/TopBar/User/User.component.test.tsx index 707e0f5dac4dac4709f7d47e1eef9e5ee3e226ba..5a1ec9b5b884b2330ed91aa4faab3f490441ee70 100644 --- a/src/components/FunctionalArea/TopBar/User/User.component.test.tsx +++ b/src/components/FunctionalArea/TopBar/User/User.component.test.tsx @@ -6,8 +6,6 @@ import { USER_INITIAL_STATE_MOCK } from '@/redux/user/user.mock'; import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; import { apiPath } from '@/redux/apiPath'; import { HttpStatusCode } from 'axios'; -import mockRouter from 'next-router-mock'; -import { projectFixture } from '@/models/fixtures/projectFixture'; import { oauthFixture } from '@/models/fixtures/oauthFixture'; import { User } from './User.component'; @@ -160,39 +158,6 @@ describe('AuthenticatedUser component', () => { expect(modalState.isOpen).toBeTruthy(); expect(modalState.modalName).toBe('login'); }); - it('should change site to admin panel if go to the admin panel is pressed', async () => { - const routerPushSpy = jest.spyOn(mockRouter, 'push'); - renderComponent({ - project: { - data: projectFixture, - loading: 'succeeded', - error: { message: '', name: '' }, - projectId: '', - }, - user: { - ...USER_INITIAL_STATE_MOCK, - authenticated: true, - login: 'name', - role: 'admin', - }, - }); - - const button = screen.getByTestId('authenticated-button'); - - await waitFor(() => { - button.click(); - }); - - const adminPanelButton = screen.getByText('Go to the admin panel'); - - await waitFor(() => { - adminPanelButton.click(); - }); - - expect(routerPushSpy).toHaveBeenCalledWith( - `https://lux1.atcomp.pl/minerva/admin.xhtml?id=pdmap_appu_test`, - ); - }); }); describe('UnauthenticatedUser component', () => { diff --git a/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts b/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts index f1c0f845b995fe380cd750a38acbf3d7b874631b..cb3deb245565a989e12bb64a7bb8fa2b7d9d4b48 100644 --- a/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts +++ b/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts @@ -4,7 +4,6 @@ import { openLoginModal } from '@/redux/modal/modal.slice'; import { userRoleSelector } from '@/redux/user/user.selectors'; import { logout } from '@/redux/user/user.thunks'; import { IconTypes } from '@/types/iconTypes'; -import { useRouter } from 'next/router'; import { USER_ROLE } from '@/constants/user'; import { useMemo } from 'react'; import { CURRENT_PROJECT_ADMIN_PANEL_URL } from '@/constants'; @@ -21,7 +20,6 @@ type UseUserActionsReturnType = { export const useUserActions = (): UseUserActionsReturnType => { const dispatch = useAppDispatch(); const userRole = useAppSelector(userRoleSelector); - const router = useRouter(); const actions = useMemo(() => { return userRole === USER_ROLE.ADMIN || userRole === USER_ROLE.CURATOR @@ -43,7 +41,7 @@ export const useUserActions = (): UseUserActionsReturnType => { }; const goToThePanelAdmin = (): void => { - router.push(CURRENT_PROJECT_ADMIN_PANEL_URL); + window.location.href = CURRENT_PROJECT_ADMIN_PANEL_URL; }; const handleActionClick = (action: string): void => { diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts index cb49dd7a9e4da9c667198b710f7780aa1e82df5c..785d7d4d23dc42d2853d96cd77b59d6835153004 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts @@ -1,5 +1,5 @@ /* eslint-disable no-magic-numbers */ -import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common'; +import { SIZE_OF_EMPTY_ARRAY } from '@/constants/common'; import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture'; import { reactionsFixture } from '@/models/fixtures/reactionFixture'; import { @@ -12,6 +12,7 @@ import { mockNetworkNewAPIResponse, mockNetworkResponse } from '@/utils/mockNetw import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener'; import { HttpStatusCode } from 'axios'; import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; +import { bioEntityFixture } from '@/models/fixtures/bioEntityFixture'; import * as findClosestReactionPoint from './findClosestReactionPoint'; import { handleReactionResults } from './handleReactionResults'; @@ -40,6 +41,16 @@ const SEARCH_CONFIG_MOCK = { isResultDrawerOpen: false, }; +const reaction = { + ...reactionsFixture[0], + id: ELEMENT_SEARCH_RESULT_MOCK_REACTION.id, + modelId: ELEMENT_SEARCH_RESULT_MOCK_REACTION.modelId, + products: [], + reactants: [], + modifiers: [], + lines: [{ start: { x: 0, y: 0 }, end: { x: 3, y: 4 }, type: 'START' }], +}; + describe('handleReactionResults - util', () => { const searchDistance = '10'; @@ -62,11 +73,20 @@ describe('handleReactionResults - util', () => { ) .reply(HttpStatusCode.Ok, bioEntityResponseFixture); + mockedAxiosNewClient + .onGet( + apiPath.getReactionByIdInNewApi( + ELEMENT_SEARCH_RESULT_MOCK_REACTION.id, + ELEMENT_SEARCH_RESULT_MOCK_REACTION.modelId, + ), + ) + .reply(HttpStatusCode.Ok, bioEntityFixture); + mockedAxiosOldClient .onGet(apiPath.getReactionsWithIds([ELEMENT_SEARCH_RESULT_MOCK_REACTION.id])) .reply(HttpStatusCode.Ok, [ { - ...reactionsFixture[0], + ...reaction, reactants: [], products: [], modifiers: [ @@ -96,7 +116,7 @@ describe('handleReactionResults - util', () => { const actions = store.getActions(); expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY); expect(actions[2].type).toEqual('drawer/openReactionDrawerById'); - expect(actions[2].payload).toEqual(reactionsFixture[FIRST_ARRAY_ELEMENT].id); + expect(actions[2].payload).toEqual(reaction.id); }); it('should run select tab as fourth action', () => { @@ -154,11 +174,20 @@ describe('handleReactionResults - util', () => { ) .reply(HttpStatusCode.Ok, bioEntityResponseFixture); + mockedAxiosNewClient + .onGet( + apiPath.getReactionByIdInNewApi( + ELEMENT_SEARCH_RESULT_MOCK_REACTION.id, + ELEMENT_SEARCH_RESULT_MOCK_REACTION.modelId, + ), + ) + .reply(HttpStatusCode.Ok, bioEntityFixture); + mockedAxiosOldClient .onGet(apiPath.getReactionsWithIds([ELEMENT_SEARCH_RESULT_MOCK_REACTION.id])) .reply(HttpStatusCode.Ok, [ { - ...reactionsFixture[0], + ...reaction, reactants: [], products: [], modifiers: [ @@ -220,14 +249,6 @@ describe('handleReactionResults - util', () => { }); }); describe('when search config provided and matching reaction found', () => { - const reaction = { - ...reactionsFixture[0], - products: [], - reactants: [], - modifiers: [], - lines: [{ start: { x: 0, y: 0 }, end: { x: 3, y: 4 }, type: 'START' }], - }; - const point = { x: 1, y: 1 }; const maxZoom = 10; const zoom = 5; @@ -243,6 +264,15 @@ describe('handleReactionResults - util', () => { ) .reply(HttpStatusCode.Ok, []); + mockedAxiosNewClient + .onGet( + apiPath.getReactionByIdInNewApi( + ELEMENT_SEARCH_RESULT_MOCK_REACTION.id, + ELEMENT_SEARCH_RESULT_MOCK_REACTION.modelId, + ), + ) + .reply(HttpStatusCode.Ok, bioEntityFixture); + mockedAxiosOldClient .onGet(apiPath.getReactionsWithIds([ELEMENT_SEARCH_RESULT_MOCK_REACTION.id])) .reply(HttpStatusCode.Ok, [reaction]); @@ -270,14 +300,6 @@ describe('handleReactionResults - util', () => { }); }); describe('when matching reaction found', () => { - const reaction = { - ...reactionsFixture[0], - products: [], - reactants: [], - modifiers: [], - lines: [{ start: { x: 0, y: 0 }, end: { x: 3, y: 4 }, type: 'START' }], - }; - const point = { x: 1, y: 1 }; const maxZoom = 10; const zoom = 5; @@ -293,6 +315,15 @@ describe('handleReactionResults - util', () => { ) .reply(HttpStatusCode.Ok, []); + mockedAxiosNewClient + .onGet( + apiPath.getReactionByIdInNewApi( + ELEMENT_SEARCH_RESULT_MOCK_REACTION.id, + ELEMENT_SEARCH_RESULT_MOCK_REACTION.modelId, + ), + ) + .reply(HttpStatusCode.Ok, bioEntityFixture); + mockedAxiosOldClient .onGet(apiPath.getReactionsWithIds([ELEMENT_SEARCH_RESULT_MOCK_REACTION.id])) .reply(HttpStatusCode.Ok, [reaction]); @@ -306,7 +337,7 @@ describe('handleReactionResults - util', () => { })(ELEMENT_SEARCH_RESULT_MOCK_REACTION); expect(PluginsEventBus.dispatchEvent).toHaveBeenCalledWith('onSearch', { - results: [[reaction]], + results: [[{ bioEntity: bioEntityFixture, perfect: true }]], searchValues: [ELEMENT_SEARCH_RESULT_MOCK_REACTION], type: 'reaction', }); diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts index 937415fcc3fdc638ad97e8b52f8818439b24a702..f948c75042d38860ba69e010d76684b27fa1bb3d 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts @@ -6,10 +6,14 @@ import { AppDispatch } from '@/redux/store'; import { searchFitBounds } from '@/services/pluginsManager/map/triggerSearch/searchFitBounds'; import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; import { Point } from '@/types/map'; -import { ElementSearchResult } from '@/types/models'; -import { findClosestReactionPoint } from './findClosestReactionPoint'; -import { getBioEntitiesIdsFromReaction } from './getBioEntitiesIdsFromReaction'; +import { BioEntity, ElementSearchResult } from '@/types/models'; +import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; +import { apiPath } from '@/redux/apiPath'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; +import { bioEntitySchema } from '@/models/bioEntitySchema'; import { handleReactionSearchClickFailure } from './handleReactionSearchClickFailure'; +import { getBioEntitiesIdsFromReaction } from './getBioEntitiesIdsFromReaction'; +import { findClosestReactionPoint } from './findClosestReactionPoint'; type SearchConfig = { point: Point; @@ -49,21 +53,30 @@ export const handleReactionResults = dispatch(openReactionDrawerById(reaction.id)); dispatch(selectTab('')); - await dispatch( - getMultiBioEntity({ - searchQueries: bioEntitiesIds, - isPerfectMatch: true }, - ) - ).unwrap().then((bioEntityContents) => { - PluginsEventBus.dispatchEvent('onSearch', { - type: 'reaction', - searchValues: [closestSearchResult], - results: [[...bioEntityContents, reaction]], - }); - if (searchConfig && searchConfig.hasFitBounds) { - searchFitBounds(); - } - }); + const response = await axiosInstanceNewAPI.get<BioEntity>(apiPath.getReactionByIdInNewApi(reaction.id, reaction.modelId)); + const isDataValid = validateDataUsingZodSchema(response.data, bioEntitySchema); + + if (isDataValid) { + const reactionNewApi = response.data; + + await dispatch( + getMultiBioEntity({ + searchQueries: bioEntitiesIds, + isPerfectMatch: true + }, + ) + ).unwrap().then((bioEntityContents) => { + PluginsEventBus.dispatchEvent('onSearch', { + type: 'reaction', + searchValues: [closestSearchResult], + results: [[...bioEntityContents, { bioEntity: reactionNewApi, perfect: true }]], + }); + + if (searchConfig && searchConfig.hasFitBounds) { + searchFitBounds(); + } + }); + } }; diff --git a/src/models/fixtures/bioEntityFixture.ts b/src/models/fixtures/bioEntityFixture.ts new file mode 100644 index 0000000000000000000000000000000000000000..652ee55c6445b76c6604577d9723d79f445f1c73 --- /dev/null +++ b/src/models/fixtures/bioEntityFixture.ts @@ -0,0 +1,9 @@ +import { ZOD_SEED } from '@/constants'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { createFixture } from 'zod-fixture'; +import { bioEntitySchema } from '@/models/bioEntitySchema'; + +export const bioEntityFixture = createFixture(bioEntitySchema, { + seed: ZOD_SEED, + array: { min: 2, max: 2 }, +}); diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts index 8227bfec287407fd9cc09415b7176beb6ed914bb..29aa41741fa7d60ed7c1d72aa6c67709749fd7aa 100644 --- a/src/redux/apiPath.ts +++ b/src/redux/apiPath.ts @@ -22,6 +22,9 @@ const getPublicationsURLSearchParams = ( export const apiPath = { getElementById: (elementId: number, modelId: number): string => `projects/${PROJECT_ID}/models/${modelId}/bioEntities/elements/${elementId}`, + getReactionByIdInNewApi: (reactionId: number, modelId: number): string => + `projects/${PROJECT_ID}/models/${modelId}/bioEntities/reactions/${reactionId}`, + getReactionById: (reactionId: number, modelId: number): string => `projects/${PROJECT_ID}/models/${modelId}/bioEntities/reactions/?id=${reactionId}`, getBioEntityContentsStringWithQuery: ({ diff --git a/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts b/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts index 60bb693bb95e8d8a0fc4362ed56da4995ad75335..935487c6838b64dcb4c8c2f6d6b4ccb3461000ba 100644 --- a/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts +++ b/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts @@ -5,7 +5,6 @@ import { Drug, ElementSearchResult, MapOverlay, - Reaction, } from '@/types/models'; import { dispatchEvent } from './pluginsEventBus'; @@ -57,7 +56,7 @@ export type ClickedSurfaceOverlay = { export type SearchDataReaction = { type: 'reaction'; searchValues: string[] | ElementSearchResult[]; - results: (BioEntityContent | Reaction)[][]; + results: BioEntityContent[][]; }; export type SearchDataBioEntity = {