From a51328e95522c08995421c413d63f8552b8b6d09 Mon Sep 17 00:00:00 2001
From: mateusz-winiarczyk <mateusz.winiarczyk@appunite.com>
Date: Tue, 16 Jan 2024 15:19:51 +0100
Subject: [PATCH] feat(overlaybioentity): add util to get validated overlay bio
 entities

---
 .../overlayBioEntity.thunk.ts                 | 14 +++----
 .../overlayBioEntity.utils.test.ts            | 38 ++++++++++++++++++-
 .../overlayBioEntity.utils.ts                 | 22 +++++++++++
 3 files changed, 66 insertions(+), 8 deletions(-)

diff --git a/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts b/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts
index 2ba83189..8a09ebb0 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 5714a9a7..abb5b8fb 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 e632f31a..7c92f7a2 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;
+};
-- 
GitLab