diff --git a/package.json b/package.json
index 7d00909318..de63a3c87a 100644
--- a/package.json
+++ b/package.json
@@ -328,6 +328,7 @@
"react-refresh": "^0.9.0",
"react-router-dom": "^5.2.0",
"react-select": "^3.1.0",
+ "react-select-event": "^5.1.0",
"react-window": "^1.8.5",
"sass-loader": "^8.0.2",
"sharp": "^0.26.1",
diff --git a/src/renderer/components/dock/__test__/log-resource-selector.test.tsx b/src/renderer/components/dock/__test__/log-resource-selector.test.tsx
new file mode 100644
index 0000000000..1c8111657e
--- /dev/null
+++ b/src/renderer/components/dock/__test__/log-resource-selector.test.tsx
@@ -0,0 +1,198 @@
+import React from "react";
+import "@testing-library/jest-dom/extend-expect";
+import { render } from "@testing-library/react";
+import selectEvent from "react-select-event";
+
+import { Pod } from "../../../api/endpoints";
+import { LogResourceSelector } from "../log-resource-selector";
+import { LogTabData } from "../log-tab.store";
+
+const dummyPod = {
+ apiVersion: "v1",
+ kind: "dummy",
+ metadata: {
+ uid: "dummyPod",
+ name: "dummyPod",
+ creationTimestamp: "dummy",
+ resourceVersion: "dummy",
+ namespace: "default"
+ },
+ spec: {
+ initContainers: [] as any,
+ containers: [
+ {
+ name: "docker-exporter",
+ image: "docker.io/prom/node-exporter:v1.0.0-rc.0",
+ imagePullPolicy: "pull"
+ }
+ ],
+ serviceAccountName: "dummy",
+ serviceAccount: "dummy",
+ },
+ status: {
+ phase: "Running",
+ conditions: [{
+ type: "Running",
+ status: "Running",
+ lastProbeTime: 1,
+ lastTransitionTime: "Some time",
+ }],
+ hostIP: "dummy",
+ podIP: "dummy",
+ startTime: "dummy",
+ }
+};
+
+const anotherDummyPod = {
+ apiVersion: "v1",
+ kind: "dummy",
+ metadata: {
+ uid: "anotherDummyPod",
+ name: "anotherDummyPod",
+ creationTimestamp: "dummy",
+ resourceVersion: "dummy",
+ namespace: "default",
+ ownerReferences: [{
+ apiVersion: "v1",
+ kind: "Deployment",
+ name: "super-deployment",
+ uid: "uuid",
+ controller: true,
+ blockOwnerDeletion: true,
+ }]
+ },
+ spec: {
+ initContainers: [
+ {
+ name: "init-node-exporter",
+ image: "docker.io/prom/node-exporter:v1.0.0-rc.0",
+ imagePullPolicy: "pull"
+ },
+ {
+ name: "init-node-exporter-1",
+ image: "docker.io/prom/node-exporter:v1.0.0-rc.0",
+ imagePullPolicy: "pull"
+ }
+ ],
+ containers: [
+ {
+ name: "node-exporter",
+ image: "docker.io/prom/node-exporter:v1.0.0-rc.0",
+ imagePullPolicy: "pull"
+ },
+ {
+ name: "node-exporter-1",
+ image: "docker.io/prom/node-exporter:v1.0.0-rc.0",
+ imagePullPolicy: "pull"
+ }
+ ],
+ serviceAccountName: "dummy",
+ serviceAccount: "dummy",
+ },
+ status: {
+ phase: "Running",
+ conditions: [{
+ type: "Running",
+ status: "Running",
+ lastProbeTime: 1,
+ lastTransitionTime: "Some time",
+ }],
+ hostIP: "dummy",
+ podIP: "dummy",
+ startTime: "dummy",
+ }
+};
+
+const getComponent = (tabData: LogTabData) => {
+ return (
+
+ );
+};
+
+const getOnePodTabData = (): LogTabData => {
+ const selectedPod = new Pod(dummyPod);
+
+ return {
+ pods: [] as Pod[],
+ selectedPod,
+ selectedContainer: selectedPod.getContainers()[0],
+ containers: selectedPod.getContainers(),
+ initContainers: selectedPod.getInitContainers(),
+ };
+};
+
+const getFewPodsTabData = (): LogTabData => {
+ const selectedPod = new Pod(anotherDummyPod);
+ const anotherPod = new Pod(dummyPod);
+
+ return {
+ pods: [anotherPod],
+ selectedPod,
+ selectedContainer: selectedPod.getContainers()[0],
+ containers: selectedPod.getContainers(),
+ initContainers: selectedPod.getInitContainers(),
+ };
+};
+
+describe("", () => {
+ it("renders w/o errors", () => {
+ const tabData = getOnePodTabData();
+ const { container } = render(getComponent(tabData));
+
+ expect(container).toBeInstanceOf(HTMLElement);
+ });
+
+ it("renders proper namespace", () => {
+ const tabData = getOnePodTabData();
+ const { getByTestId } = render(getComponent(tabData));
+ const ns = getByTestId("namespace-badge");
+
+ expect(ns).toHaveTextContent("default");
+ });
+
+ it("renders proper selected items within dropdowns", () => {
+ const tabData = getOnePodTabData();
+ const { getByText } = render(getComponent(tabData));
+
+ expect(getByText("dummyPod")).toBeInTheDocument();
+ expect(getByText("docker-exporter")).toBeInTheDocument();
+ });
+
+ it("renders sibling pods in dropdown", () => {
+ const tabData = getFewPodsTabData();
+ const { container, getByText } = render(getComponent(tabData));
+ const podSelector: HTMLElement = container.querySelector(".pod-selector");
+
+ selectEvent.openMenu(podSelector);
+
+ expect(getByText("dummyPod")).toBeInTheDocument();
+ expect(getByText("anotherDummyPod")).toBeInTheDocument();
+ });
+
+ it("renders sibling containers in dropdown", () => {
+ const tabData = getFewPodsTabData();
+ const { getByText, container } = render(getComponent(tabData));
+ const containerSelector: HTMLElement = container.querySelector(".container-selector");
+
+ selectEvent.openMenu(containerSelector);
+
+ expect(getByText("node-exporter-1")).toBeInTheDocument();
+ expect(getByText("init-node-exporter")).toBeInTheDocument();
+ expect(getByText("init-node-exporter-1")).toBeInTheDocument();
+ });
+
+ it("renders pod owner as dropdown title", () => {
+ const tabData = getFewPodsTabData();
+ const { getByText, container } = render(getComponent(tabData));
+ const podSelector: HTMLElement = container.querySelector(".pod-selector");
+
+ selectEvent.openMenu(podSelector);
+
+ expect(getByText("super-deployment")).toBeInTheDocument();
+ });
+});
\ No newline at end of file
diff --git a/src/renderer/components/dock/log-resource-selector.tsx b/src/renderer/components/dock/log-resource-selector.tsx
index 3d10c928da..43f4c656bc 100644
--- a/src/renderer/components/dock/log-resource-selector.tsx
+++ b/src/renderer/components/dock/log-resource-selector.tsx
@@ -33,6 +33,11 @@ export const LogResourceSelector = observer((props: Props) => {
const onPodChange = (option: SelectOption) => {
const selectedPod = podsStore.getByName(option.value, pod.getNs());
+
+ if (!selectedPod) {
+ return;
+ }
+
const { getContainers, getInitContainers, getAllContainers } = selectedPod;
save({
@@ -77,13 +82,14 @@ export const LogResourceSelector = observer((props: Props) => {
return (
- Namespace
+ Namespace
Pod
Container
);
diff --git a/yarn.lock b/yarn.lock
index 97eae9dc25..d9d4729536 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -267,6 +267,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.12.5":
+ version "7.12.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
+ integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.1", "@babel/template@^7.3.3":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811"
@@ -768,6 +775,17 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
+"@jest/types@^26.6.2":
+ version "26.6.2"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
+ integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^15.0.0"
+ chalk "^4.0.0"
+
"@kubernetes/client-node@^0.12.0":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.12.0.tgz#79120311bced206ac8fa36435fb4cc2c1828fff2"
@@ -931,6 +949,20 @@
dependencies:
defer-to-connect "^1.0.1"
+"@testing-library/dom@>=7":
+ version "7.29.4"
+ resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.29.4.tgz#1647c2b478789621ead7a50614ad81ab5ae5b86c"
+ integrity sha512-CtrJRiSYEfbtNGtEsd78mk1n1v2TUbeABlNIcOCJdDfkN5/JTOwQEbbQpoSRxGqzcWPgStMvJ4mNolSuBRv1NA==
+ dependencies:
+ "@babel/code-frame" "^7.10.4"
+ "@babel/runtime" "^7.12.5"
+ "@types/aria-query" "^4.2.0"
+ aria-query "^4.2.2"
+ chalk "^4.1.0"
+ dom-accessibility-api "^0.5.4"
+ lz-string "^1.4.4"
+ pretty-format "^26.6.2"
+
"@testing-library/dom@^7.26.0":
version "7.26.3"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.26.3.tgz#5554ee985f712d621bd676104b879f85d9a7a0ef"
@@ -4538,7 +4570,7 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
-dom-accessibility-api@^0.5.1:
+dom-accessibility-api@^0.5.1, dom-accessibility-api@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz#b06d059cdd4a4ad9a79275f9d414a5c126241166"
integrity sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==
@@ -10797,6 +10829,16 @@ pretty-format@^26.0.1:
ansi-styles "^4.0.0"
react-is "^16.12.0"
+pretty-format@^26.6.2:
+ version "26.6.2"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
+ integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
+ dependencies:
+ "@jest/types" "^26.6.2"
+ ansi-regex "^5.0.0"
+ ansi-styles "^4.0.0"
+ react-is "^17.0.1"
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -11173,6 +11215,13 @@ react-router@5.2.0, react-router@^5.2.0:
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
+react-select-event@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/react-select-event/-/react-select-event-5.1.0.tgz#d45ef68f2a9c872903e8c9725f3ae6e7576f7be0"
+ integrity sha512-D5DzJlYCdZsGbDVFMQFynrG0OLalJM3ZzDT7KQADNVWE604JCeQF9bIuvPZqVD7IzhnPsFzOUCsilzDA6w6WRQ==
+ dependencies:
+ "@testing-library/dom" ">=7"
+
react-select@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.1.0.tgz#ab098720b2e9fe275047c993f0d0caf5ded17c27"