From b0ab29095e4e7db9e2662333e229c9e304714b75 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Mon, 6 Feb 2023 10:34:31 +0300 Subject: [PATCH] Clean up tests from boilderplate Signed-off-by: Alex Andreev --- .../namespace-tree-view.test.tsx.snap | 114 +++++----- .../hierarchical-namespaces.injectable.ts | 14 ++ .../+namespaces/namespace-tree-view.test.tsx | 195 ++++++------------ .../+namespaces/namespace-tree-view.tsx | 14 +- 4 files changed, 145 insertions(+), 192 deletions(-) create mode 100644 packages/core/src/renderer/components/+namespaces/hierarchical-namespaces.injectable.ts diff --git a/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap b/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap index abc6a75809..7a35090817 100644 --- a/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap +++ b/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` once the subscribe resolves collapses item by clicking minus button 1`] = ` +exports[` collapses item by clicking minus button 1`] = `
once the subscribe resolves collapses item by cli `; -exports[` once the subscribe resolves expands item by clicking plus button 1`] = ` +exports[` expands item by clicking plus button 1`] = `
once the subscribe resolves expands item by click `; -exports[` once the subscribe resolves renders 2 levels deep 1`] = ` +exports[` renders 2 levels deep 1`] = `
once the subscribe resolves renders 2 levels deep `; -exports[` once the subscribe resolves renders namespace with 2 children namespaces 1`] = ` +exports[` renders namespace with 2 children namespaces 1`] = `
once the subscribe resolves renders namespace wit `; -exports[` once the subscribe resolves renders namespace with children namespaces and a subnamespace 1`] = ` +exports[` renders namespace with children namespaces and a subnamespace 1`] = `
once the subscribe resolves renders namespace wit
+
  • +
    +
    +
    + +
    +
    +
    + team-c + +
    +
    +
      +
      +
      +
      +
    +
  • once the subscribe resolves renders namespace wit
  • -
  • -
    -
    -
    - -
    -
    -
    - team-c - -
    -
    -
      -
      -
      -
      -
    -
  • @@ -1001,13 +1001,13 @@ exports[` once the subscribe resolves renders namespace wit `; -exports[` once the subscribe resolves renders null with regular namespace 1`] = ` +exports[` renders null with regular namespace 1`] = `
    `; -exports[` once the subscribe resolves renders one namespace without children 1`] = ` +exports[` renders one namespace without children 1`] = `
    { + const namespaceStore = di.inject(namespaceStoreInjectable); + + return namespaceStore.getByLabel(["hnc.x-k8s.io/included-namespace=true"]); + }, +}) + +export default hierarchicalNamespacesInjectable; \ No newline at end of file diff --git a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.test.tsx b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.test.tsx index 461eeee02e..090aa8ae8b 100644 --- a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.test.tsx +++ b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.test.tsx @@ -2,28 +2,15 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { AsyncFnMock } from "@async-fn/jest"; -import asyncFn from "@async-fn/jest"; import type { DiContainer } from "@ogre-tools/injectable"; import { fireEvent } from "@testing-library/react"; import React from "react"; -import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; -import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; -import type { Fetch } from "../../../common/fetch/fetch.injectable"; -import fetchInjectable from "../../../common/fetch/fetch.injectable"; import { Namespace } from "../../../common/k8s-api/endpoints"; -import { createMockResponseFromString } from "../../../test-utils/mock-responses"; -import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable"; -import createClusterInjectable from "../../cluster/create-cluster.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; -import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable"; -import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable"; -import { type Disposer, disposer } from "../../utils"; import type { DiRender } from "../test-utils/renderFor"; import { renderFor } from "../test-utils/renderFor"; +import hierarchicalNamespacesInjectable from "./hierarchical-namespaces.injectable"; import { NamespaceTreeView } from "./namespace-tree-view"; -import type { NamespaceStore } from "./store"; -import namespaceStoreInjectable from "./store.injectable"; jest.mock("react-router-dom", () => ({ Link: ({ children }: { children: React.ReactNode }) => children, @@ -116,149 +103,103 @@ const levelDeepSubChildA = createNamespace("level-deep-subchild-a", { describe("", () => { let di: DiContainer; let render: DiRender; - let namespaceStore: NamespaceStore; - let fetchMock: AsyncFnMock; - let cleanup: Disposer; beforeEach(async () => { di = getDiForUnitTesting({ doGeneralOverrides: true }); - di.unoverride(subscribeStoresInjectable); - di.override(directoryForUserDataInjectable, () => "/some-user-store-path"); - di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs"); - di.override(storesAndApisCanBeCreatedInjectable, () => true); + di.override(hierarchicalNamespacesInjectable, () => [ + acmeGroup, + orgA, + teamA, + teamB, + teamC, + service1, + levelsDeep, + levelDeepChildA, + levelDeepChildB, + levelDeepSubChildA, + ]) - fetchMock = asyncFn(); - di.override(fetchInjectable, () => fetchMock); - - const createCluster = di.inject(createClusterInjectable); - - di.override(hostedClusterInjectable, () => createCluster({ - contextName: "some-context-name", - id: "some-cluster-id", - kubeConfigPath: "/some-path-to-a-kubeconfig", - }, { - clusterServerUrl: "https://localhost:8080", - })); - - namespaceStore = di.inject(namespaceStoreInjectable); - - const subscribeStores = di.inject(subscribeStoresInjectable); - - cleanup = disposer(subscribeStores([namespaceStore])); render = renderFor(di); }); - afterEach(() => { - cleanup(); + it("renders null with regular namespace", () => { + const result = render(); + + expect(result.baseElement).toMatchSnapshot(); }); - describe("once the subscribe resolves", () => { - beforeEach(async () => { - await fetchMock.resolveSpecific([ - "https://127.0.0.1:12345/api-kube/api/v1/namespaces", - ], createMockResponseFromString("https://127.0.0.1:12345/api-kube/api/v1/namespaces", JSON.stringify({ - apiVersion: "v1", - kind: "NamespaceList", - metadata: {}, - items: [ - createNamespace("test-1"), - createNamespace("test-2"), - createNamespace("test-3"), - createNamespace("test-4"), - createNamespace("test-5"), - acmeGroup, - orgA, - teamA, - teamB, - teamC, - service1, - levelsDeep, - levelDeepChildA, - levelDeepChildB, - levelDeepSubChildA, - ], - }))); - }); + it("renders one namespace without children", () => { + const result = render(); - it("renders null with regular namespace", () => { - const result = render(); - - expect(result.baseElement).toMatchSnapshot(); - }); + expect(result.baseElement).toMatchSnapshot(); + }); - it("renders one namespace without children", () => { - const result = render(); - - expect(result.baseElement).toMatchSnapshot(); - }); + it("renders namespace with 2 children namespaces", () => { + const result = render(); - it("renders namespace with 2 children namespaces", () => { - const result = render(); + expect(result.baseElement).toMatchSnapshot(); + }); - expect(result.baseElement).toMatchSnapshot(); - }); + it("renders namespace with children namespaces and a subnamespace", () => { + const result = render(); - it("renders namespace with children namespaces and a subnamespace", () => { - const result = render(); + expect(result.baseElement).toMatchSnapshot(); + }); - expect(result.baseElement).toMatchSnapshot(); - }); + it("renders an indicator badge for the subnamespace", () => { + const result = render(); - it("renders an indicator badge for the subnamespace", () => { - const result = render(); + expect(result.getByTestId("subnamespace-badge-for-service-1-1")).toBeInTheDocument(); + }); - expect(result.getByTestId("subnamespace-badge-for-service-1-1")).toBeInTheDocument(); - }); + it("does not render an indicator badge for the true namespace", () => { + const result = render(); + const trueNamespace = result.getByTestId("namespace-team-c-1"); - it("does not render an indicator badge for the true namespace", () => { - const result = render(); - const trueNamespace = result.getByTestId("namespace-team-c-1"); + expect(trueNamespace.querySelector("[data-testid='subnamespace-badge-for-team-c-1']")).toBeNull(); + }); - expect(trueNamespace.querySelector("[data-testid='subnamespace-badge-for-team-c-1']")).toBeNull(); - }); + it("renders 2 levels deep", () => { + const result = render(); - it("renders 2 levels deep", () => { - const result = render(); + expect(result.baseElement).toMatchSnapshot(); + }); - expect(result.baseElement).toMatchSnapshot(); - }); + it("expands children items by default", () => { + const result = render(); + const deepest = result.getByTestId("namespace-level-deep-child-b-1"); - it("expands children items by default", () => { - const result = render(); - const deepest = result.getByTestId("namespace-level-deep-child-b-1"); + expect(deepest).toHaveAttribute("aria-expanded", "true"); + }); - expect(deepest).toHaveAttribute("aria-expanded", "true"); - }); + it("collapses item by clicking minus button", () => { + const result = render(); + const levelB = result.getByTestId("namespace-level-deep-child-b-1"); + const minusButton = levelB.querySelector("[data-testid='minus-square']"); - it("collapses item by clicking minus button", () => { - const result = render(); - const levelB = result.getByTestId("namespace-level-deep-child-b-1"); - const minusButton = levelB.querySelector("[data-testid='minus-square']"); + if (minusButton) { + fireEvent.click(minusButton); + } - if (minusButton) { - fireEvent.click(minusButton); - } + expect(result.baseElement).toMatchSnapshot(); + }); - expect(result.baseElement).toMatchSnapshot(); - }); + it("expands item by clicking plus button", () => { + const result = render(); + const levelB = result.getByTestId("namespace-level-deep-child-b-1"); + const minusButton = levelB.querySelector("[data-testid='minus-square']"); - it("expands item by clicking plus button", () => { - const result = render(); - const levelB = result.getByTestId("namespace-level-deep-child-b-1"); - const minusButton = levelB.querySelector("[data-testid='minus-square']"); + if (minusButton) { + fireEvent.click(minusButton); + } - if (minusButton) { - fireEvent.click(minusButton); - } + const plusButton = levelB.querySelector("[data-testid='plus-square']"); - const plusButton = levelB.querySelector("[data-testid='plus-square']"); + if (plusButton) { + fireEvent.click(plusButton); + } - if (plusButton) { - fireEvent.click(plusButton); - } - - expect(result.baseElement).toMatchSnapshot(); - }); + expect(result.baseElement).toMatchSnapshot(); }); }); diff --git a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx index 355dbb3494..81a0c6cec0 100644 --- a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx +++ b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx @@ -14,16 +14,15 @@ import type { Namespace } from "../../../common/k8s-api/endpoints"; import { DrawerTitle } from "../drawer"; import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable"; import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable"; -import type { NamespaceStore } from "./store"; -import namespaceStoreInjectable from "./store.injectable"; import { SubnamespaceBadge } from "./subnamespace-badge"; +import hierarchicalNamespacesInjectable from "./hierarchical-namespaces.injectable"; interface NamespaceTreeViewProps { root: Namespace; } interface Dependencies { - namespaceStore: NamespaceStore; + namespaces: Namespace[]; getDetailsUrl: GetDetailsUrl; } @@ -33,14 +32,13 @@ function isNamespaceControlledByHNC(namespace: Namespace) { return namespace.getLabels().find(label => label === hierarchicalNamesaceControllerLabel); } -function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: Dependencies & NamespaceTreeViewProps) { - const hierarchicalNamespaces = namespaceStore.getByLabel(["hnc.x-k8s.io/included-namespace=true"]); - const [expandedItems, setExpandedItems] = React.useState(hierarchicalNamespaces.map(ns => `namespace-${ns.getId()}`)); +function NonInjectableNamespaceTreeView({ root, namespaces, getDetailsUrl }: Dependencies & NamespaceTreeViewProps) { + const [expandedItems, setExpandedItems] = React.useState(namespaces.map(ns => `namespace-${ns.getId()}`)); const classes = { group: styles.group, label: styles.label }; const nodeId = `namespace-${root.getId()}`; function renderChildren(parent: Namespace) { - const children = hierarchicalNamespaces.filter(ns => + const children = namespaces.filter(ns => ns.getLabels().find(label => label === `${parent.getName()}.tree.hnc.x-k8s.io/depth=1`), ); @@ -133,7 +131,7 @@ function PlusSquareIcon() { export const NamespaceTreeView = withInjectables(NonInjectableNamespaceTreeView, { getProps: (di, props) => ({ - namespaceStore: di.inject(namespaceStoreInjectable), + namespaces: di.inject(hierarchicalNamespacesInjectable), getDetailsUrl: di.inject(getDetailsUrlInjectable), ...props, }),