From 5bdfb65b7129f98c8df3dd7703192c6670806201 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tadeusz=20Miesi=C4=85c?= <tadeusz.miesiac@gmail.com>
Date: Mon, 22 Jan 2024 11:45:17 +0100
Subject: [PATCH] refactor(project drawer): changed project schema

---
 .../Map/Drawer/Drawer.component.test.tsx      |  8 ++--
 .../ProjectInfoDrawer.component.test.tsx      | 38 +++++++++----------
 .../ProjectInfoDrawer.component.tsx           | 18 ++++++---
 .../ProjectInfoDrawer/hooks/useDisease.ts     | 37 ------------------
 .../ProjectInfoDrawer/hooks/useOrganism.ts    | 37 ------------------
 src/models/fixtures/meshFixture.ts            |  8 ----
 src/models/fixtures/projectFixture.ts         |  2 +-
 src/models/fixtures/taxonomyFixture.ts        |  8 ----
 src/models/meshSchema.ts                      |  8 ----
 src/models/{project.ts => projectSchema.ts}   |  7 +++-
 src/models/taxonomySchema.ts                  |  6 ---
 src/redux/project/project.reducers.test.ts    |  4 +-
 src/redux/project/project.selectors.ts        | 12 +++---
 src/redux/project/project.thunks.ts           |  6 +--
 src/types/models.ts                           |  6 +--
 .../initialize/useInitializeStore.test.ts     |  5 ++-
 16 files changed, 57 insertions(+), 153 deletions(-)
 delete mode 100644 src/components/Map/Drawer/ProjectInfoDrawer/hooks/useDisease.ts
 delete mode 100644 src/components/Map/Drawer/ProjectInfoDrawer/hooks/useOrganism.ts
 delete mode 100644 src/models/fixtures/meshFixture.ts
 delete mode 100644 src/models/fixtures/taxonomyFixture.ts
 delete mode 100644 src/models/meshSchema.ts
 rename src/models/{project.ts => projectSchema.ts} (85%)
 delete mode 100644 src/models/taxonomySchema.ts

diff --git a/src/components/Map/Drawer/Drawer.component.test.tsx b/src/components/Map/Drawer/Drawer.component.test.tsx
index fb4be23d..2499e7f3 100644
--- a/src/components/Map/Drawer/Drawer.component.test.tsx
+++ b/src/components/Map/Drawer/Drawer.component.test.tsx
@@ -104,10 +104,10 @@ describe('Drawer - component', () => {
       });
 
       expect(screen.queryByTestId('reaction-drawer')).not.toBeInTheDocument();
-
-      store.dispatch(getReactionsByIds([id]));
-      store.dispatch(openReactionDrawerById(id));
-
+      await act(() => {
+        store.dispatch(getReactionsByIds([id]));
+        store.dispatch(openReactionDrawerById(id));
+      });
       await waitFor(() => expect(screen.getByTestId('reaction-drawer')).toBeInTheDocument());
     });
   });
