From 0d04660a486dcc49be0dae739a0fb37f57a88eb8 Mon Sep 17 00:00:00 2001 From: Tiffany Forkner Date: Tue, 21 Jan 2025 17:15:11 -0500 Subject: [PATCH] added tests for Chipbar --- mocks/handlers/api/user.ts | 1 + mocks/handlers/auth.utils.ts | 1 + react-app/src/api/useGetUser.ts | 1 + .../main/Filtering/Chipbar/index.test.tsx | 347 ++++++++++++++++++ .../main/Filtering/Chipbar/index.tsx | 7 +- .../Opensearch/main/Provider/index.tsx | 2 +- .../features/dashboard/Lists/spas/consts.tsx | 1 + 7 files changed, 356 insertions(+), 4 deletions(-) create mode 100644 react-app/src/components/Opensearch/main/Filtering/Chipbar/index.test.tsx diff --git a/mocks/handlers/api/user.ts b/mocks/handlers/api/user.ts index 48c07897fe..4ab4e98928 100644 --- a/mocks/handlers/api/user.ts +++ b/mocks/handlers/api/user.ts @@ -5,6 +5,7 @@ import type { TestUserData } from "../.."; // using `any` type here because the function that this is mocking uses any export const mockCurrentAuthenticatedUser = (): TestUserData | any => { + console.log("username", process.env.MOCK_USER_USERNAME); if (process.env.MOCK_USER_USERNAME) { return findUserByUsername(process.env.MOCK_USER_USERNAME); } diff --git a/mocks/handlers/auth.utils.ts b/mocks/handlers/auth.utils.ts index 419d2cbf0f..e27d62dc8f 100644 --- a/mocks/handlers/auth.utils.ts +++ b/mocks/handlers/auth.utils.ts @@ -3,6 +3,7 @@ import type { TestUserData } from "../index.d"; import { CognitoUserAttributes } from "shared-types"; export const setMockUsername = (user?: TestUserData | string | null): void => { + console.log({ user }); if (user && typeof user === "string") { process.env.MOCK_USER_USERNAME = user; } else if (user && (user as TestUserData).Username !== undefined) { diff --git a/react-app/src/api/useGetUser.ts b/react-app/src/api/useGetUser.ts index bf9e1eb7f1..e617ab5b28 100644 --- a/react-app/src/api/useGetUser.ts +++ b/react-app/src/api/useGetUser.ts @@ -12,6 +12,7 @@ export type OneMacUser = { export const getUser = async (): Promise => { try { const currentAuthenticatedUser = await Auth.currentAuthenticatedUser(); + console.log({ currentAuthenticatedUser }); if (!currentAuthenticatedUser) { return { user: null } satisfies OneMacUser; } diff --git a/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.test.tsx b/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.test.tsx new file mode 100644 index 0000000000..9f5e858082 --- /dev/null +++ b/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.test.tsx @@ -0,0 +1,347 @@ +import { describe, expect, it, vi, afterEach } from "vitest"; +import { screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { ChipBool, ChipDate, ChipTerms } from "./index"; +import { render } from "@testing-library/react"; + +describe("FilterChips", () => { + const openDrawer = vi.fn(); + const clearFilter = vi.fn(); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe("ChipBool", () => { + it.each([ + [true, "Yes"], + ["yes", "Yes"], + [undefined, "No"], + [null, "No"], + ["", "No"], + [false, "No"], + ])("when value is '%s' it should display %s", (value, expected) => { + render( + , + ); + expect(screen.getByText("Test:").textContent).toEqual(`Test: ${expected}`); + }); + + it("should not show a label if no label is provided", () => { + render( + , + ); + expect(screen.getByText("Yes").parentElement.textContent).toEqual("Yes"); + }); + + it("should handle clicking the close icon", async () => { + const user = userEvent.setup(); + render( + , + ); + await user.click(screen.getByRole("button")); + expect(clearFilter).toHaveBeenCalledWith({ + label: "Test", + value: true, + type: "match", + prefix: "must", + field: "authority.keyword", + }); + }); + + it("should handle clicking the chip", async () => { + const user = userEvent.setup(); + const { container } = render( + , + ); + await user.click(container.firstChild as Element); + expect(openDrawer).toHaveBeenCalled(); + }); + }); + + describe("ChipDate", () => { + it.each([ + [{ gte: "2024-01-01", lte: "2024-03-01" }, "1/1/2024 - 3/1/2024"], + [{ gte: "2024-01-01" }, "1/1/2024 - Invalid Date"], + [{ lte: "2024-03-01" }, "Invalid Date - 3/1/2024"], + ])("when value is '%s' it should display %s", (value, expected) => { + render( + , + ); + expect(screen.getByText(`Test: ${expected}`)).toBeInTheDocument(); + }); + + it("should not show a label if no label is provided", () => { + render( + , + ); + expect(screen.getByText("1/1/2024 - 3/1/2024").parentElement.textContent).toEqual( + "1/1/2024 - 3/1/2024", + ); + }); + + it("should handle clicking the close icon", async () => { + const user = userEvent.setup(); + render( + , + ); + await user.click(screen.getByRole("button")); + expect(clearFilter).toHaveBeenCalledWith({ + label: "Test", + value: { gte: "2024-01-01", lte: "2024-03-01" }, + type: "range", + prefix: "must", + field: "authority.keyword", + }); + }); + + it("should handle clicking the chip", async () => { + const user = userEvent.setup(); + const { container } = render( + , + ); + await user.click(container.firstChild as Element); + expect(openDrawer).toHaveBeenCalled(); + }); + }); + + describe("ChipTerms", () => { + it.each([ + [ + "multiple terms with labels", + "Test", + ["New", "MD"], + ["Test: Initial", "Test: Maryland, MD"], + ], + ["multiple terms without labels", undefined, ["New", "MD"], ["Initial", "Maryland, MD"]], + ["single term with labels", "Test", ["New"], ["Test: Initial"]], + ["single term without labels", undefined, ["MD"], ["Maryland, MD"]], + ])("should display %s", (_, label, value, expected) => { + render( + , + ); + + expected.forEach((val) => { + expect(screen.getByText(val)).toBeInTheDocument(); + }); + }); + + it("should return null if the value is not an array", () => { + const { container } = render( + , + ); + expect(container.firstChild).toBeNull(); + }); + + it("should return null if the value is an empty array", () => { + const { container } = render( + , + ); + expect(container.firstChild).toBeNull(); + }); + + it("should handle clicking the close icon", async () => { + const user = userEvent.setup(); + render( + , + ); + await user.click(screen.getByRole("button")); + expect(clearFilter).toHaveBeenCalledWith( + { + value: ["New"], + type: "terms", + prefix: "must", + field: "authority.keyword", + }, + 0, + ); + }); + + it("should handle clicking the close icon on the second chip", async () => { + const user = userEvent.setup(); + render( + , + ); + await user.click(screen.getAllByRole("button")[1]); + expect(clearFilter).toHaveBeenCalledWith( + { + value: ["New", "MD"], + type: "terms", + prefix: "must", + field: "authority.keyword", + }, + 1, + ); + }); + + it("should handle clicking the chip", async () => { + const user = userEvent.setup(); + const { container } = render( + , + ); + await user.click(container.firstChild as Element); + expect(openDrawer).toHaveBeenCalled(); + }); + }); +}); diff --git a/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.tsx b/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.tsx index ba0fe30fc5..b89a82e03b 100644 --- a/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.tsx +++ b/react-app/src/components/Opensearch/main/Filtering/Chipbar/index.tsx @@ -14,7 +14,7 @@ export interface RenderProp { } export const ChipBool: FC = ({ filter, openDrawer, clearFilter }) => { - const value = filter.value as opensearch.RangeValue; + const value = filter.value as opensearch.FilterValue; return ( = ({ filter, openDrawer, clearFilter }) => clearFilter(filter); }} > - {filter?.label}: {value ? "Yes" : "No"} + {filter?.label ? `${filter.label}: ` : ""} + {value ? "Yes" : "No"} ); }; @@ -36,7 +37,7 @@ export const ChipDate: FC = ({ filter, openDrawer, clearFilter }) => clearFilter(filter); }} > - {`${filter?.label}: ${offsetFromUtc( + {`${filter?.label ? `${filter.label}: ` : ""}${offsetFromUtc( new Date(value.gte || ""), ).toLocaleDateString()} - ${offsetFromUtc(new Date(value.lte || "")).toLocaleDateString()}`} diff --git a/react-app/src/components/Opensearch/main/Provider/index.tsx b/react-app/src/components/Opensearch/main/Provider/index.tsx index cebb49b4a0..d500a31771 100644 --- a/react-app/src/components/Opensearch/main/Provider/index.tsx +++ b/react-app/src/components/Opensearch/main/Provider/index.tsx @@ -2,7 +2,7 @@ import { ReactNode } from "react"; import { createContextProvider } from "@/utils"; import { ReactQueryApiError, opensearch } from "shared-types"; -type ContextState = { +export type ContextState = { data: opensearch.main.Response["hits"] | undefined; isLoading: boolean; error: ReactQueryApiError | null; diff --git a/react-app/src/features/dashboard/Lists/spas/consts.tsx b/react-app/src/features/dashboard/Lists/spas/consts.tsx index 7061542575..9aa7108f60 100644 --- a/react-app/src/features/dashboard/Lists/spas/consts.tsx +++ b/react-app/src/features/dashboard/Lists/spas/consts.tsx @@ -8,6 +8,7 @@ import { CellDetailsLink, renderCellActions, renderCellDate } from "../renderCel export const useSpaTableColumns = (): OsTableColumn[] => { const { data: props } = useGetUser(); + console.log({ props }); if (!props?.user) return [];