diff --git a/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts b/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts index 2ba83189feb03c61dd36bb018a9519b485a81772..8a09ebb08aca68fb46d2bb1a908fceb45c41bd56 100644 --- a/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts +++ b/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts @@ -1,11 +1,11 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; -import { z } from 'zod'; import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; import { OverlayBioEntity } from '@/types/models'; -import { overlayBioEntitySchema } from '@/models/overlayBioEntitySchema'; -import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; import { OverlayBioEntityRender } from '@/types/OLrendering'; -import { parseOverlayBioEntityToOlRenderingFormat } from './overlayBioEntity.utils'; +import { + getValidOverlayBioEntities, + parseOverlayBioEntityToOlRenderingFormat, +} from './overlayBioEntity.utils'; import { apiPath } from '../apiPath'; import { modelsIdsSelector } from '../models/models.selectors'; import type { RootState } from '../store'; @@ -27,10 +27,10 @@ export const getOverlayBioEntity = createAsyncThunk( apiPath.getOverlayBioEntity({ overlayId, modelId }), ); - const isDataValid = validateDataUsingZodSchema(response.data, z.array(overlayBioEntitySchema)); + const validOverlayBioEntities = getValidOverlayBioEntities(response.data); - if (isDataValid) { - return parseOverlayBioEntityToOlRenderingFormat(response.data, overlayId); + if (validOverlayBioEntities) { + return parseOverlayBioEntityToOlRenderingFormat(validOverlayBioEntities, overlayId); } return undefined; diff --git a/src/redux/overlayBioEntity/overlayBioEntity.utils.test.ts b/src/redux/overlayBioEntity/overlayBioEntity.utils.test.ts index 5714a9a799a8b56f2d6ae54ccac8055261fa613c..abb5b8fb8b1a2e841f19a268a3c49a4e2350de02 100644 --- a/src/redux/overlayBioEntity/overlayBioEntity.utils.test.ts +++ b/src/redux/overlayBioEntity/overlayBioEntity.utils.test.ts @@ -1,4 +1,6 @@ -import { calculateOvarlaysOrder } from './overlayBioEntity.utils'; +import { overlayBioEntityFixture } from '@/models/fixtures/overlayBioEntityFixture'; +import { OverlayBioEntity } from '@/types/models'; +import { calculateOvarlaysOrder, getValidOverlayBioEntities } from './overlayBioEntity.utils'; describe('calculateOverlaysOrder', () => { const cases = [ @@ -62,3 +64,37 @@ describe('calculateOverlaysOrder', () => { expect(calculateOvarlaysOrder(data)).toStrictEqual(expected); }); }); + +describe('getValidOverlayBioEntities', () => { + it('should return empty array if overlayBioEntities are empty array', () => { + const result = getValidOverlayBioEntities([]); + + expect(result).toEqual([]); + }); + it('should return the same overlayBioEntities if all overlayBioEntities are valid', () => { + const result = getValidOverlayBioEntities(overlayBioEntityFixture); + expect(result).toEqual(overlayBioEntityFixture); + }); + it('should filter properly and return valid overlayBioEntities if overlayBioEntities are mixed array with valid and invalid entities', () => { + const invalidOverlayBioEntities = overlayBioEntityFixture.map(overlayBioEntity => ({ + ...overlayBioEntity, + left: {}, + })) as OverlayBioEntity[]; + + const result = getValidOverlayBioEntities([ + ...overlayBioEntityFixture, + ...invalidOverlayBioEntities, + ]); + expect(result).toEqual(overlayBioEntityFixture); + }); + it('should return empty array if all overlayBioEntities are invalid', () => { + const invalidOverlayBioEntities = overlayBioEntityFixture.map(overlayBioEntity => ({ + ...overlayBioEntity, + right: {}, + })) as OverlayBioEntity[]; + + const result = getValidOverlayBioEntities(invalidOverlayBioEntities); + + expect(result).toEqual([]); + }); +}); diff --git a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts index e632f31a4fd5cb75b966d33868cddf9f0acf1777..7c92f7a20080e78660bcf391194990c13940451b 100644 --- a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts +++ b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts @@ -1,6 +1,8 @@ import { ONE } from '@/constants/common'; +import { overlayBioEntitySchema } from '@/models/overlayBioEntitySchema'; import { OverlayBioEntityRender } from '@/types/OLrendering'; import { OverlayBioEntity } from '@/types/models'; +import { z } from 'zod'; export const parseOverlayBioEntityToOlRenderingFormat = ( data: OverlayBioEntity[], @@ -66,3 +68,23 @@ export const calculateOvarlaysOrder = ( return overlaysOrder; }; + +const isValidOverlayBioEntity = (overlayBioEntity: OverlayBioEntity): boolean => { + return overlayBioEntitySchema.safeParse(overlayBioEntity).success; +}; + +type OverlayBioEntities = OverlayBioEntity[]; + +export const getValidOverlayBioEntities = ( + unvalidatedOverlayBioEntities: OverlayBioEntities, +): OverlayBioEntities | undefined => { + const filteredValidOverlayBioEntitiesSchema = z + .array(z.any()) + .transform(overlayBioEntities => overlayBioEntities.filter(isValidOverlayBioEntity)); + + const parsedOverlayBioEntities = filteredValidOverlayBioEntitiesSchema.safeParse( + unvalidatedOverlayBioEntities, + ); + + return parsedOverlayBioEntities.success ? parsedOverlayBioEntities.data : undefined; +};