diff --git a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.test.tsx b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.test.tsx
index 560ab58a..bfad3705 100644
--- a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.test.tsx
+++ b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.test.tsx
@@ -1,4 +1,3 @@
-import { HttpStatusCode } from 'axios';
 import { act } from 'react-dom/test-utils';
 import { render, screen } from '@testing-library/react';
 import {
@@ -7,15 +6,9 @@ import {
 } from '@/utils/testing/getReduxWrapperWithStore';
 import { projectFixture } from '@/models/fixtures/projectFixture';
 import { StoreType } from '@/redux/store';
-import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
 import { MODEL_WITH_DESCRIPTION } from '@/models/mocks/modelsMock';
-import { meshFixture } from '@/models/fixtures/meshFixture';
-import { apiPath } from '@/redux/apiPath';
-import { taxonomyFixture } from '@/models/fixtures/taxonomyFixture';
 import { ProjectInfoDrawer } from './ProjectInfoDrawer.component';
 
-const mockedAxiosClient = mockNetworkResponse();
-
 const MOCKED_STORE: InitialStoreState = {
   project: {
     data: { ...projectFixture },
@@ -44,10 +37,6 @@ const renderComponent = (initialStore?: InitialStoreState): { store: StoreType }
 };
 
 describe('ProjectInfoDrawer', () => {
-  beforeEach(() => {
-    mockedAxiosClient.reset();
-  });
-
   it('should render the project name', () => {
     renderComponent(MOCKED_STORE);
 
@@ -72,9 +61,6 @@ describe('ProjectInfoDrawer', () => {
   });
 
   it('should render the disease link with name and href', async () => {
-    mockedAxiosClient
-      .onGet(apiPath.getMesh(projectFixture.disease.resource))
-      .reply(HttpStatusCode.Ok, meshFixture);
     await act(() => {
       renderComponent(MOCKED_STORE);
     });
@@ -82,15 +68,12 @@ describe('ProjectInfoDrawer', () => {
     const diseaseLink = screen.getByText(/Disease:/i);
     expect(diseaseLink).toBeInTheDocument();
 
-    const linkelement = screen.getByRole('link', { name: meshFixture.name });
+    const linkelement = screen.getByRole('link', { name: projectFixture.diseaseName });
     expect(linkelement).toBeInTheDocument();
     expect(linkelement).toHaveAttribute('href', projectFixture.disease.link);
   });
 
   it('should fetch diesease name when diseaseId is provided', async () => {
-    mockedAxiosClient
-      .onGet(apiPath.getTaxonomy(projectFixture.organism.resource))
-      .reply(HttpStatusCode.Ok, taxonomyFixture);
     await act(() => {
       renderComponent(MOCKED_STORE);
     });
@@ -98,7 +81,7 @@ describe('ProjectInfoDrawer', () => {
     const organismLink = screen.getByText(/Organism:/i);
     expect(organismLink).toBeInTheDocument();
 
-    const linkelement = screen.getByRole('link', { name: taxonomyFixture.name });
+    const linkelement = screen.getByRole('link', { name: projectFixture.organismName });
     expect(linkelement).toBeInTheDocument();
     expect(linkelement).toHaveAttribute('href', projectFixture.organism.link);
   });
@@ -114,4 +97,21 @@ describe('ProjectInfoDrawer', () => {
     );
     expect(downloadButton).toHaveAttribute('download', 'sourceFile.txt');
   });
+
+  it('should render the description when it exists', () => {
+    renderComponent(MOCKED_STORE);
+
+    const desc = screen.getByTestId('project-description');
+
+    expect(desc.innerHTML).toContain(
+      'For information on content, functionalities and referencing the Parkinson\'s disease map, click <a href="http://pdmap.uni.lu" target="_blank">here</a>',
+    );
+  });
+
+  it.skip('should not render the description when it does not exist', () => {
+    renderComponent();
+
+    const descriptionElement = screen.queryByText('This is the project description.');
+    expect(descriptionElement).not.toBeInTheDocument();
+  });
 });
diff --git a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx
index 439a017a..31823981 100644
--- a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx
+++ b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx
@@ -1,16 +1,23 @@
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { projectNameSelector, versionSelector } from '@/redux/project/project.selectors';
+import {
+  diseaseNameSelector,
+  projectNameSelector,
+  versionSelector,
+  organismNameSelector,
+  diseaseLinkSelector,
+  organismLinkSelector,
+} from '@/redux/project/project.selectors';
 import { DrawerHeading } from '@/shared/DrawerHeading';
 import { apiPath } from '@/redux/apiPath';
 import { LinkButton } from '@/shared/LinkButton';
 import { mainMapModelDescriptionSelector } from '@/redux/models/models.selectors';
 import './ProjectInfoDrawer.styles.css';
-import { useDisease } from './hooks/useDisease';
-import { useOrganism } from './hooks/useOrganism';
 
 export const ProjectInfoDrawer = (): JSX.Element => {
-  const { diseaseName, diseaseLink } = useDisease();
-  const { organismName, organismLink } = useOrganism();
+  const diseaseName = useAppSelector(diseaseNameSelector);
+  const diseaseLink = useAppSelector(diseaseLinkSelector);
+  const organismLink = useAppSelector(organismLinkSelector);
+  const organismName = useAppSelector(organismNameSelector);
   const projectName = useAppSelector(projectNameSelector);
   const version = useAppSelector(versionSelector);
   const description = useAppSelector(mainMapModelDescriptionSelector);
@@ -68,6 +75,7 @@ export const ProjectInfoDrawer = (): JSX.Element => {
         </LinkButton>
         {description && (
           <div
+            data-testid="project-description"
             className="anchor-tag mt-7 rounded-lg bg-cultured px-4 py-2"
             // eslint-disable-next-line react/no-danger
             dangerouslySetInnerHTML={{ __html: description }}
diff --git a/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useDisease.ts b/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useDisease.ts
deleted file mode 100644
index 9c99905c..00000000
--- a/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useDisease.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useEffect, useState } from 'react';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { diseaseIdSelector, diseaseLinkSelector } from '@/redux/project/project.selectors';
-import { Mesh } from '@/types/models';
-import { apiPath } from '@/redux/apiPath';
-import { axiosInstance } from '@/services/api/utils/axiosInstance';
-
-type UseDiseaseReturnType = {
-  diseaseName: string;
-  diseaseLink?: string;
-};
-
-export const useDisease = (): UseDiseaseReturnType => {
-  const [diseaseName, setDiseaseName] = useState<string>('');
-  const diseaseId = useAppSelector(diseaseIdSelector);
-  const diseaseLink = useAppSelector(diseaseLinkSelector);
-
-  useEffect(() => {
-    const getDiseaseName = async (id: string): Promise<void> => {
-      try {
-        const mesh = await axiosInstance.get<Mesh>(apiPath.getMesh(id));
-        setDiseaseName(mesh.data.name);
-      } catch (error) {
-        /* empty */
-      }
-    };
-
-    if (diseaseId) {
-      getDiseaseName(diseaseId);
-    }
-  }, [diseaseId]);
-
-  return {
-    diseaseName,
-    diseaseLink,
-  };
-};
diff --git a/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useOrganism.ts b/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useOrganism.ts
deleted file mode 100644
index bff0276e..00000000
--- a/src/components/Map/Drawer/ProjectInfoDrawer/hooks/useOrganism.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { apiPath } from '@/redux/apiPath';
-import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { organismIdSelector, organismLinkSelector } from '@/redux/project/project.selectors';
-import { axiosInstance } from '@/services/api/utils/axiosInstance';
-import { Taxonomy } from '@/types/models';
-import { useState, useEffect } from 'react';
-
-type UseOrganismReturnType = {
-  organismName: string;
-  organismLink?: string;
-};
-
-export const useOrganism = (): UseOrganismReturnType => {
-  const [organismName, setOrganismName] = useState<string>('');
-  const organismId = useAppSelector(organismIdSelector);
-  const organismLink = useAppSelector(organismLinkSelector);
-
-  useEffect(() => {
-    const getOrganismName = async (id: string): Promise<void> => {
-      try {
-        const taxonomy = await axiosInstance.get<Taxonomy>(apiPath.getTaxonomy(id));
-        setOrganismName(taxonomy.data.name);
-      } catch (error) {
-        /* empty */
-      }
-    };
-
-    if (organismId) {
-      getOrganismName(organismId);
-    }
-  }, [organismId]);
-
-  return {
-    organismName,
-    organismLink,
-  };
-};
diff --git a/src/models/fixtures/meshFixture.ts b/src/models/fixtures/meshFixture.ts
deleted file mode 100644
index 753cc1bb..00000000
--- a/src/models/fixtures/meshFixture.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { ZOD_SEED } from '@/constants';
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { createFixture } from 'zod-fixture';
-import { meshSchema } from '../meshSchema';
-
-export const meshFixture = createFixture(meshSchema, {
-  seed: ZOD_SEED,
-});
diff --git a/src/models/fixtures/projectFixture.ts b/src/models/fixtures/projectFixture.ts
index 99e01bb3..06868af6 100644
--- a/src/models/fixtures/projectFixture.ts
+++ b/src/models/fixtures/projectFixture.ts
@@ -1,7 +1,7 @@
 import { ZOD_SEED } from '@/constants';
 // eslint-disable-next-line import/no-extraneous-dependencies
 import { createFixture } from 'zod-fixture';
-import { projectSchema } from '../project';
+import { projectSchema } from '../projectSchema';
 
 export const projectFixture = createFixture(projectSchema, {
   seed: ZOD_SEED,
diff --git a/src/models/fixtures/taxonomyFixture.ts b/src/models/fixtures/taxonomyFixture.ts
deleted file mode 100644
index 99b5db53..00000000
--- a/src/models/fixtures/taxonomyFixture.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { ZOD_SEED } from '@/constants';
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { createFixture } from 'zod-fixture';
-import { taxonomySchema } from '../taxonomySchema';
-
-export const taxonomyFixture = createFixture(taxonomySchema, {
-  seed: ZOD_SEED,
-});
diff --git a/src/models/meshSchema.ts b/src/models/meshSchema.ts
deleted file mode 100644
index c78ff933..00000000
--- a/src/models/meshSchema.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { z } from 'zod';
-
-export const meshSchema = z.object({
-  id: z.string(),
-  name: z.string(),
-  decription: z.string(),
-  synonyms: z.array(z.string()),
-});
diff --git a/src/models/project.ts b/src/models/projectSchema.ts
similarity index 85%
rename from src/models/project.ts
rename to src/models/projectSchema.ts
index 844fe680..517d7b0c 100644
--- a/src/models/project.ts
+++ b/src/models/projectSchema.ts
@@ -6,8 +6,9 @@ import { overviewImageView } from './overviewImageView';
 export const projectSchema = z.object({
   version: z.string(),
   disease,
+  diseaseName: z.string(),
   organism,
-  idObject: z.number(),
+  organismName: z.string(),
   status: z.string(),
   directory: z.string(),
   progress: z.number(),
@@ -15,7 +16,9 @@ export const projectSchema = z.object({
   logEntries: z.boolean(),
   name: z.string(),
   sharedInMinervaNet: z.boolean(),
-  owner: z.string(),
+  owner: z.object({
+    login: z.string(),
+  }),
   projectId: z.string(),
   creationDate: z.string(),
   mapCanvasType: z.string(),
diff --git a/src/models/taxonomySchema.ts b/src/models/taxonomySchema.ts
deleted file mode 100644
index cfc3d9e2..00000000
--- a/src/models/taxonomySchema.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { z } from 'zod';
-
-export const taxonomySchema = z.object({
-  id: z.string(),
-  name: z.string(),
-});
diff --git a/src/redux/project/project.reducers.test.ts b/src/redux/project/project.reducers.test.ts
index 28b9ef70..744f7252 100644
--- a/src/redux/project/project.reducers.test.ts
+++ b/src/redux/project/project.reducers.test.ts
@@ -4,14 +4,14 @@ import {
   ToolkitStoreWithSingleSlice,
   createStoreInstanceUsingSliceReducer,
 } from '@/utils/createStoreInstanceUsingSliceReducer';
-import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
+import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
 import { HttpStatusCode } from 'axios';
 import { apiPath } from '../apiPath';
 import projectReducer from './project.slice';
 import { getProjectById } from './project.thunks';
 import { ProjectState } from './project.types';
 
-const mockedAxiosClient = mockNetworkResponse();
+const mockedAxiosClient = mockNetworkNewAPIResponse();
 
 const INITIAL_STATE: ProjectState = {
   data: undefined,
diff --git a/src/redux/project/project.selectors.ts b/src/redux/project/project.selectors.ts
index 198295bf..6ae2769e 100644
--- a/src/redux/project/project.selectors.ts
+++ b/src/redux/project/project.selectors.ts
@@ -42,9 +42,9 @@ export const projectNameSelector = createSelector(
   projectData => projectData?.name,
 );
 
-export const diseaseIdSelector = createSelector(
+export const diseaseNameSelector = createSelector(
   projectDataSelector,
-  projectData => projectData?.disease.resource,
+  projectData => projectData?.diseaseName,
 );
 
 export const diseaseLinkSelector = createSelector(
@@ -52,14 +52,14 @@ export const diseaseLinkSelector = createSelector(
   projectData => projectData?.disease.link,
 );
 
-export const organismIdSelector = createSelector(
+export const organismLinkSelector = createSelector(
   projectDataSelector,
-  projectData => projectData?.organism.resource,
+  projectData => projectData?.organism.link,
 );
 
-export const organismLinkSelector = createSelector(
+export const organismNameSelector = createSelector(
   projectDataSelector,
-  projectData => projectData?.organism.link,
+  projectData => projectData?.organismName,
 );
 
 export const versionSelector = createSelector(projectDataSelector, state => state?.version);
diff --git a/src/redux/project/project.thunks.ts b/src/redux/project/project.thunks.ts
index f3d9fbe2..649f867d 100644
--- a/src/redux/project/project.thunks.ts
+++ b/src/redux/project/project.thunks.ts
@@ -1,5 +1,5 @@
-import { projectSchema } from '@/models/project';
-import { axiosInstance } from '@/services/api/utils/axiosInstance';
+import { projectSchema } from '@/models/projectSchema';
+import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance';
 import { Project } from '@/types/models';
 import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
 import { createAsyncThunk } from '@reduxjs/toolkit';
@@ -8,7 +8,7 @@ import { apiPath } from '../apiPath';
 export const getProjectById = createAsyncThunk(
   'project/getProjectById',
   async (id: string): Promise<Project | undefined> => {
-    const response = await axiosInstance.get<Project>(apiPath.getProjectById(id));
+    const response = await axiosInstanceNewAPI.get<Project>(apiPath.getProjectById(id));
 
     const isDataValid = validateDataUsingZodSchema(response.data, projectSchema);
 
diff --git a/src/types/models.ts b/src/types/models.ts
index db056dc4..8ad656d4 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -20,7 +20,6 @@ import {
   mapOverlay,
   uploadedOverlayFileContentSchema,
 } from '@/models/mapOverlay';
-import { meshSchema } from '@/models/meshSchema';
 import { mapModelSchema } from '@/models/modelSchema';
 import { organism } from '@/models/organism';
 import { overlayBioEntitySchema } from '@/models/overlayBioEntitySchema';
@@ -30,14 +29,13 @@ import {
   overviewImageLinkModel,
 } from '@/models/overviewImageLink';
 import { overviewImageView } from '@/models/overviewImageView';
-import { projectSchema } from '@/models/project';
+import { projectSchema } from '@/models/projectSchema';
 import { reactionSchema } from '@/models/reaction';
 import { reactionLineSchema } from '@/models/reactionLineSchema';
 import { referenceSchema } from '@/models/referenceSchema';
 import { sessionSchemaValid } from '@/models/sessionValidSchema';
 import { statisticsSchema } from '@/models/statisticsSchema';
 import { targetSchema } from '@/models/targetSchema';
-import { taxonomySchema } from '@/models/taxonomySchema';
 import { z } from 'zod';
 
 export type Project = z.infer<typeof projectSchema>;
@@ -74,5 +72,3 @@ export type Color = z.infer<typeof colorSchema>;
 export type Statistics = z.infer<typeof statisticsSchema>;
 export type CompartmentPathway = z.infer<typeof compartmentPathwaySchema>;
 export type CompartmentPathwayDetails = z.infer<typeof compartmentPathwayDetailsSchema>;
-export type Mesh = z.infer<typeof meshSchema>;
-export type Taxonomy = z.infer<typeof taxonomySchema>;
diff --git a/src/utils/initialize/useInitializeStore.test.ts b/src/utils/initialize/useInitializeStore.test.ts
index d1b7da08..1a99f715 100644
--- a/src/utils/initialize/useInitializeStore.test.ts
+++ b/src/utils/initialize/useInitializeStore.test.ts
@@ -9,13 +9,14 @@ import { modelsDataSelector } from '@/redux/models/models.selectors';
 import { overlaysDataSelector } from '@/redux/overlays/overlays.selectors';
 import { projectDataSelector } from '@/redux/project/project.selectors';
 import { initDataLoadingInitialized } from '@/redux/root/init.selectors';
-import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
+import { mockNetworkNewAPIResponse, mockNetworkResponse } from '@/utils/mockNetworkResponse';
 import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
 import { renderHook, waitFor } from '@testing-library/react';
 import { HttpStatusCode } from 'axios';
 import * as hook from './useInitializeStore';
 
 const mockedAxiosClient = mockNetworkResponse();
+const mockedAxiosNEWApiClient = mockNetworkNewAPIResponse();
 
 describe('useInitializeStore - hook', () => {
   describe('when fired', () => {
@@ -24,7 +25,7 @@ describe('useInitializeStore - hook', () => {
       mockedAxiosClient
         .onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true }))
         .reply(HttpStatusCode.Ok, overlaysFixture);
-      mockedAxiosClient
+      mockedAxiosNEWApiClient
         .onGet(apiPath.getProjectById(PROJECT_ID))
         .reply(HttpStatusCode.Ok, projectFixture);
       mockedAxiosClient
-- 
GitLab