diff --git a/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap b/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap
new file mode 100644
index 0000000000..17b797c044
--- /dev/null
+++ b/src/renderer/components/+namespaces/__snapshots__/namespace-select-filter.test.tsx.snap
@@ -0,0 +1,868 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` renders 1`] = `
+
+
+
+
+
+
+
+
+
+ All namespaces
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` when clicked renders 1`] = `
+
+
+
+
+`;
+
+exports[` when clicked when 'kube-system' is clicked renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Namespace: kube-system
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` when clicked when 'kube-system' is clicked when clicked again renders 1`] = `
+
+
+
+
+`;
+
+exports[` when clicked when 'kube-system' is clicked when clicked again when 'default' is clicked renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Namespace: default
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` when clicked when 'kube-system' is clicked when clicked again when 'default' is clicked when clicked again, then holding down multi select key, and then clicking 'kube-system-2' when 'kube-system-2' is clicked renders 1`] = `
+
+
+
+
+`;
diff --git a/src/renderer/components/+namespaces/namespace-select-filter-model/namespace-select-filter-model.tsx b/src/renderer/components/+namespaces/namespace-select-filter-model/namespace-select-filter-model.tsx
index 1c34690819..718790cb88 100644
--- a/src/renderer/components/+namespaces/namespace-select-filter-model/namespace-select-filter-model.tsx
+++ b/src/renderer/components/+namespaces/namespace-select-filter-model/namespace-select-filter-model.tsx
@@ -70,11 +70,13 @@ export class NamespaceSelectFilterModel {
{
value: selectAllNamespaces,
label: "All Namespaces",
+ id: "all-namespaces",
isSelected: false,
},
...baseOptions.map(namespace => ({
value: namespace,
label: namespace,
+ id: namespace,
isSelected: selectedNames.has(namespace),
})),
];
@@ -94,6 +96,7 @@ export class NamespaceSelectFilterModel {
small
material="check"
className="box right"
+ data-testid={`namespace-select-filter-option-${value}-selected`}
/>
)}
diff --git a/src/renderer/components/+namespaces/namespace-select-filter.test.tsx b/src/renderer/components/+namespaces/namespace-select-filter.test.tsx
new file mode 100644
index 0000000000..abc40f62e7
--- /dev/null
+++ b/src/renderer/components/+namespaces/namespace-select-filter.test.tsx
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+
+import type { DiContainer } from "@ogre-tools/injectable";
+import type { RenderResult } from "@testing-library/react";
+import { fireEvent } from "@testing-library/react";
+import React from "react";
+import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
+import { Namespace } from "../../../common/k8s-api/endpoints";
+import { getDiForUnitTesting } from "../../getDiForUnitTesting";
+import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
+import { renderFor } from "../test-utils/renderFor";
+import { NamespaceSelectFilter } from "./namespace-select-filter";
+import type { NamespaceStore } from "./store";
+import namespaceStoreInjectable from "./store.injectable";
+
+function createNamespace(name: string): Namespace {
+ return new Namespace({
+ apiVersion: "v1",
+ kind: "Namespace",
+ metadata: {
+ name,
+ resourceVersion: "1",
+ selfLink: `/api/v1/namespaces/${name}`,
+ uid: `${name}-1`,
+ },
+ });
+}
+
+describe(" ", () => {
+ let di: DiContainer;
+ let namespaceStore: NamespaceStore;
+ let result: RenderResult;
+
+ beforeEach(() => {
+ di = getDiForUnitTesting({ doGeneralOverrides: true });
+ di.override(directoryForUserDataInjectable, () => "/some-directory");
+ di.override(storesAndApisCanBeCreatedInjectable, () => true);
+ namespaceStore = di.inject(namespaceStoreInjectable);
+
+ const render = renderFor(di);
+
+ namespaceStore.items.replace([
+ createNamespace("default"),
+ createNamespace("kube-system"),
+ createNamespace("kube-system-2"),
+ ]);
+
+ result = render((
+
+ ));
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ describe("when clicked", () => {
+ beforeEach(() => {
+ result.getByTestId("namespace-select-filter").click();
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ it("opens menu", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull();
+ });
+
+ describe("when 'kube-system' is clicked", () => {
+ beforeEach(() => {
+ result.getByText("kube-system").click();
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ it("has only 'kube-system' is selected in the store", () => {
+ expect(namespaceStore.contextNamespaces).toEqual(["kube-system"]);
+ });
+
+ it("closes menu", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull();
+ });
+
+ describe("when clicked again", () => {
+ beforeEach(() => {
+ result.getByTestId("namespace-select-filter").click();
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ it("shows 'kube-system' as selected", () => {
+ expect(result.queryByTestId("namespace-select-filter-option-kube-system-selected")).not.toBeNull();
+ });
+
+ it("does not show 'default' as selected", () => {
+ expect(result.queryByTestId("namespace-select-filter-option-default-selected")).toBeNull();
+ });
+
+ describe("when 'default' is clicked", () => {
+ beforeEach(() => {
+ result.getByText("default").click();
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ it("has only 'default' is selected in the store", () => {
+ expect(namespaceStore.contextNamespaces).toEqual(["default"]);
+ });
+
+ it("closes menu", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull();
+ });
+
+ describe("when clicked again, then holding down multi select key, and then clicking 'kube-system-2'", () => {
+ beforeEach(() => {
+ const filter = result.getByTestId("namespace-select-filter");
+
+ filter.click();
+ fireEvent.keyDown(filter, { key: "Meta" });
+ });
+
+ describe("when 'kube-system-2' is clicked", () => {
+ beforeEach(() => {
+ result.getByText("kube-system-2").click();
+ });
+
+ it("renders", () => {
+ expect(result.baseElement).toMatchSnapshot();
+ });
+
+ it("has both 'default' and 'kube-system-2' as selected in the store", () => {
+ expect(new Set(namespaceStore.contextNamespaces)).toEqual(new Set(["default", "kube-system-2"]));
+ });
+
+ it("keeps menu open", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull();
+ });
+
+ it("does not show 'kube-system' as selected", () => {
+ expect(result.queryByTestId("namespace-select-filter-option-kube-system-selected")).toBeNull();
+ });
+
+ describe("when releasing multi select key", () => {
+ beforeEach(() => {
+ const filter = result.getByTestId("namespace-select-filter");
+
+ fireEvent.keyUp(filter, { key: "Meta" });
+ });
+
+ it("closes menu", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).toBeNull();
+ });
+ });
+ });
+
+ describe("when releasing multi select key", () => {
+ beforeEach(() => {
+ const filter = result.getByTestId("namespace-select-filter");
+
+ fireEvent.keyUp(filter, { key: "Meta" });
+ });
+
+ it("keeps menu open", () => {
+ expect(result.baseElement.querySelector("#react-select-namespace-select-filter-listbox")).not.toBeNull();
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/src/renderer/components/+namespaces/namespace-select-filter.tsx b/src/renderer/components/+namespaces/namespace-select-filter.tsx
index b68e211464..969cf9f917 100644
--- a/src/renderer/components/+namespaces/namespace-select-filter.tsx
+++ b/src/renderer/components/+namespaces/namespace-select-filter.tsx
@@ -30,6 +30,7 @@ const NonInjectedNamespaceSelectFilter = observer(({ model, id }: Dependencies &
onKeyDown={model.onKeyDown}
onClick={model.onClick}
className="NamespaceSelectFilterParent"
+ data-testid="namespace-select-filter"
>
id={id}
diff --git a/src/renderer/components/select/select.tsx b/src/renderer/components/select/select.tsx
index d38ff57f3a..61b6de1284 100644
--- a/src/renderer/components/select/select.tsx
+++ b/src/renderer/components/select/select.tsx
@@ -25,6 +25,7 @@ export interface SelectOption {
label: React.ReactNode;
isDisabled?: boolean;
isSelected?: boolean;
+ id?: string;
}
/**