From 6876194e3feb66ae1d1d9e46e94a5f4c37888114 Mon Sep 17 00:00:00 2001 From: bbehnke Date: Thu, 26 Oct 2023 13:29:06 -0700 Subject: [PATCH] fix: ISBCreate test and fetch mock setup Signed-off-by: bbehnke --- ui/package.json | 4 +- .../partials/ISBCreate/index.test.tsx | 216 ++++++++++++++++++ ui/src/setupTests.ts | 7 +- ui/yarn.lock | 15 +- 4 files changed, 236 insertions(+), 6 deletions(-) create mode 100644 ui/src/components/common/SlidingSidebar/partials/ISBCreate/index.test.tsx diff --git a/ui/package.json b/ui/package.json index 049acdde07..5f3fc7894c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -72,6 +72,7 @@ "eslint": "^7.19.0", "eslint-config-prettier": "7.2.0", "eslint-plugin-prettier": "3.3.1", + "jest-fetch-mock": "^3.0.3", "jest-junit": "^12.0.0", "prettier": "2.5.1", "react-scripts": "5.0.1" @@ -82,6 +83,7 @@ "jest": { "transformIgnorePatterns": [ "/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates|reactflow|react-toastify|moment)" - ] + ], + "resetMocks": false } } diff --git a/ui/src/components/common/SlidingSidebar/partials/ISBCreate/index.test.tsx b/ui/src/components/common/SlidingSidebar/partials/ISBCreate/index.test.tsx new file mode 100644 index 0000000000..283f077f05 --- /dev/null +++ b/ui/src/components/common/SlidingSidebar/partials/ISBCreate/index.test.tsx @@ -0,0 +1,216 @@ +import React from "react"; +import { + fireEvent, + render, + screen, + waitFor, + act, +} from "@testing-library/react"; +import { ISBCreate } from "./index"; +import fetch from "jest-fetch-mock"; + +import "@testing-library/jest-dom"; + +// Mock SpecEditor +jest.mock("../../../SpecEditor", () => { + const originalModule = jest.requireActual("../../../SpecEditor"); + const react = jest.requireActual("react"); + // Mock any module exports here + return { + __esModule: true, + ...originalModule, + // Named export mocks + SpecEditor: (props: any) => { + const [mutated, setMutated] = react.useState(false); + const handleMutateClick = react.useCallback(() => { + props.onMutatedChange(mutated); + setMutated(!mutated); + }, [mutated, props.onMutatedChange]); + return ( +
+
{JSON.stringify(props.validationMessage)}
+
{JSON.stringify(props.statusIndicator)}
+
{props.initialYaml}
+
+ ); + }, + }; +}); + +describe("ISBCreate", () => { + beforeEach(() => { + jest.clearAllMocks(); + fetch.resetMocks(); + }); + + it("renders title and spec editor", async () => { + const mockSetModalOnClose = jest.fn(); + render( + + ); + await waitFor(() => { + expect(screen.getByText("Create ISB Service")).toBeInTheDocument(); + expect(screen.getByTestId("spec-editor-reset")).toBeInTheDocument(); + }); + // Click reset + act(() => { + const resetBtn = screen.getByTestId("spec-editor-reset"); + fireEvent.click(resetBtn); + }); + // Fire mutation change twice to run both branches + act(() => { + const mutationBtn = screen.getByTestId("spec-editor-mutated"); + fireEvent.click(mutationBtn); + }); + expect(mockSetModalOnClose).toHaveBeenCalledWith(undefined); + mockSetModalOnClose.mockClear(); + act(() => { + const mutationBtn = screen.getByTestId("spec-editor-mutated"); + fireEvent.click(mutationBtn); + }); + expect(mockSetModalOnClose).toHaveBeenCalledWith({ + iconType: "warn", + message: "Are you sure you want to discard your changes?", + }); + }); + + it("validation success", async () => { + fetch.mockResponseOnce(JSON.stringify({ data: {} })); + const mockSetModalOnClose = jest.fn(); + render( + + ); + await waitFor(() => { + expect(screen.getByText("Create ISB Service")).toBeInTheDocument(); + expect(screen.getByTestId("spec-editor-reset")).toBeInTheDocument(); + }); + // Click reset + act(() => { + const validateBtn = screen.getByTestId("spec-editor-validate"); + fireEvent.click(validateBtn); + }); + await waitFor(() => { + expect( + screen.getByText( + `{"type":"success","message":"Successfully validated"}` + ) + ).toBeInTheDocument(); + }); + }); + + it("validation failure", async () => { + fetch.mockResponseOnce(JSON.stringify({ errMsg: "failed" })); + const mockSetModalOnClose = jest.fn(); + render( + + ); + await waitFor(() => { + expect(screen.getByText("Create ISB Service")).toBeInTheDocument(); + expect(screen.getByTestId("spec-editor-reset")).toBeInTheDocument(); + }); + // Click reset + act(() => { + const validateBtn = screen.getByTestId("spec-editor-validate"); + fireEvent.click(validateBtn); + }); + await waitFor(() => { + expect( + screen.getByText(`{"type":"error","message":"Error: failed"}`) + ).toBeInTheDocument(); + }); + }); + + it("submit success", async () => { + fetch.mockResponseOnce(JSON.stringify({ data: {} })); + const mockUpdateComplete = jest.fn(); + render( + + ); + await waitFor(() => { + expect(screen.getByText("Create ISB Service")).toBeInTheDocument(); + expect(screen.getByTestId("spec-editor-reset")).toBeInTheDocument(); + }); + // Click reset + act(() => { + const submitBtn = screen.getByTestId("spec-editor-submit"); + fireEvent.click(submitBtn); + }); + await waitFor(() => { + expect( + screen.getByText( + `{"submit":{"status":1,"message":"ISB Service created successfully","allowRetry":false}}` + ) + ).toBeInTheDocument(); + }); + // Wait for onUpdateComplete call + await new Promise((r) => setTimeout(r, 1000)); + expect(mockUpdateComplete).toHaveBeenCalledTimes(1); + }); + + it("submit failure", async () => { + fetch.mockResponseOnce(JSON.stringify({ errMsg: "failed" })); + const mockUpdateComplete = jest.fn(); + render( + + ); + await waitFor(() => { + expect(screen.getByText("Create ISB Service")).toBeInTheDocument(); + expect(screen.getByTestId("spec-editor-reset")).toBeInTheDocument(); + }); + // Click reset + act(() => { + const submitBtn = screen.getByTestId("spec-editor-submit"); + fireEvent.click(submitBtn); + }); + await waitFor(() => { + expect( + screen.getByText(`{"type":"error","message":"Error: failed"}`) + ).toBeInTheDocument(); + }); + }); +}); diff --git a/ui/src/setupTests.ts b/ui/src/setupTests.ts index 8f2609b7b3..43de1120bb 100644 --- a/ui/src/setupTests.ts +++ b/ui/src/setupTests.ts @@ -1,5 +1,4 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom +import { enableFetchMocks } from 'jest-fetch-mock' +enableFetchMocks() import '@testing-library/jest-dom'; + diff --git a/ui/yarn.lock b/ui/yarn.lock index de10f13f29..d23283c320 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -4401,7 +4401,7 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -cross-fetch@^3.1.5: +cross-fetch@^3.0.4, cross-fetch@^3.1.5: version "3.1.8" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== @@ -7156,6 +7156,14 @@ jest-environment-node@^27.5.1: jest-mock "^27.5.1" jest-util "^27.5.1" +jest-fetch-mock@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b" + integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw== + dependencies: + cross-fetch "^3.0.4" + promise-polyfill "^8.1.3" + jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" @@ -9271,6 +9279,11 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-polyfill@^8.1.3: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" + integrity sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg== + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"