From ea201d4361b41af88ae8540423bb826a268032dd Mon Sep 17 00:00:00 2001 From: Christina Jenks <christina.jenks@ess.eu> Date: Wed, 13 Sep 2023 11:29:50 +0000 Subject: [PATCH] CE-2065: replace useIoc hook with common --- src/__tests__/backend-mock-setup.test.js | 34 ------------------- src/api/SwaggerApi.js | 7 ---- .../IOC/AlertMessages/AlertMessages.js | 2 +- .../IOC/IOCLiveStatus/IOCLiveStatus.spec.js | 19 +++++++++-- src/components/IOC/IOCTable/IOCDescription.js | 26 +++++++++++--- .../views/IOC/IocDetailsView.stories.js | 15 ++++++++ src/views/IOC/IOCDetailsContainer.js | 31 ++++++++++++++--- 7 files changed, 80 insertions(+), 54 deletions(-) delete mode 100644 src/__tests__/backend-mock-setup.test.js create mode 100644 src/stories/views/IOC/IocDetailsView.stories.js diff --git a/src/__tests__/backend-mock-setup.test.js b/src/__tests__/backend-mock-setup.test.js deleted file mode 100644 index 9b3d8d3c..00000000 --- a/src/__tests__/backend-mock-setup.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { act, render, screen } from "@testing-library/react"; -import { SnackbarProvider } from "notistack"; -import { APIProvider, useIOCList } from "../api/SwaggerApi"; - -function APIHarness({ children }) { - // We need a snackbar provider at the moment - return ( - <SnackbarProvider> - <APIProvider>{children}</APIProvider> - </SnackbarProvider> - ); -} - -// This component will just try to use a hook from our API -// We want to check that we can get a response from the mock backend -function DisplayIOCs() { - const [iocs] = useIOCList(); - return JSON.stringify(iocs); -} - -test("that using OpenAPIBackend and MSW works with Swagger-Client and our API hooks", async () => { - // render and wait for the state changes - await act(async () => { - render( - <APIHarness> - <DisplayIOCs /> - </APIHarness> - ); - }); - - // check that we got the example IOCList from the OpenAPI spec back - expect(await screen.findByText(/activeDeployment/i)).toBeInTheDocument(); -}); diff --git a/src/api/SwaggerApi.js b/src/api/SwaggerApi.js index 91e1b6b3..6f5457f4 100644 --- a/src/api/SwaggerApi.js +++ b/src/api/SwaggerApi.js @@ -240,13 +240,6 @@ export function useIOCSearch() { return useAsync({ fcn: method, call: false, init: emptyIocListResponse }); } -export function useIOC(id, onError) { - const api = useContext(apiContext); - const method = useCallAndUnpack(api.apis.IOCs.getIoc, unpackIOC); - const boundMethod = useCallback(method.bind(null, { ioc_id: id }), [id]); - return useAsync({ fcn: boundMethod, onError: onError }); -} - export function useCreateIOC(onError) { const api = useContext(apiContext); const method = useCallAndUnpack( diff --git a/src/components/IOC/AlertMessages/AlertMessages.js b/src/components/IOC/AlertMessages/AlertMessages.js index 9496d633..e06128b2 100644 --- a/src/components/IOC/AlertMessages/AlertMessages.js +++ b/src/components/IOC/AlertMessages/AlertMessages.js @@ -35,7 +35,7 @@ export default function AlertMessages({ alerts }) { spacing={1} direction="column" > - {alerts.map((alert) => ( + {alerts?.map((alert) => ( <Grid item key={alert?.message || alert} diff --git a/src/components/IOC/IOCLiveStatus/IOCLiveStatus.spec.js b/src/components/IOC/IOCLiveStatus/IOCLiveStatus.spec.js index bf6fce40..07d67abf 100644 --- a/src/components/IOC/IOCLiveStatus/IOCLiveStatus.spec.js +++ b/src/components/IOC/IOCLiveStatus/IOCLiveStatus.spec.js @@ -1,14 +1,27 @@ -import React from "react"; -import { useIOC } from "../../../api/SwaggerApi"; +import React, { useContext, useMemo } from "react"; import { AppHarness } from "../../../mocks/AppHarness"; import { IOCLiveStatus } from "."; +import { apiContext } from "../../../api/DeployApi"; +import { useAPIMethod } from "@ess-ics/ce-ui-common/dist/hooks/API"; function mountIntoHarness(children) { cy.mount(<AppHarness>{children}</AppHarness>); } function IOCLiveStatusContainer() { - const [ioc] = useIOC(2); + const client = useContext(apiContext); + + const params = useMemo( + () => ({ + ioc_id: 2 + }), + [] + ); + + const { value: ioc } = useAPIMethod({ + fcn: client.apis.IOCs.getIoc, + params + }); return ioc ? <IOCLiveStatus ioc={ioc} /> : null; } diff --git a/src/components/IOC/IOCTable/IOCDescription.js b/src/components/IOC/IOCTable/IOCDescription.js index 980dd0dc..6db104ff 100644 --- a/src/components/IOC/IOCTable/IOCDescription.js +++ b/src/components/IOC/IOCTable/IOCDescription.js @@ -1,6 +1,7 @@ -import React from "react"; -import { useIOC } from "../../../api/SwaggerApi"; +import React, { useContext, useMemo } from "react"; +import { apiContext } from "../../../api/SwaggerApi"; import { Skeleton, Tooltip, Typography } from "@mui/material"; +import { useAPIMethod } from "@ess-ics/ce-ui-common"; function createIocDescription(description) { return ( @@ -29,10 +30,27 @@ function createIocDescription(description) { } export const IOCDescription = ({ id }) => { - const [ioc, , , loading] = useIOC(id); + const client = useContext(apiContext); - if (loading) { + const params = useMemo( + () => ({ + ioc_id: id + }), + [id] + ); + + const { + value: ioc, + loading, + dataReady + } = useAPIMethod({ + fcn: client.apis.IOCs.getIoc, + params + }); + + if (loading || !dataReady) { return <Skeleton width="100%" />; } + return createIocDescription(ioc?.description); }; diff --git a/src/stories/views/IOC/IocDetailsView.stories.js b/src/stories/views/IOC/IocDetailsView.stories.js new file mode 100644 index 00000000..ea0221de --- /dev/null +++ b/src/stories/views/IOC/IocDetailsView.stories.js @@ -0,0 +1,15 @@ +import React from "react"; +import { AppHarness } from "../../../mocks/AppHarness"; +import { IOCDetailsContainer } from "../../../views/IOC/IOCDetailsContainer"; + +export default { + title: "Views/IOC/IOCDetailsView" +}; + +const Template = () => ( + <AppHarness> + <IOCDetailsContainer id={346} /> + </AppHarness> +); + +export const Default = () => <Template />; diff --git a/src/views/IOC/IOCDetailsContainer.js b/src/views/IOC/IOCDetailsContainer.js index ab907931..00aee004 100644 --- a/src/views/IOC/IOCDetailsContainer.js +++ b/src/views/IOC/IOCDetailsContainer.js @@ -1,22 +1,43 @@ -import React, { useEffect, useContext, useState } from "react"; +import React, { useEffect, useContext, useState, useMemo } from "react"; import { IOCDetailsView } from "./IOCDetailsView"; import { LinearProgress } from "@mui/material"; import NotFoundView from "../../components/navigation/NotFoundView/NotFoundView"; import { onFetchEntityError } from "../../components/common/Helper"; -import { useIOC } from "../../api/SwaggerApi"; import { userContext } from "@ess-ics/ce-ui-common/dist/contexts/User"; import useUrlState from "@ahooksjs/use-url-state"; +import { apiContext } from "../../api/DeployApi"; +import { useAPIMethod } from "@ess-ics/ce-ui-common"; export function IOCDetailsContainer({ id }) { const { user } = useContext(userContext); const [urlState] = useUrlState(); const [error, setError] = useState(null); - const [ioc, getIOC /* reset*/, , loading] = useIOC(id, (m, s) => { - // handle error code 404, and define custom message on the UI because BE sends back generic error message - onFetchEntityError(m, s, setError); + const client = useContext(apiContext); + + const params = useMemo( + () => ({ + ioc_id: id + }), + [id] + ); + + const { + value: ioc, + wrapper: getIOC, + loading, + error: fetchError + } = useAPIMethod({ + fcn: client.apis.IOCs.getIoc, + params }); + useEffect(() => { + if (fetchError) { + onFetchEntityError(fetchError?.message, fetchError?.status, setError); + } + }, [fetchError]); + useEffect(() => { // user logs in => clear error message, and try to re-request userInfo if (user) { -- GitLab