diff --git a/src/components/FunctionalArea/TopBar/SearchBar/SearchBar.component.test.tsx b/src/components/FunctionalArea/TopBar/SearchBar/SearchBar.component.test.tsx index a98417efeab49a8ee62f255959c4bbfab9be4fce..3a899dec667f65ac55c8a25c9ff47da618640e46 100644 --- a/src/components/FunctionalArea/TopBar/SearchBar/SearchBar.component.test.tsx +++ b/src/components/FunctionalArea/TopBar/SearchBar/SearchBar.component.test.tsx @@ -89,7 +89,7 @@ describe('SearchBar - component', () => { const { store } = renderComponent({ reactions: { ...INITIAL_STORE_STATE_MOCK.reactions, - reactions: { ...INITIAL_STORE_STATE_MOCK.reactions.reactions, data: reactionsFixture }, + data: reactionsFixture, }, }); const input = screen.getByTestId<HTMLInputElement>('search-input'); @@ -102,7 +102,7 @@ describe('SearchBar - component', () => { const { reactions } = store.getState(); - expect(reactions.reactions.data).toStrictEqual([]); + expect(reactions.data).toStrictEqual([]); }); it('should open search drawer if it is not open', () => { const { store } = renderComponent({ diff --git a/src/components/Map/Drawer/Drawer.component.test.tsx b/src/components/Map/Drawer/Drawer.component.test.tsx index b7a8b20dbf928703c3be0012c4fdf55cc4f66c25..2499e7f3b459484389a46d4453426b5123cc12ac 100644 --- a/src/components/Map/Drawer/Drawer.component.test.tsx +++ b/src/components/Map/Drawer/Drawer.component.test.tsx @@ -97,16 +97,9 @@ describe('Drawer - component', () => { const { store } = renderComponent({ reactions: { - reactions: { - data: reactionsFixture, - loading: 'succeeded', - error: { message: '', name: '' }, - }, - newReactions: { - data: [], - loading: 'succeeded', - error: { message: '', name: '' }, - }, + data: reactionsFixture, + loading: 'succeeded', + error: { message: '', name: '' }, }, }); diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx index 33bd0f0af5f66702bf29b9f26b864e854102c1cf..1a635a0b5ac357f43962460455aa1c9683780c41 100644 --- a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx +++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx @@ -35,16 +35,9 @@ describe('ReactionDrawer - component', () => { beforeEach(() => renderComponent({ reactions: { - reactions: { - data: reactionsFixture, - loading: 'succeeded', - error: { message: '', name: '' }, - }, - newReactions: { - data: [], - loading: 'succeeded', - error: { message: '', name: '' }, - }, + data: [], + loading: 'succeeded', + error: { message: '', name: '' }, }, drawer: DRAWER_INITIAL_STATE, }), @@ -77,16 +70,9 @@ describe('ReactionDrawer - component', () => { beforeEach(() => renderComponent({ reactions: { - reactions: { - data: reactionsFixture, - loading: 'succeeded', - error: { message: '', name: '' }, - }, - newReactions: { - data: [], - loading: 'succeeded', - error: { message: '', name: '' }, - }, + data: reactionsFixture, + loading: 'succeeded', + error: { message: '', name: '' }, }, drawer: { ...DRAWER_INITIAL_STATE, diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx index 019a9d0d645bf08fb9dbcdcec722948d3a8842bb..e2d365f6b978ff8e05c5a21732e9c2640cd74e63 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx @@ -332,7 +332,7 @@ describe('BioEntitiesPinsListItem - component ', () => { }, reactions: { ...INITIAL_STORE_STATE_MOCK.reactions, - reactions: { ...INITIAL_STORE_STATE_MOCK.reactions.reactions, data: reactionsFixture }, + data: reactionsFixture, }, }, ); @@ -345,6 +345,6 @@ describe('BioEntitiesPinsListItem - component ', () => { const state = store.getState(); - expect(state.reactions.reactions.data).toStrictEqual([]); + expect(state.reactions.data).toStrictEqual([]); }); }); diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts index cbf764b930348697aab7dec40c976982e9846a58..2b3680b0a29c7a00edce8d9d6a2867c6e5245697 100644 --- a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts +++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts @@ -25,9 +25,9 @@ import CompartmentCircle from '@/components/Map/MapViewer/MapViewerVector/utils/ import { ModelElement } from '@/types/models'; import Glyph from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/Glyph'; import CompartmentPathway from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentPathway'; -import { getNewReactions } from '@/redux/reactions/reactions.thunks'; -import { newReactionsDataSelector } from '@/redux/reactions/reactions.selector'; import Reaction from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/reaction/Reaction'; +import { newReactionsDataSelector } from '@/redux/newReactions/newReactions.selectors'; +import { getNewReactions } from '@/redux/newReactions/newReactions.thunks'; export const useOlMapReactionsLayer = ({ mapInstance, diff --git a/src/redux/newReactions/newReactions.constants.ts b/src/redux/newReactions/newReactions.constants.ts new file mode 100644 index 0000000000000000000000000000000000000000..80ea28ccf9f366c876a3dff5d6582db073fabe48 --- /dev/null +++ b/src/redux/newReactions/newReactions.constants.ts @@ -0,0 +1,10 @@ +import { DEFAULT_ERROR } from '@/constants/errors'; +import { NewReactionsState } from '@/redux/newReactions/newReactions.types'; + +export const NEW_REACTIONS_INITIAL_STATE: NewReactionsState = { + data: [], + loading: 'idle', + error: DEFAULT_ERROR, +}; + +export const NEW_REACTIONS_FETCHING_ERROR_PREFIX = 'Failed to fetch new reactions'; diff --git a/src/redux/newReactions/newReactions.mock.ts b/src/redux/newReactions/newReactions.mock.ts new file mode 100644 index 0000000000000000000000000000000000000000..3847aed65b5a817df00b05ba02e4a5a5c7e63133 --- /dev/null +++ b/src/redux/newReactions/newReactions.mock.ts @@ -0,0 +1,8 @@ +import { DEFAULT_ERROR } from '@/constants/errors'; +import { NewReactionsState } from '@/redux/newReactions/newReactions.types'; + +export const NEW_REACTIONS_INITIAL_STATE_MOCK: NewReactionsState = { + data: [], + loading: 'idle', + error: DEFAULT_ERROR, +}; diff --git a/src/redux/newReactions/newReactions.reducers.test.ts b/src/redux/newReactions/newReactions.reducers.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..21f8d6686e63ce18e3b924d3fa25f6f57e4c6687 --- /dev/null +++ b/src/redux/newReactions/newReactions.reducers.test.ts @@ -0,0 +1,79 @@ +/* eslint-disable no-magic-numbers */ +import { apiPath } from '@/redux/apiPath'; +import { + ToolkitStoreWithSingleSlice, + createStoreInstanceUsingSliceReducer, +} from '@/utils/createStoreInstanceUsingSliceReducer'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; +import { HttpStatusCode } from 'axios'; +import { unwrapResult } from '@reduxjs/toolkit'; +import newReactionsReducer from '@/redux/newReactions/newReactions.slice'; +import { NewReactionsState } from '@/redux/newReactions/newReactions.types'; +import { NEW_REACTIONS_INITIAL_STATE_MOCK } from '@/redux/newReactions/newReactions.mock'; +import { getNewReactions } from '@/redux/newReactions/newReactions.thunks'; +import { newReactionsFixture } from '@/models/fixtures/newReactionsFixture'; + +const mockedAxiosClient = mockNetworkNewAPIResponse(); + +const INITIAL_STATE: NewReactionsState = NEW_REACTIONS_INITIAL_STATE_MOCK; + +describe('newReactions reducer', () => { + let store = {} as ToolkitStoreWithSingleSlice<NewReactionsState>; + beforeEach(() => { + store = createStoreInstanceUsingSliceReducer('newReactions', newReactionsReducer); + }); + + it('should match initial state', () => { + const action = { type: 'unknown' }; + + expect(newReactionsReducer(undefined, action)).toEqual(INITIAL_STATE); + }); + + it('should update store after successful getNewReactions query', async () => { + mockedAxiosClient + .onGet(apiPath.getNewReactions(1)) + .reply(HttpStatusCode.Ok, newReactionsFixture); + + const { type } = await store.dispatch(getNewReactions(1)); + const { data, loading, error } = store.getState().newReactions; + expect(type).toBe('newReactions/getNewReactions/fulfilled'); + expect(loading).toEqual('succeeded'); + expect(error).toEqual({ message: '', name: '' }); + expect(data).toEqual(newReactionsFixture.content); + }); + + it('should update store after failed getNewReactions query', async () => { + mockedAxiosClient.onGet(apiPath.getNewReactions(1)).reply(HttpStatusCode.NotFound, []); + + const action = await store.dispatch(getNewReactions(1)); + const { data, loading, error } = store.getState().newReactions; + + expect(action.type).toBe('newReactions/getNewReactions/rejected'); + expect(() => unwrapResult(action)).toThrow( + "Failed to fetch new reactions: The page you're looking for doesn't exist. Please verify the URL and try again.", + ); + expect(loading).toEqual('failed'); + expect(error).toEqual({ message: '', name: '' }); + expect(data).toEqual([]); + }); + + it('should update store on loading getNewReactions query', async () => { + mockedAxiosClient + .onGet(apiPath.getNewReactions(1)) + .reply(HttpStatusCode.Ok, newReactionsFixture); + + const newReactionsPromise = store.dispatch(getNewReactions(1)); + + const { data, loading } = store.getState().newReactions; + expect(data).toEqual([]); + expect(loading).toEqual('pending'); + + newReactionsPromise.then(() => { + const { data: dataPromiseFulfilled, loading: promiseFulfilled } = + store.getState().newReactions; + + expect(dataPromiseFulfilled).toEqual(newReactionsFixture.content); + expect(promiseFulfilled).toEqual('succeeded'); + }); + }); +}); diff --git a/src/redux/newReactions/newReactions.reducers.ts b/src/redux/newReactions/newReactions.reducers.ts new file mode 100644 index 0000000000000000000000000000000000000000..306b306e770cfb0097e256e1aed05fa8017d2990 --- /dev/null +++ b/src/redux/newReactions/newReactions.reducers.ts @@ -0,0 +1,18 @@ +import { ActionReducerMapBuilder } from '@reduxjs/toolkit'; +import { getNewReactions } from '@/redux/newReactions/newReactions.thunks'; +import { NewReactionsState } from '@/redux/newReactions/newReactions.types'; + +export const getNewReactionsReducer = ( + builder: ActionReducerMapBuilder<NewReactionsState>, +): void => { + builder.addCase(getNewReactions.pending, state => { + state.loading = 'pending'; + }); + builder.addCase(getNewReactions.fulfilled, (state, action) => { + state.data = action.payload || []; + state.loading = 'succeeded'; + }); + builder.addCase(getNewReactions.rejected, state => { + state.loading = 'failed'; + }); +}; diff --git a/src/redux/newReactions/newReactions.selectors.ts b/src/redux/newReactions/newReactions.selectors.ts new file mode 100644 index 0000000000000000000000000000000000000000..4dc2babe517c9850b03cf090644ebe2389550dcd --- /dev/null +++ b/src/redux/newReactions/newReactions.selectors.ts @@ -0,0 +1,9 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { rootSelector } from '../root/root.selectors'; + +export const newReactionsSelector = createSelector(rootSelector, state => state.newReactions); + +export const newReactionsDataSelector = createSelector( + newReactionsSelector, + reactions => reactions.data || [], +); diff --git a/src/redux/newReactions/newReactions.slice.ts b/src/redux/newReactions/newReactions.slice.ts new file mode 100644 index 0000000000000000000000000000000000000000..5bb5198a1f58d89036338741124f555a64c9b71a --- /dev/null +++ b/src/redux/newReactions/newReactions.slice.ts @@ -0,0 +1,14 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { NEW_REACTIONS_INITIAL_STATE } from '@/redux/newReactions/newReactions.constants'; +import { getNewReactionsReducer } from '@/redux/newReactions/newReactions.reducers'; + +export const newReactionsSlice = createSlice({ + name: 'reactions', + initialState: NEW_REACTIONS_INITIAL_STATE, + reducers: {}, + extraReducers: builder => { + getNewReactionsReducer(builder); + }, +}); + +export default newReactionsSlice.reducer; diff --git a/src/redux/newReactions/newReactions.thunks.test.ts b/src/redux/newReactions/newReactions.thunks.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..afd14d77104b12dcbfaa00d460ca2221244947b9 --- /dev/null +++ b/src/redux/newReactions/newReactions.thunks.test.ts @@ -0,0 +1,41 @@ +/* eslint-disable no-magic-numbers */ +import { apiPath } from '@/redux/apiPath'; +import { + ToolkitStoreWithSingleSlice, + createStoreInstanceUsingSliceReducer, +} from '@/utils/createStoreInstanceUsingSliceReducer'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; +import { HttpStatusCode } from 'axios'; +import newReactionsReducer from '@/redux/newReactions/newReactions.slice'; +import { NewReactionsState } from '@/redux/newReactions/newReactions.types'; +import { newReactionsFixture } from '@/models/fixtures/newReactionsFixture'; +import { getNewReactions } from '@/redux/newReactions/newReactions.thunks'; + +const mockedAxiosClient = mockNetworkNewAPIResponse(); + +describe('newReactions thunks', () => { + let store = {} as ToolkitStoreWithSingleSlice<NewReactionsState>; + beforeEach(() => { + store = createStoreInstanceUsingSliceReducer('newReactions', newReactionsReducer); + }); + + describe('getReactions', () => { + it('should return data when data response from API is valid', async () => { + mockedAxiosClient + .onGet(apiPath.getNewReactions(1)) + .reply(HttpStatusCode.Ok, newReactionsFixture); + + const { payload } = await store.dispatch(getNewReactions(1)); + expect(payload).toEqual(newReactionsFixture.content); + }); + + it('should return undefined when data response from API is not valid ', async () => { + mockedAxiosClient + .onGet(apiPath.getNewReactions(1)) + .reply(HttpStatusCode.Ok, { randomProperty: 'randomValue' }); + + const { payload } = await store.dispatch(getNewReactions(1)); + expect(payload).toEqual(undefined); + }); + }); +}); diff --git a/src/redux/newReactions/newReactions.thunks.ts b/src/redux/newReactions/newReactions.thunks.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e7081a85787f62592bce8fc9095714a45eef4b3 --- /dev/null +++ b/src/redux/newReactions/newReactions.thunks.ts @@ -0,0 +1,24 @@ +import { apiPath } from '@/redux/apiPath'; +import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; +import { NewReaction, NewReactions } from '@/types/models'; +import { ThunkConfig } from '@/types/store'; +import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; +import { createAsyncThunk } from '@reduxjs/toolkit'; +import { getError } from '@/utils/error-report/getError'; +import { newReactionSchema } from '@/models/newReactionSchema'; +import { pageableSchema } from '@/models/pageableSchema'; +import { NEW_REACTIONS_FETCHING_ERROR_PREFIX } from '@/redux/newReactions/newReactions.constants'; + +export const getNewReactions = createAsyncThunk< + Array<NewReaction> | undefined, + number, + ThunkConfig +>('newReactions/getNewReactions', async (modelId: number) => { + try { + const { data } = await axiosInstanceNewAPI.get<NewReactions>(apiPath.getNewReactions(modelId)); + const isDataValid = validateDataUsingZodSchema(data, pageableSchema(newReactionSchema)); + return isDataValid ? data.content : undefined; + } catch (error) { + return Promise.reject(getError({ error, prefix: NEW_REACTIONS_FETCHING_ERROR_PREFIX })); + } +}); diff --git a/src/redux/newReactions/newReactions.types.ts b/src/redux/newReactions/newReactions.types.ts new file mode 100644 index 0000000000000000000000000000000000000000..142906d7f46037ae9789eee1e74504ea2408d55f --- /dev/null +++ b/src/redux/newReactions/newReactions.types.ts @@ -0,0 +1,4 @@ +import { FetchDataState } from '@/types/fetchDataState'; +import { NewReaction } from '@/types/models'; + +export type NewReactionsState = FetchDataState<NewReaction[]>; diff --git a/src/redux/reactions/reactions.constants.ts b/src/redux/reactions/reactions.constants.ts index 5c6e50cb8b1eb4c4d069ec56e8c9f46ddb1b40a5..c5f51f9d4bfb67f52a7e543eb115c69bcec43eef 100644 --- a/src/redux/reactions/reactions.constants.ts +++ b/src/redux/reactions/reactions.constants.ts @@ -1,15 +1,9 @@ -import { DEFAULT_ERROR } from '@/constants/errors'; import { ReactionsState } from './reactions.types'; export const REACTIONS_INITIAL_STATE: ReactionsState = { - reactions: { - data: [], - loading: 'idle', - error: DEFAULT_ERROR, - }, - newReactions: { data: [], loading: 'idle', error: DEFAULT_ERROR }, + data: [], + loading: 'idle', + error: { name: '', message: '' }, }; export const REACTIONS_FETCHING_ERROR_PREFIX = 'Failed to fetch reactions'; - -export const NEW_REACTIONS_FETCHING_ERROR_PREFIX = 'Failed to fetch new reactions'; diff --git a/src/redux/reactions/reactions.mock.ts b/src/redux/reactions/reactions.mock.ts index 6f9ae43cfc9f725e9fa9ae8148b51c6709e63801..f8d9614b5a568fb8af107b76bff3180766d31c46 100644 --- a/src/redux/reactions/reactions.mock.ts +++ b/src/redux/reactions/reactions.mock.ts @@ -2,10 +2,7 @@ import { DEFAULT_ERROR } from '@/constants/errors'; import { ReactionsState } from './reactions.types'; export const REACTIONS_STATE_INITIAL_MOCK: ReactionsState = { - reactions: { - data: [], - loading: 'idle', - error: DEFAULT_ERROR, - }, - newReactions: { data: [], loading: 'idle', error: DEFAULT_ERROR }, + data: [], + loading: 'idle', + error: DEFAULT_ERROR, }; diff --git a/src/redux/reactions/reactions.reducers.ts b/src/redux/reactions/reactions.reducers.ts index 780ad2b8bf2338cfbb95f661e4c6a4a561f1d8e9..2ef4a163ec4f235e3c0aefbcadeff1f7fc28a7cb 100644 --- a/src/redux/reactions/reactions.reducers.ts +++ b/src/redux/reactions/reactions.reducers.ts @@ -1,42 +1,28 @@ import { ActionReducerMapBuilder } from '@reduxjs/toolkit'; import { REACTIONS_INITIAL_STATE } from './reactions.constants'; -import { getNewReactions, getReactionsByIds } from './reactions.thunks'; +import { getReactionsByIds } from './reactions.thunks'; import { ReactionsState } from './reactions.types'; export const getReactionsReducer = (builder: ActionReducerMapBuilder<ReactionsState>): void => { builder.addCase(getReactionsByIds.pending, state => { - state.reactions.loading = 'pending'; + state.loading = 'pending'; }); builder.addCase(getReactionsByIds.fulfilled, (state, action) => { const { payload } = action; if (!payload) return; - state.reactions.data = payload.shouldConcat - ? [...(state.reactions.data || []), ...payload.data] - : payload.data; - state.reactions.loading = 'succeeded'; + const newData = payload.shouldConcat ? [...(state.data || []), ...payload.data] : payload.data; + state.data = newData; + state.loading = 'succeeded'; }); builder.addCase(getReactionsByIds.rejected, state => { - state.reactions.loading = 'failed'; + state.loading = 'failed'; // TODO: error management to be discussed in the team }); }; -export const getNewReactionsReducer = (builder: ActionReducerMapBuilder<ReactionsState>): void => { - builder.addCase(getNewReactions.pending, state => { - state.newReactions.loading = 'pending'; - }); - builder.addCase(getNewReactions.fulfilled, (state, action) => { - state.newReactions.data = action.payload || []; - state.newReactions.loading = 'succeeded'; - }); - builder.addCase(getNewReactions.rejected, state => { - state.newReactions.loading = 'failed'; - }); -}; - export const resetReactionsDataReducer = (state: ReactionsState): void => { - state.reactions.data = REACTIONS_INITIAL_STATE.reactions.data; - state.reactions.error = REACTIONS_INITIAL_STATE.reactions.error; - state.reactions.loading = REACTIONS_INITIAL_STATE.reactions.loading; + state.data = REACTIONS_INITIAL_STATE.data; + state.error = REACTIONS_INITIAL_STATE.error; + state.loading = REACTIONS_INITIAL_STATE.loading; }; diff --git a/src/redux/reactions/reactions.selector.ts b/src/redux/reactions/reactions.selector.ts index ab0035717f5911f08d5ac43d1125c8b22ac557eb..14590fdaf229a209cbf1b052f4f76be6a5e5c85b 100644 --- a/src/redux/reactions/reactions.selector.ts +++ b/src/redux/reactions/reactions.selector.ts @@ -11,12 +11,7 @@ export const reactionsSelector = createSelector(rootSelector, state => state.rea export const reactionsDataSelector = createSelector( reactionsSelector, - reactions => reactions.reactions.data || [], -); - -export const newReactionsDataSelector = createSelector( - reactionsSelector, - reactions => reactions.newReactions.data || [], + reactions => reactions?.data || [], ); export const allReactionsSelectorOfCurrentMap = createSelector( diff --git a/src/redux/reactions/reactions.slice.ts b/src/redux/reactions/reactions.slice.ts index 17d80119d8664bd8e3c35c0adc73e8c5769fde3a..f97e9050155d87e496cb8adada0f8e28f0d0f4ba 100644 --- a/src/redux/reactions/reactions.slice.ts +++ b/src/redux/reactions/reactions.slice.ts @@ -1,10 +1,6 @@ import { createSlice } from '@reduxjs/toolkit'; import { REACTIONS_INITIAL_STATE } from './reactions.constants'; -import { - getNewReactionsReducer, - getReactionsReducer, - resetReactionsDataReducer, -} from './reactions.reducers'; +import { getReactionsReducer, resetReactionsDataReducer } from './reactions.reducers'; export const reactionsSlice = createSlice({ name: 'reactions', @@ -14,7 +10,6 @@ export const reactionsSlice = createSlice({ }, extraReducers: builder => { getReactionsReducer(builder); - getNewReactionsReducer(builder); }, }); diff --git a/src/redux/reactions/reactions.thunks.test.ts b/src/redux/reactions/reactions.thunks.test.ts index 72356327d077da55b37b0cf76779e9c0dcf58c44..d570a341bf204a66eaf062403f6698da0908b654 100644 --- a/src/redux/reactions/reactions.thunks.test.ts +++ b/src/redux/reactions/reactions.thunks.test.ts @@ -4,16 +4,14 @@ import { ToolkitStoreWithSingleSlice, createStoreInstanceUsingSliceReducer, } from '@/utils/createStoreInstanceUsingSliceReducer'; -import { mockNetworkNewAPIResponse, mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; import { HttpStatusCode } from 'axios'; -import { newReactionsFixture } from '@/models/fixtures/newReactionsFixture'; import { apiPath } from '../apiPath'; import reactionsReducer from './reactions.slice'; -import { getNewReactions, getReactionsByIds } from './reactions.thunks'; +import { getReactionsByIds } from './reactions.thunks'; import { ReactionsState } from './reactions.types'; const mockedAxiosClient = mockNetworkResponse(); -const mockedNewAxiosClient = mockNetworkNewAPIResponse(); describe('reactions thunks', () => { let store = {} as ToolkitStoreWithSingleSlice<ReactionsState>; @@ -49,24 +47,4 @@ describe('reactions thunks', () => { expect(payload).toEqual({ data: [], shouldConcat: false }); }); }); - - describe('getNewReactions', () => { - it('should return data when data response from API is valid', async () => { - mockedNewAxiosClient - .onGet(apiPath.getNewReactions(1)) - .reply(HttpStatusCode.Ok, newReactionsFixture); - - const { payload } = await store.dispatch(getNewReactions(1)); - expect(payload).toEqual(newReactionsFixture.content); - }); - - it('should return undefined when data response from API is not valid ', async () => { - mockedNewAxiosClient - .onGet(apiPath.getNewReactions(1)) - .reply(HttpStatusCode.Ok, { randomProperty: 'randomValue' }); - - const { payload } = await store.dispatch(getNewReactions(1)); - expect(payload).toEqual(undefined); - }); - }); }); diff --git a/src/redux/reactions/reactions.thunks.ts b/src/redux/reactions/reactions.thunks.ts index 7c6913791301094d542a02c495d26789b97cf680..af0b8c057f8af9724fba767b6ee04cc974f23f70 100644 --- a/src/redux/reactions/reactions.thunks.ts +++ b/src/redux/reactions/reactions.thunks.ts @@ -1,18 +1,13 @@ import { reactionSchema } from '@/models/reaction'; import { apiPath } from '@/redux/apiPath'; -import { axiosInstance, axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; -import { NewReaction, NewReactions, Reaction } from '@/types/models'; +import { axiosInstance } from '@/services/api/utils/axiosInstance'; +import { Reaction } from '@/types/models'; import { ThunkConfig } from '@/types/store'; import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; import { createAsyncThunk } from '@reduxjs/toolkit'; import { z } from 'zod'; import { getError } from '@/utils/error-report/getError'; -import { newReactionSchema } from '@/models/newReactionSchema'; -import { pageableSchema } from '@/models/pageableSchema'; -import { - NEW_REACTIONS_FETCHING_ERROR_PREFIX, - REACTIONS_FETCHING_ERROR_PREFIX, -} from './reactions.constants'; +import { REACTIONS_FETCHING_ERROR_PREFIX } from './reactions.constants'; type GetReactionsByIdsArgs = | number[] @@ -51,17 +46,3 @@ export const getReactionsByIds = createAsyncThunk< return Promise.reject(getError({ error, prefix: REACTIONS_FETCHING_ERROR_PREFIX })); } }); - -export const getNewReactions = createAsyncThunk< - Array<NewReaction> | undefined, - number, - ThunkConfig ->('reactions/getNewReactions', async (modelId: number) => { - try { - const { data } = await axiosInstanceNewAPI.get<NewReactions>(apiPath.getNewReactions(modelId)); - const isDataValid = validateDataUsingZodSchema(data, pageableSchema(newReactionSchema)); - return isDataValid ? data.content : undefined; - } catch (error) { - return Promise.reject(getError({ error, prefix: NEW_REACTIONS_FETCHING_ERROR_PREFIX })); - } -}); diff --git a/src/redux/reactions/reactions.types.ts b/src/redux/reactions/reactions.types.ts index 3fb3f1f5c18d07215e581a0d241fa8603da2be7a..02bd81cd1a77eb600ea5accac1317868c60ef7e2 100644 --- a/src/redux/reactions/reactions.types.ts +++ b/src/redux/reactions/reactions.types.ts @@ -1,7 +1,4 @@ import { FetchDataState } from '@/types/fetchDataState'; -import { NewReaction, Reaction } from '@/types/models'; +import { Reaction } from '@/types/models'; -export type ReactionsState = { - reactions: FetchDataState<Reaction[]>; - newReactions: FetchDataState<NewReaction[]>; -}; +export type ReactionsState = FetchDataState<Reaction[]>; diff --git a/src/redux/root/root.fixtures.ts b/src/redux/root/root.fixtures.ts index 8b1cec49d6e6fe6104c2487e898f080f322e2a1a..007c2b355b0bb4cc0dbf4a5d5e0a9d84b7b8d19c 100644 --- a/src/redux/root/root.fixtures.ts +++ b/src/redux/root/root.fixtures.ts @@ -6,6 +6,7 @@ import { AUTOCOMPLETE_INITIAL_STATE } from '@/redux/autocomplete/autocomplete.co import { SHAPES_STATE_INITIAL_MOCK } from '@/redux/shapes/shapes.mock'; import { MODEL_ELEMENTS_INITIAL_STATE_MOCK } from '@/redux/modelElements/modelElements.mock'; import { LAYERS_STATE_INITIAL_MOCK } from '@/redux/layers/layers.mock'; +import { NEW_REACTIONS_INITIAL_STATE_MOCK } from '@/redux/newReactions/newReactions.mock'; import { BACKGROUND_INITIAL_STATE_MOCK } from '../backgrounds/background.mock'; import { BIOENTITY_INITIAL_STATE_MOCK } from '../bioEntity/bioEntity.mock'; import { CHEMICALS_INITIAL_STATE_MOCK } from '../chemicals/chemicals.mock'; @@ -53,6 +54,7 @@ export const INITIAL_STORE_STATE_MOCK: RootState = { oauth: OAUTH_INITIAL_STATE_MOCK, overlays: OVERLAYS_INITIAL_STATE_MOCK, reactions: REACTIONS_STATE_INITIAL_MOCK, + newReactions: NEW_REACTIONS_INITIAL_STATE_MOCK, configuration: CONFIGURATION_INITIAL_STATE, constant: CONSTANT_INITIAL_STATE, overlayBioEntity: OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK, diff --git a/src/redux/store.ts b/src/redux/store.ts index f6b8ad65c8648756943c421cc42fd796f75e6bd7..a5d31bb57d0a4db6a0bae569a15a89579317c211 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -19,6 +19,7 @@ import overlaysReducer from '@/redux/overlays/overlays.slice'; import projectReducer from '@/redux/project/project.slice'; import projectsReducer from '@/redux/projects/projects.slice'; import reactionsReducer from '@/redux/reactions/reactions.slice'; +import newReactionsReducer from '@/redux/newReactions/newReactions.slice'; import searchReducer from '@/redux/search/search.slice'; import userReducer from '@/redux/user/user.slice'; import { @@ -66,6 +67,7 @@ export const reducers = { modelElements: modelElementsReducer, layers: layersReducer, reactions: reactionsReducer, + newReactions: newReactionsReducer, contextMenu: contextMenuReducer, cookieBanner: cookieBannerReducer, user: userReducer,