diff --git a/.env b/.env index 88c76981d85f1e298c0c03d911a28e8edaace6ee..e6ecdfb64ae9d6ed25ef25817873c338f58b57c0 100644 --- a/.env +++ b/.env @@ -1,3 +1,4 @@ -NEXT_PUBLIC_BASE_API_URL = 'https://corsproxy.io/?https://pdmap.uni.lu/minerva/api' -NEXT_PUBLIC_PROJECT_ID = 'pd_map_winter_23' \ No newline at end of file +NEXT_PUBLIC_BASE_API_URL = 'https://corsproxy.io/?https://lux1.atcomp.pl/minerva/api' +NEXT_PUBLIC_BASE_NEW_API_URL = 'https://corsproxy.io/?https://lux1.atcomp.pl/minerva/new_api/' +NEXT_PUBLIC_PROJECT_ID = 'pdmap_appu_test' \ No newline at end of file diff --git a/src/constants/index.ts b/src/constants/index.ts index 16e892f07522e3d15e68ac4d0e802f290a406b8c..9841d4db376dff71a623e453166bda61fc093ebb 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,4 +1,5 @@ export const BASE_API_URL = process.env.NEXT_PUBLIC_BASE_API_URL || ''; +export const BASE_NEW_API_URL = process.env.NEXT_PUBLIC_BASE_NEW_API_URL || ''; export const PROJECT_ID = process.env.NEXT_PUBLIC_PROJECT_ID || ''; export const ZOD_SEED = 997; export const BIO_ENTITY = 'bioEntity'; diff --git a/src/models/arrowSchema.ts b/src/models/arrowSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..68c5a069a21b62038fbc3008bd56d671327c9d26 --- /dev/null +++ b/src/models/arrowSchema.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +export const arrowSchema = z.object({ + arrowType: z.string(), + angle: z.number(), + lineType: z.string(), + length: z.number(), +}); diff --git a/src/models/bioEntityContentSchema.ts b/src/models/bioEntityContentSchema.ts index 1eb0d70467b9684f15aeaaedfeea1106e5fbdaa7..4ff85815794b73a621cf5909903b3de1f3443745 100644 --- a/src/models/bioEntityContentSchema.ts +++ b/src/models/bioEntityContentSchema.ts @@ -1,7 +1,8 @@ import { z } from 'zod'; +import { bioEntitySchema } from './bioEntitySchema'; export const bioEntityContentSchema = z.object({ - id: z.number(), - modelId: z.number(), - type: z.string(), + bioEntity: bioEntitySchema, + /** indicates if bioEntity matches perfect match even if not provided in query */ + perfect: z.boolean(), }); diff --git a/src/models/bioEntityResponseSchema.ts b/src/models/bioEntityResponseSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4b4827bfb60345751424d36fb8d4f68be030b5e --- /dev/null +++ b/src/models/bioEntityResponseSchema.ts @@ -0,0 +1,11 @@ +import { z } from 'zod'; +import { bioEntityContentSchema } from './bioEntityContentSchema'; + +export const bioEntityResponseSchema = z.object({ + content: z.array(bioEntityContentSchema), + totalPages: z.number(), + totalElements: z.number(), + numberOfElements: z.number(), + size: z.number(), + number: z.number(), +}); diff --git a/src/models/bioEntitySchema.ts b/src/models/bioEntitySchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..51f1880c44af38be603d8633c84bb0b8d7dc1432 --- /dev/null +++ b/src/models/bioEntitySchema.ts @@ -0,0 +1,80 @@ +import { z } from 'zod'; +import { referenceSchema } from './referenceSchema'; +import { glyphSchema } from './glyphSchema'; +import { modificationResiduesSchema } from './modificationResiduesSchema'; +import { submodelSchema } from './submodelSchema'; +import { colorSchema } from './colorSchema'; +import { productsSchema } from './products'; +import { lineSchema } from './lineSchema'; +import { operatorSchema } from './operatorSchema'; +import { structuralStateSchema } from './structuralStateSchema'; + +export const bioEntitySchema = z.object({ + id: z.number(), + stringType: z.string(), + name: z.string(), + elementId: z.string(), + model: z.number(), + references: z.array(referenceSchema), + z: z.number(), + notes: z.string(), + symbol: z.string().nullable(), + homodimer: z.number(), + nameX: z.number(), + nameY: z.number(), + nameWidth: z.number(), + nameHeight: z.number(), + nameVerticalAlign: z.string(), + nameHorizontalAlign: z.string(), + width: z.number(), + height: z.number(), + visibilityLevel: z.string(), + transparencyLevel: z.string(), + synonyms: z.array(z.string()), + formerSymbols: z.array(z.string()), + fullName: z.string().nullable(), + abbreviation: z.string().nullable(), + formula: z.string().nullable(), + glyph: glyphSchema.nullable(), + activity: z.boolean(), + structuralState: structuralStateSchema.nullable(), + hypothetical: z.boolean().nullable(), + boundaryCondition: z.boolean(), + constant: z.boolean(), + initialAmount: z.number().nullable(), + initialConcentration: z.number().nullable(), + charge: z.number().nullable(), + substanceUnits: z.string().nullable(), + onlySubstanceUnits: z.boolean(), + modificationResidues: z.optional(z.array(modificationResiduesSchema)), + complex: z.number().nullable(), + compartment: z.number().nullable(), + submodel: submodelSchema.nullable(), + x: z.number(), + y: z.number(), + lineWidth: z.number(), + fontColor: colorSchema, + fontSize: z.number(), + fillColor: colorSchema, + borderColor: colorSchema, + smiles: z.optional(z.string()), + inChI: z.optional(z.string().nullable()), + inChIKey: z.optional(z.string().nullable()), + thickness: z.optional(z.number()), + outerWidth: z.optional(z.number()), + innerWidth: z.optional(z.number()), + idReaction: z.optional(z.string()), + reversible: z.optional(z.boolean()), + mechanicalConfidenceScore: z.optional(z.boolean()), + lowerBound: z.optional(z.boolean()), + upperBound: z.optional(z.boolean()), + subsystem: z.optional(z.string()), + geneProteinReaction: z.optional(z.string()), + kinetics: z.optional(z.null()), + products: z.optional(z.array(productsSchema)), + reactants: z.optional(z.array(productsSchema)), + modifiers: z.optional(z.array(productsSchema)), + processCoordinates: z.optional(z.null()), + line: z.optional(lineSchema), + operators: z.optional(z.array(operatorSchema)), +}); diff --git a/src/models/colorSchema.ts b/src/models/colorSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..d40933695d9664644a048abb1888c8700afffa47 --- /dev/null +++ b/src/models/colorSchema.ts @@ -0,0 +1,6 @@ +import { z } from 'zod'; + +export const colorSchema = z.object({ + alpha: z.number(), + rgb: z.number(), +}); diff --git a/src/models/fixtures/bioEntityContentsFixture.ts b/src/models/fixtures/bioEntityContentsFixture.ts index fec6a7137e8f820642686b4104f4450e15ac5b6d..09fc894b35b14f223d06ac99cb43e72f4ff174cb 100644 --- a/src/models/fixtures/bioEntityContentsFixture.ts +++ b/src/models/fixtures/bioEntityContentsFixture.ts @@ -1,12 +1,11 @@ import { ZOD_SEED } from '@/constants'; import { bioEntityContentSchema } from '@/models/bioEntityContentSchema'; -import { z } from 'zod'; // eslint-disable-next-line import/no-extraneous-dependencies import { createFixture } from 'zod-fixture'; +import { bioEntityResponseSchema } from '../bioEntityResponseSchema'; -export const bioEntityContentsFixture = createFixture(z.array(bioEntityContentSchema), { +export const bioEntityResponseFixture = createFixture(bioEntityResponseSchema, { seed: ZOD_SEED, - array: { min: 2, max: 2 }, }); export const bioEntityContentFixture = createFixture(bioEntityContentSchema, { diff --git a/src/models/glyphSchema.ts b/src/models/glyphSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..ed69e8141e58fbe4002bb5a614fd3e673329377c --- /dev/null +++ b/src/models/glyphSchema.ts @@ -0,0 +1,5 @@ +import { z } from 'zod'; + +export const glyphSchema = z.object({ + file: z.number(), +}); diff --git a/src/models/lineSchema.ts b/src/models/lineSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..8db5ae33c1aabc5890cb62ed423e94a8c5b9c08b --- /dev/null +++ b/src/models/lineSchema.ts @@ -0,0 +1,15 @@ +import { z } from 'zod'; +import { colorSchema } from './colorSchema'; +import { segmentSchema } from './segmentSchema'; +import { arrowSchema } from './arrowSchema'; + +export const lineSchema = z.object({ + id: z.number(), + width: z.number(), + color: colorSchema, + z: z.number(), + segments: z.array(segmentSchema), + startArrow: arrowSchema, + endArrow: arrowSchema, + lineType: z.string(), +}); diff --git a/src/models/modelSchema.ts b/src/models/modelSchema.ts index 64752c8c1bd4043d1ff24cc0de26022f5f22daa2..0c8a488d7f340dc182ec0b62a1fbe785089d9340 100644 --- a/src/models/modelSchema.ts +++ b/src/models/modelSchema.ts @@ -15,17 +15,17 @@ export const modelSchema = z.object({ /** size of the png tile used to visualize in frontend */ tileSize: z.number(), /** default x center used in frontend visualization */ - defaultCenterX: z.union([z.number(), z.null()]), + defaultCenterX: z.number().nullable(), /** default y center used in frontend visualization */ - defaultCenterY: z.union([z.number(), z.null()]), + defaultCenterY: z.number().nullable(), /** default zoom level used in frontend visualization */ - defaultZoomLevel: z.union([z.number(), z.null()]), + defaultZoomLevel: z.number().nullable(), /** minimum zoom level availbale for the map */ minZoom: z.number(), /** maximum zoom level available for the map */ maxZoom: z.number(), authors: z.array(authorSchema), references: z.array(referenceSchema), - creationDate: z.union([z.string(), z.null()]), + creationDate: z.string().nullable(), modificationDates: z.array(z.string()), }); diff --git a/src/models/modificationResiduesSchema.ts b/src/models/modificationResiduesSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..884ebe4b5c2f5c5fe59eec89a2c115123b8adb73 --- /dev/null +++ b/src/models/modificationResiduesSchema.ts @@ -0,0 +1,15 @@ +import { z } from 'zod'; +import { positionSchema } from './positionSchema'; +import { colorSchema } from './colorSchema'; + +export const modificationResiduesSchema = z.object({ + id: z.number(), + idModificationResidue: z.string(), + name: z.string(), + position: positionSchema, + z: z.number(), + borderColor: colorSchema, + state: z.union([z.string(), z.number()]).nullable(), + size: z.number(), + elementId: z.string(), +}); diff --git a/src/models/operatorSchema.ts b/src/models/operatorSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..20f6305e34862db3cda4e2e4e059e8079f8873de --- /dev/null +++ b/src/models/operatorSchema.ts @@ -0,0 +1,13 @@ +import { z } from 'zod'; +import { lineSchema } from './lineSchema'; + +export const operatorSchema = z.object({ + id: z.number(), + line: lineSchema, + inputs: z.array(z.object({ id: z.number() })), + outputs: z.undefined(), + operatorText: z.string(), + reactantOperator: z.boolean(), + productOperator: z.boolean(), + modifierOperator: z.boolean(), +}); diff --git a/src/models/positionSchema.ts b/src/models/positionSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..cf91481d25b701d09dd996071db84c2df328fe27 --- /dev/null +++ b/src/models/positionSchema.ts @@ -0,0 +1,6 @@ +import { z } from 'zod'; + +export const positionSchema = z.object({ + x: z.number(), + y: z.number(), +}); diff --git a/src/models/products.ts b/src/models/products.ts new file mode 100644 index 0000000000000000000000000000000000000000..4807c4862dbe9be1abe5be98890bcbc5066b3509 --- /dev/null +++ b/src/models/products.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const productsSchema = z.object({ + aliasId: z.number(), + stoichiometry: z.number().nullable(), + type: z.optional(z.string()), +}); diff --git a/src/models/referenceSchema.ts b/src/models/referenceSchema.ts index 30c2bd65da5d6107397d3e72280865ce2305b258..30a31e287cfdc79348e9655b635a417a0729a34b 100644 --- a/src/models/referenceSchema.ts +++ b/src/models/referenceSchema.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { articleSchema } from './articleSchema'; export const referenceSchema = z.object({ - link: z.string(), + link: z.string().nullable(), article: articleSchema.optional(), type: z.string(), resource: z.string(), diff --git a/src/models/segmentSchema.ts b/src/models/segmentSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..34c8155dd1c26bfe33f33bb452707d51ecbacdb6 --- /dev/null +++ b/src/models/segmentSchema.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +export const segmentSchema = z.object({ + x1: z.number(), + y1: z.number(), + x2: z.number(), + y2: z.number(), +}); diff --git a/src/models/structuralStateSchema.ts b/src/models/structuralStateSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ef0f149b4d4d0b3fa4e4158296ad6d8f789d949 --- /dev/null +++ b/src/models/structuralStateSchema.ts @@ -0,0 +1,16 @@ +import { z } from 'zod'; +import { positionSchema } from './positionSchema'; +import { colorSchema } from './colorSchema'; + +export const structuralStateSchema = z.object({ + value: z.string(), + position: positionSchema, + z: z.number(), + width: z.number(), + height: z.number(), + fontSize: z.number(), + size: z.number(), + center: positionSchema, + borderColor: colorSchema, + elementId: z.string(), +}); diff --git a/src/models/submodelSchema.ts b/src/models/submodelSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..634522b96339a8e3ca4e6e7a2805ebe7505770b0 --- /dev/null +++ b/src/models/submodelSchema.ts @@ -0,0 +1,6 @@ +import { z } from 'zod'; + +export const submodelSchema = z.object({ + mapId: z.number(), + type: z.string(), +}); diff --git a/src/redux/apiPath.test.ts b/src/redux/apiPath.test.ts index e1337f97c6f7f73f141d5739313c1868ab357f30..d23bffc005c9cb4587b70e60f574aee2720198af 100644 --- a/src/redux/apiPath.test.ts +++ b/src/redux/apiPath.test.ts @@ -16,7 +16,7 @@ describe('api path', () => { it('should return url string for bio entity content', () => { expect(apiPath.getBioEntityContentsStringWithQuery('park7')).toBe( - `projects/${PROJECT_ID}/models/*/bioEntities:search?query=park7`, + `projects/${PROJECT_ID}/models/*/bioEntities/:search?query=park7&size=1000`, ); }); diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts index 11ce6f11c1e59f6e8f6a4bf38037ac62e2e501a2..c9df159acff7b313a359a0bc6d6c107b0ec51759 100644 --- a/src/redux/apiPath.ts +++ b/src/redux/apiPath.ts @@ -2,7 +2,7 @@ import { PROJECT_ID } from '@/constants'; export const apiPath = { getBioEntityContentsStringWithQuery: (searchQuery: string): string => - `projects/${PROJECT_ID}/models/*/bioEntities:search?query=${searchQuery}`, + `projects/${PROJECT_ID}/models/*/bioEntities/:search?query=${searchQuery}&size=1000`, getDrugsStringWithQuery: (searchQuery: string): string => `projects/${PROJECT_ID}/drugs:search?query=${searchQuery}`, getMirnasStringWithQuery: (searchQuery: string): string => diff --git a/src/redux/bioEntityContents/bioEntityContents.reducers.test.ts b/src/redux/bioEntity/bioEntity.reducers.test.ts similarity index 51% rename from src/redux/bioEntityContents/bioEntityContents.reducers.test.ts rename to src/redux/bioEntity/bioEntity.reducers.test.ts index 12831d5c7b0c2bb05d54f2ca863fa9fd655ea1f0..ed3afdbda94f2b9a5ed7641b292337e7a6ce57af 100644 --- a/src/redux/bioEntityContents/bioEntityContents.reducers.test.ts +++ b/src/redux/bioEntity/bioEntity.reducers.test.ts @@ -1,16 +1,16 @@ -import { bioEntityContentsFixture } from '@/models/fixtures/bioEntityContentsFixture'; -import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { ToolkitStoreWithSingleSlice, createStoreInstanceUsingSliceReducer, } from '@/utils/createStoreInstanceUsingSliceReducer'; import { HttpStatusCode } from 'axios'; import { apiPath } from '@/redux/apiPath'; -import { getBioEntityContents } from './bioEntityContents.thunks'; -import bioEntityContentsReducer from './bioEntityContents.slice'; -import { BioEntityContentsState } from './bioEntityContents.types'; +import { getBioEntity } from './bioEntity.thunks'; +import bioEntityContentsReducer from './bioEntity.slice'; +import { BioEntityContentsState } from './bioEntity.types'; -const mockedAxiosClient = mockNetworkResponse(); +const mockedAxiosClient = mockNetworkNewAPIResponse(); const SEARCH_QUERY = 'park7'; const INITIAL_STATE: BioEntityContentsState = { @@ -19,10 +19,10 @@ const INITIAL_STATE: BioEntityContentsState = { error: { name: '', message: '' }, }; -describe('bioEntityContents reducer', () => { +describe('bioEntity reducer', () => { let store = {} as ToolkitStoreWithSingleSlice<BioEntityContentsState>; beforeEach(() => { - store = createStoreInstanceUsingSliceReducer('bioEntityContents', bioEntityContentsReducer); + store = createStoreInstanceUsingSliceReducer('bioEntity', bioEntityContentsReducer); }); it('should match initial state', () => { @@ -30,27 +30,27 @@ describe('bioEntityContents reducer', () => { expect(bioEntityContentsReducer(undefined, action)).toEqual(INITIAL_STATE); }); - it('should update store after succesfull getBioEntityContents query', async () => { + it('should update store after succesfull getBioEntity query', async () => { mockedAxiosClient .onGet(apiPath.getBioEntityContentsStringWithQuery(SEARCH_QUERY)) - .reply(HttpStatusCode.Ok, bioEntityContentsFixture); + .reply(HttpStatusCode.Ok, bioEntityResponseFixture); - const { type } = await store.dispatch(getBioEntityContents(SEARCH_QUERY)); - const { data, loading, error } = store.getState().bioEntityContents; + const { type } = await store.dispatch(getBioEntity(SEARCH_QUERY)); + const { data, loading, error } = store.getState().bioEntity; expect(type).toBe('project/getBioEntityContents/fulfilled'); expect(loading).toEqual('succeeded'); expect(error).toEqual({ message: '', name: '' }); - expect(data).toEqual(bioEntityContentsFixture); + expect(data).toEqual(bioEntityResponseFixture.content); }); - it('should update store after failed getBioEntityContents query', async () => { + it('should update store after failed getBioEntity query', async () => { mockedAxiosClient .onGet(apiPath.getBioEntityContentsStringWithQuery(SEARCH_QUERY)) - .reply(HttpStatusCode.NotFound, bioEntityContentsFixture); + .reply(HttpStatusCode.NotFound, bioEntityResponseFixture); - const { type } = await store.dispatch(getBioEntityContents(SEARCH_QUERY)); - const { data, loading, error } = store.getState().bioEntityContents; + const { type } = await store.dispatch(getBioEntity(SEARCH_QUERY)); + const { data, loading, error } = store.getState().bioEntity; expect(type).toBe('project/getBioEntityContents/rejected'); expect(loading).toEqual('failed'); @@ -58,22 +58,21 @@ describe('bioEntityContents reducer', () => { expect(data).toEqual([]); }); - it('should update store on loading getBioEntityContents query', async () => { + it('should update store on loading getBioEntity query', async () => { mockedAxiosClient .onGet(apiPath.getBioEntityContentsStringWithQuery(SEARCH_QUERY)) - .reply(HttpStatusCode.Ok, bioEntityContentsFixture); + .reply(HttpStatusCode.Ok, bioEntityResponseFixture); - const bioEntityContentsPromise = store.dispatch(getBioEntityContents(SEARCH_QUERY)); + const bioEntityContentsPromise = store.dispatch(getBioEntity(SEARCH_QUERY)); - const { data, loading } = store.getState().bioEntityContents; + const { data, loading } = store.getState().bioEntity; expect(data).toEqual([]); expect(loading).toEqual('pending'); bioEntityContentsPromise.then(() => { - const { data: dataPromiseFulfilled, loading: promiseFulfilled } = - store.getState().bioEntityContents; + const { data: dataPromiseFulfilled, loading: promiseFulfilled } = store.getState().bioEntity; - expect(dataPromiseFulfilled).toEqual(bioEntityContentsFixture); + expect(dataPromiseFulfilled).toEqual(bioEntityResponseFixture.content); expect(promiseFulfilled).toEqual('succeeded'); }); }); diff --git a/src/redux/bioEntityContents/bioEntityContents.reducers.ts b/src/redux/bioEntity/bioEntity.reducers.ts similarity index 54% rename from src/redux/bioEntityContents/bioEntityContents.reducers.ts rename to src/redux/bioEntity/bioEntity.reducers.ts index d8806feb7989dbfb6cf7a0d2876711c774feec4d..48ce02f4ce25e3b734ae97c905b767a03edbb101 100644 --- a/src/redux/bioEntityContents/bioEntityContents.reducers.ts +++ b/src/redux/bioEntity/bioEntity.reducers.ts @@ -1,18 +1,18 @@ import { ActionReducerMapBuilder } from '@reduxjs/toolkit'; -import { BioEntityContentsState } from './bioEntityContents.types'; -import { getBioEntityContents } from './bioEntityContents.thunks'; +import { BioEntityContentsState } from './bioEntity.types'; +import { getBioEntity } from './bioEntity.thunks'; export const getBioEntityContentsReducer = ( builder: ActionReducerMapBuilder<BioEntityContentsState>, ): void => { - builder.addCase(getBioEntityContents.pending, state => { + builder.addCase(getBioEntity.pending, state => { state.loading = 'pending'; }); - builder.addCase(getBioEntityContents.fulfilled, (state, action) => { + builder.addCase(getBioEntity.fulfilled, (state, action) => { state.data = action.payload; state.loading = 'succeeded'; }); - builder.addCase(getBioEntityContents.rejected, state => { + builder.addCase(getBioEntity.rejected, state => { state.loading = 'failed'; // TODO: error management to be discussed in the team }); diff --git a/src/redux/bioEntityContents/bioEntityContents.selectors.ts b/src/redux/bioEntity/bioEntity.selectors.ts similarity index 67% rename from src/redux/bioEntityContents/bioEntityContents.selectors.ts rename to src/redux/bioEntity/bioEntity.selectors.ts index 80a88cb0bec55d0ebf43ba8dd85827b44b429121..b29b13b78a665ebf7bc42a06c58d45312364abdc 100644 --- a/src/redux/bioEntityContents/bioEntityContents.selectors.ts +++ b/src/redux/bioEntity/bioEntity.selectors.ts @@ -1,10 +1,7 @@ import { rootSelector } from '@/redux/root/root.selectors'; import { createSelector } from '@reduxjs/toolkit'; -export const bioEntityContentsSelector = createSelector( - rootSelector, - state => state.bioEntityContents, -); +export const bioEntityContentsSelector = createSelector(rootSelector, state => state.bioEntity); export const loadingBioEntityStatusSelector = createSelector( bioEntityContentsSelector, diff --git a/src/redux/bioEntityContents/bioEntityContents.slice.ts b/src/redux/bioEntity/bioEntity.slice.ts similarity index 70% rename from src/redux/bioEntityContents/bioEntityContents.slice.ts rename to src/redux/bioEntity/bioEntity.slice.ts index 97e3b73cbb92836c41263f9cc4744bf9f756799f..1400797ae523cac389458436f9dfd5280aba24b4 100644 --- a/src/redux/bioEntityContents/bioEntityContents.slice.ts +++ b/src/redux/bioEntity/bioEntity.slice.ts @@ -1,6 +1,6 @@ import { createSlice } from '@reduxjs/toolkit'; -import { BioEntityContentsState } from '@/redux/bioEntityContents/bioEntityContents.types'; -import { getBioEntityContentsReducer } from './bioEntityContents.reducers'; +import { BioEntityContentsState } from '@/redux/bioEntity/bioEntity.types'; +import { getBioEntityContentsReducer } from './bioEntity.reducers'; const initialState: BioEntityContentsState = { data: [], diff --git a/src/redux/bioEntityContents/bioEntityContents.thunks.test.ts b/src/redux/bioEntity/bioEntity.thunks.test.ts similarity index 61% rename from src/redux/bioEntityContents/bioEntityContents.thunks.test.ts rename to src/redux/bioEntity/bioEntity.thunks.test.ts index 540e29ce5181233a2ce2667a19fcfcdb3e6e7135..b5b51d289aa49fa406b619e3e1fa1924a5afd9f1 100644 --- a/src/redux/bioEntityContents/bioEntityContents.thunks.test.ts +++ b/src/redux/bioEntity/bioEntity.thunks.test.ts @@ -1,16 +1,16 @@ -import { bioEntityContentsFixture } from '@/models/fixtures/bioEntityContentsFixture'; -import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { ToolkitStoreWithSingleSlice, createStoreInstanceUsingSliceReducer, } from '@/utils/createStoreInstanceUsingSliceReducer'; import { HttpStatusCode } from 'axios'; import { apiPath } from '@/redux/apiPath'; -import { getBioEntityContents } from './bioEntityContents.thunks'; -import contentsReducer from './bioEntityContents.slice'; -import { BioEntityContentsState } from './bioEntityContents.types'; +import { getBioEntity } from './bioEntity.thunks'; +import contentsReducer from './bioEntity.slice'; +import { BioEntityContentsState } from './bioEntity.types'; -const mockedAxiosClient = mockNetworkResponse(); +const mockedAxiosClient = mockNetworkNewAPIResponse(); const SEARCH_QUERY = 'park7'; describe('bioEntityContents thunks', () => { @@ -22,17 +22,17 @@ describe('bioEntityContents thunks', () => { it('should return data when data response from API is valid', async () => { mockedAxiosClient .onGet(apiPath.getBioEntityContentsStringWithQuery(SEARCH_QUERY)) - .reply(HttpStatusCode.Ok, bioEntityContentsFixture); + .reply(HttpStatusCode.Ok, bioEntityResponseFixture); - const { payload } = await store.dispatch(getBioEntityContents(SEARCH_QUERY)); - expect(payload).toEqual(bioEntityContentsFixture); + const { payload } = await store.dispatch(getBioEntity(SEARCH_QUERY)); + expect(payload).toEqual(bioEntityResponseFixture.content); }); it('should return undefined when data response from API is not valid ', async () => { mockedAxiosClient .onGet(apiPath.getBioEntityContentsStringWithQuery(SEARCH_QUERY)) .reply(HttpStatusCode.Ok, { randomProperty: 'randomValue' }); - const { payload } = await store.dispatch(getBioEntityContents(SEARCH_QUERY)); + const { payload } = await store.dispatch(getBioEntity(SEARCH_QUERY)); expect(payload).toEqual(undefined); }); }); diff --git a/src/redux/bioEntityContents/bioEntityContents.thunks.ts b/src/redux/bioEntity/bioEntity.thunks.ts similarity index 50% rename from src/redux/bioEntityContents/bioEntityContents.thunks.ts rename to src/redux/bioEntity/bioEntity.thunks.ts index 6ccda7e246a6dd21568856018632752f1d9390bd..c175948124fa5fd2e193f5e0cca003d9743fad44 100644 --- a/src/redux/bioEntityContents/bioEntityContents.thunks.ts +++ b/src/redux/bioEntity/bioEntity.thunks.ts @@ -1,20 +1,19 @@ -import { z } from 'zod'; import { createAsyncThunk } from '@reduxjs/toolkit'; -import { axiosInstance } from '@/services/api/utils/axiosInstance'; -import { BioEntityContent } from '@/types/models'; -import { bioEntityContentSchema } from '@/models/bioEntityContentSchema'; +import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; +import { BioEntityContent, BioEntityResponse } from '@/types/models'; import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; import { apiPath } from '@/redux/apiPath'; +import { bioEntityResponseSchema } from '@/models/bioEntityResponseSchema'; -export const getBioEntityContents = createAsyncThunk( +export const getBioEntity = createAsyncThunk( 'project/getBioEntityContents', async (searchQuery: string): Promise<BioEntityContent[] | undefined> => { - const response = await axiosInstance.get<BioEntityContent[]>( + const response = await axiosInstanceNewAPI.get<BioEntityResponse>( apiPath.getBioEntityContentsStringWithQuery(searchQuery), ); - const isDataValid = validateDataUsingZodSchema(response.data, z.array(bioEntityContentSchema)); + const isDataValid = validateDataUsingZodSchema(response.data, bioEntityResponseSchema); - return isDataValid ? response.data : undefined; + return isDataValid ? response.data.content : undefined; }, ); diff --git a/src/redux/bioEntityContents/bioEntityContents.types.ts b/src/redux/bioEntity/bioEntity.types.ts similarity index 100% rename from src/redux/bioEntityContents/bioEntityContents.types.ts rename to src/redux/bioEntity/bioEntity.types.ts diff --git a/src/redux/search/search.thunks.ts b/src/redux/search/search.thunks.ts index 2724826c65aa793de889176cc3fe75764509ec1c..88dfc4f4dcc04fea7c30fd46241d27e72b8d478e 100644 --- a/src/redux/search/search.thunks.ts +++ b/src/redux/search/search.thunks.ts @@ -1,4 +1,4 @@ -import { getBioEntityContents } from '@/redux/bioEntityContents/bioEntityContents.thunks'; +import { getBioEntity } from '@/redux/bioEntity/bioEntity.thunks'; import { getChemicals } from '@/redux/chemicals/chemicals.thunks'; import { getDrugs } from '@/redux/drugs/drugs.thunks'; import { getMirnas } from '@/redux/mirnas/mirnas.thunks'; @@ -9,7 +9,7 @@ export const getSearchData = createAsyncThunk( async (searchQuery: string, { dispatch }): Promise<void> => { await Promise.all([ dispatch(getDrugs(searchQuery)), - dispatch(getBioEntityContents(searchQuery)), + dispatch(getBioEntity(searchQuery)), dispatch(getChemicals(searchQuery)), dispatch(getMirnas(searchQuery)), ]); diff --git a/src/redux/store.ts b/src/redux/store.ts index 4d16d81bf05937fca10c7390f19778fdfce73742..35208d7d0978999cb466ecac53889822ed814312 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -1,4 +1,4 @@ -import bioEntityContentsReducer from '@/redux/bioEntityContents/bioEntityContents.slice'; +import bioEntityReducer from '@/redux/bioEntity/bioEntity.slice'; import chemicalsReducer from '@/redux/chemicals/chemicals.slice'; import drawerReducer from '@/redux/drawer/drawer.slice'; import drugsReducer from '@/redux/drugs/drugs.slice'; @@ -16,7 +16,7 @@ export const store = configureStore({ drugs: drugsReducer, mirnas: mirnasReducer, chemicals: chemicalsReducer, - bioEntityContents: bioEntityContentsReducer, + bioEntity: bioEntityReducer, drawer: drawerReducer, map: mapReducer, models: modelsReducer, diff --git a/src/services/api/utils/axiosInstance.ts b/src/services/api/utils/axiosInstance.ts index 5912be0111ef30130d07af064b423be058b389ec..aaa17d287f1f0d3023f1d178e7ac54adf57ea9a8 100644 --- a/src/services/api/utils/axiosInstance.ts +++ b/src/services/api/utils/axiosInstance.ts @@ -1,6 +1,10 @@ -import { BASE_API_URL } from '@/constants'; +import { BASE_API_URL, BASE_NEW_API_URL } from '@/constants'; import axios from 'axios'; export const axiosInstance = axios.create({ baseURL: BASE_API_URL, }); + +export const axiosInstanceNewAPI = axios.create({ + baseURL: BASE_NEW_API_URL, +}); diff --git a/src/types/models.ts b/src/types/models.ts index 8902849349a999a58661d14d73d5734574f96130..13be16b5f76d48c14e55bac7440336425a9696c5 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -1,4 +1,3 @@ -import { bioEntityContentSchema } from '@/models/bioEntityContentSchema'; import { chemicalSchema } from '@/models/chemicalSchema'; import { disease } from '@/models/disease'; import { drugSchema } from '@/models/drugSchema'; @@ -7,12 +6,17 @@ import { organism } from '@/models/organism'; import { projectSchema } from '@/models/project'; import { z } from 'zod'; import { modelSchema } from '@/models/modelSchema'; +import { bioEntitySchema } from '@/models/bioEntitySchema'; +import { bioEntityResponseSchema } from '@/models/bioEntityResponseSchema'; +import { bioEntityContentSchema } from '@/models/bioEntityContentSchema'; export type Project = z.infer<typeof projectSchema>; export type Organism = z.infer<typeof organism>; export type Disease = z.infer<typeof disease>; export type Drug = z.infer<typeof drugSchema>; export type Mirna = z.infer<typeof mirnaSchema>; +export type BioEntity = z.infer<typeof bioEntitySchema>; export type BioEntityContent = z.infer<typeof bioEntityContentSchema>; +export type BioEntityResponse = z.infer<typeof bioEntityResponseSchema>; export type Model = z.infer<typeof modelSchema>; export type Chemical = z.infer<typeof chemicalSchema>; diff --git a/src/utils/mockNetworkResponse.ts b/src/utils/mockNetworkResponse.ts index 4f7bd1098b390c116d72c591feda2ecf14eab949..67077e0286c5b06b4c8c190f267db9170d8c1be7 100644 --- a/src/utils/mockNetworkResponse.ts +++ b/src/utils/mockNetworkResponse.ts @@ -1,8 +1,13 @@ // eslint-disable-next-line import/no-extraneous-dependencies import MockAdapter from 'axios-mock-adapter'; -import { axiosInstance } from '@/services/api/utils/axiosInstance'; +import { axiosInstance, axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; export const mockNetworkResponse = (): MockAdapter => { const mock = new MockAdapter(axiosInstance); return mock; }; + +export const mockNetworkNewAPIResponse = (): MockAdapter => { + const mock = new MockAdapter(axiosInstanceNewAPI); + return mock; +}; diff --git a/src/utils/testing/getReduxWrapperWithStore.tsx b/src/utils/testing/getReduxWrapperWithStore.tsx index bfff374c2d6fa878ef1cae2ee7a75637c57d5a7e..05e4a4536cec509deef92d9c296584e77de2f3e3 100644 --- a/src/utils/testing/getReduxWrapperWithStore.tsx +++ b/src/utils/testing/getReduxWrapperWithStore.tsx @@ -1,4 +1,4 @@ -import bioEntityContentsReducer from '@/redux/bioEntityContents/bioEntityContents.slice'; +import bioEntityReducer from '@/redux/bioEntity/bioEntity.slice'; import chemicalsReducer from '@/redux/chemicals/chemicals.slice'; import drawerReducer from '@/redux/drawer/drawer.slice'; import drugsReducer from '@/redux/drugs/drugs.slice'; @@ -32,7 +32,7 @@ export const getReduxWrapperWithStore: GetReduxWrapperUsingSliceReducer = ( drugs: drugsReducer, mirnas: mirnasReducer, chemicals: chemicalsReducer, - bioEntityContents: bioEntityContentsReducer, + bioEntity: bioEntityReducer, drawer: drawerReducer, models: modelsReducer, map: mapReducer,