From 0f11b62ad540011d1664abac6d22e2b35ce4e46b Mon Sep 17 00:00:00 2001 From: Huw Wilkins Date: Mon, 9 Dec 2024 10:38:24 +1100 Subject: [PATCH] chore(tests): add tests for the provider list --- .../EditPanelButton/EditPanelButton.tsx | 3 +- .../providers/DeleteProviderBtn/index.ts | 1 + .../providers/DeleteProviderBtn/test-types.ts | 3 + .../EditProviderBtn/EditProviderBtn.tsx | 4 + .../pages/providers/EditProviderBtn/index.ts | 1 + .../providers/EditProviderBtn/test-types.ts | 3 + .../ProviderList/ProviderList.test.tsx | 76 +++++++++++++++++++ .../providers/ProviderList/ProviderList.tsx | 14 ++-- ui/src/pages/providers/ProviderList/types.ts | 6 ++ 9 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 ui/src/pages/providers/DeleteProviderBtn/test-types.ts create mode 100644 ui/src/pages/providers/EditProviderBtn/test-types.ts create mode 100644 ui/src/pages/providers/ProviderList/ProviderList.test.tsx create mode 100644 ui/src/pages/providers/ProviderList/types.ts diff --git a/ui/src/components/EditPanelButton/EditPanelButton.tsx b/ui/src/components/EditPanelButton/EditPanelButton.tsx index e2dff0d83..54e462694 100644 --- a/ui/src/components/EditPanelButton/EditPanelButton.tsx +++ b/ui/src/components/EditPanelButton/EditPanelButton.tsx @@ -5,7 +5,7 @@ import usePanelParams from "util/usePanelParams"; import { Label, Props } from "./types"; -const EditPanelButton: FC = ({ openPanel }: Props) => { +const EditPanelButton: FC = ({ openPanel, ...props }: Props) => { const panelParams = usePanelParams(); return ( @@ -13,6 +13,7 @@ const EditPanelButton: FC = ({ openPanel }: Props) => { className="u-no-margin--bottom" hasIcon onClick={() => openPanel(panelParams)} + {...props} > {Label.EDIT} diff --git a/ui/src/pages/providers/DeleteProviderBtn/index.ts b/ui/src/pages/providers/DeleteProviderBtn/index.ts index 576ed9214..3a86fffae 100644 --- a/ui/src/pages/providers/DeleteProviderBtn/index.ts +++ b/ui/src/pages/providers/DeleteProviderBtn/index.ts @@ -1 +1,2 @@ export { default } from "./DeleteProviderBtn"; +export { TestId as DeleteProviderBtnTestId } from "./test-types"; diff --git a/ui/src/pages/providers/DeleteProviderBtn/test-types.ts b/ui/src/pages/providers/DeleteProviderBtn/test-types.ts new file mode 100644 index 000000000..6eb9b09ea --- /dev/null +++ b/ui/src/pages/providers/DeleteProviderBtn/test-types.ts @@ -0,0 +1,3 @@ +export enum TestId { + COMPONENT = "DeleteProviderBtn", +} diff --git a/ui/src/pages/providers/EditProviderBtn/EditProviderBtn.tsx b/ui/src/pages/providers/EditProviderBtn/EditProviderBtn.tsx index 804f58ab9..613711a5f 100644 --- a/ui/src/pages/providers/EditProviderBtn/EditProviderBtn.tsx +++ b/ui/src/pages/providers/EditProviderBtn/EditProviderBtn.tsx @@ -1,6 +1,9 @@ import { FC } from "react"; import EditPanelButton from "components/EditPanelButton"; +import { testId } from "test/utils"; + +import { TestId } from "./test-types"; interface Props { providerId: string; @@ -10,6 +13,7 @@ const EditProviderBtn: FC = ({ providerId }) => { return ( panelParams.openProviderEdit(providerId)} + {...testId(TestId.COMPONENT)} /> ); }; diff --git a/ui/src/pages/providers/EditProviderBtn/index.ts b/ui/src/pages/providers/EditProviderBtn/index.ts index d51da9c1c..eb0451ef2 100644 --- a/ui/src/pages/providers/EditProviderBtn/index.ts +++ b/ui/src/pages/providers/EditProviderBtn/index.ts @@ -1 +1,2 @@ export { default } from "./EditProviderBtn"; +export { TestId as EditProviderBtnTestId } from "./test-types"; diff --git a/ui/src/pages/providers/EditProviderBtn/test-types.ts b/ui/src/pages/providers/EditProviderBtn/test-types.ts new file mode 100644 index 000000000..84e580841 --- /dev/null +++ b/ui/src/pages/providers/EditProviderBtn/test-types.ts @@ -0,0 +1,3 @@ +export enum TestId { + COMPONENT = "EditProviderBtn", +} diff --git a/ui/src/pages/providers/ProviderList/ProviderList.test.tsx b/ui/src/pages/providers/ProviderList/ProviderList.test.tsx new file mode 100644 index 000000000..e5fff8d09 --- /dev/null +++ b/ui/src/pages/providers/ProviderList/ProviderList.test.tsx @@ -0,0 +1,76 @@ +import { screen } from "@testing-library/dom"; +import MockAdapter from "axios-mock-adapter"; +import userEvent from "@testing-library/user-event"; +import { faker } from "@faker-js/faker"; + +import { axiosInstance } from "api/axios"; +import { customWithin } from "test/queries/within"; +import { mockIdentityProvider } from "test/mocks/providers"; +import { mockPaginatedResponse } from "test/mocks/responses"; +import { renderComponent } from "test/utils"; + +import { DeleteProviderBtnTestId } from "../DeleteProviderBtn"; +import { EditProviderBtnTestId } from "../EditProviderBtn"; + +import { Label } from "./types"; +import ProviderList from "./ProviderList"; +import { Location } from "react-router-dom"; +import { panels } from "util/usePanelParams"; + +const mock = new MockAdapter(axiosInstance); + +beforeEach(() => { + mock.reset(); + mock.onGet("/idps").reply(200, mockPaginatedResponse([], { _meta: {} })); +}); + +test("displays provider rows", async () => { + const provider = { + id: faker.word.sample(), + provider: faker.word.sample(), + }; + const providers = [mockIdentityProvider(provider)]; + mock + .onGet("/idps") + .reply(200, mockPaginatedResponse(providers, { _meta: {} })); + renderComponent(); + const row = await screen.findByRole("row", { + name: new RegExp(provider.id), + }); + expect( + customWithin(row).getCellByHeader(Label.HEADER_NAME, { role: "rowheader" }), + ).toHaveTextContent(provider.id); + expect( + customWithin(row).getCellByHeader(Label.HEADER_PROVIDER, { + role: "gridcell", + hasRowHeader: true, + }), + ).toHaveTextContent(provider.provider); +}); + +test("opens add provider panel", async () => { + let location: Location | null = null; + renderComponent(, { + setLocation: (newLocation) => { + location = newLocation; + }, + }); + await userEvent.click(screen.getByRole("button", { name: Label.ADD })); + expect((location as Location | null)?.search).toBe( + `?panel=${panels.providerCreate}`, + ); +}); + +test("displays edit and delete buttons", async () => { + const providers = [mockIdentityProvider()]; + mock + .onGet("/idps") + .reply(200, mockPaginatedResponse(providers, { _meta: {} })); + renderComponent(); + expect( + await screen.findByTestId(EditProviderBtnTestId.COMPONENT), + ).toBeInTheDocument(); + expect( + await screen.findByTestId(DeleteProviderBtnTestId.COMPONENT), + ).toBeInTheDocument(); +}); diff --git a/ui/src/pages/providers/ProviderList/ProviderList.tsx b/ui/src/pages/providers/ProviderList/ProviderList.tsx index 1fc53293f..74ad8d3f0 100644 --- a/ui/src/pages/providers/ProviderList/ProviderList.tsx +++ b/ui/src/pages/providers/ProviderList/ProviderList.tsx @@ -12,6 +12,7 @@ import { fetchProviders } from "api/provider"; import usePanelParams from "util/usePanelParams"; import EditProviderBtn from "pages/providers/EditProviderBtn"; import DeleteProviderBtn from "pages/providers/DeleteProviderBtn"; +import { Label } from "./types"; const ProviderList: FC = () => { const panelParams = usePanelParams(); @@ -34,7 +35,7 @@ const ProviderList: FC = () => { appearance="positive" onClick={panelParams.openProviderCreate} > - Add ID provider + {Label.ADD} @@ -47,9 +48,9 @@ const ProviderList: FC = () => { sortable responsive headers={[ - { content: "Name", sortKey: "id" }, - { content: "Provider", sortKey: "provider" }, - { content: "Actions" }, + { content: Label.HEADER_NAME, sortKey: "id" }, + { content: Label.HEADER_PROVIDER, sortKey: "provider" }, + { content: Label.HEADER_ACTIONS }, ]} rows={providers?.data.map((provider) => { return { @@ -57,12 +58,9 @@ const ProviderList: FC = () => { { content: provider.id, role: "rowheader", - "aria-label": "Name", }, { content: provider.provider, - role: "rowheader", - "aria-label": "Provider", }, { content: ( @@ -71,8 +69,6 @@ const ProviderList: FC = () => { ), - role: "rowheader", - "aria-label": "Actions", }, ], sortData: { diff --git a/ui/src/pages/providers/ProviderList/types.ts b/ui/src/pages/providers/ProviderList/types.ts new file mode 100644 index 000000000..9090676c6 --- /dev/null +++ b/ui/src/pages/providers/ProviderList/types.ts @@ -0,0 +1,6 @@ +export enum Label { + ADD = "Add ID provider", + HEADER_ACTIONS = "Actions", + HEADER_NAME = "Name", + HEADER_PROVIDER = "Provider", +}