mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
635 lines
25 KiB
TypeScript
635 lines
25 KiB
TypeScript
/**
|
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
*/
|
|
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
|
import navigateToHelmReleasesInjectable from "../../common/front-end-routing/routes/cluster/helm/releases/navigate-to-helm-releases.injectable";
|
|
import type { RenderResult } from "@testing-library/react";
|
|
import { fireEvent } from "@testing-library/react";
|
|
import type { AsyncFnMock } from "@async-fn/jest";
|
|
import asyncFn from "@async-fn/jest";
|
|
import type { RequestHelmReleases } from "../../common/k8s-api/endpoints/helm-releases.api/request-releases.injectable";
|
|
import requestHelmReleasesInjectable from "../../common/k8s-api/endpoints/helm-releases.api/request-releases.injectable";
|
|
import type { RequestHelmReleaseConfiguration } from "../../common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable";
|
|
import requestHelmReleaseConfigurationInjectable from "../../common/k8s-api/endpoints/helm-releases.api/request-configuration.injectable";
|
|
import type { RequestHelmReleaseUpdate } from "../../common/k8s-api/endpoints/helm-releases.api/request-update.injectable";
|
|
import requestHelmReleaseUpdateInjectable from "../../common/k8s-api/endpoints/helm-releases.api/request-update.injectable";
|
|
import type { RequestDetailedHelmRelease } from "../../renderer/components/+helm-releases/release-details/release-details-model/request-detailed-helm-release.injectable";
|
|
import requestDetailedHelmReleaseInjectable from "../../renderer/components/+helm-releases/release-details/release-details-model/request-detailed-helm-release.injectable";
|
|
import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable";
|
|
import showCheckedErrorInjectable from "../../renderer/components/notifications/show-checked-error.injectable";
|
|
import getRandomUpgradeChartTabIdInjectable from "../../renderer/components/dock/upgrade-chart/get-random-upgrade-chart-tab-id.injectable";
|
|
import type { RequestHelmCharts } from "../../common/k8s-api/endpoints/helm-charts.api/request-charts.injectable";
|
|
import type { RequestHelmChartVersions } from "../../common/k8s-api/endpoints/helm-charts.api/request-versions.injectable";
|
|
import type { RequestHelmChartReadme } from "../../common/k8s-api/endpoints/helm-charts.api/request-readme.injectable";
|
|
import type { RequestHelmChartValues } from "../../common/k8s-api/endpoints/helm-charts.api/request-values.injectable";
|
|
import requestHelmChartsInjectable from "../../common/k8s-api/endpoints/helm-charts.api/request-charts.injectable";
|
|
import requestHelmChartVersionsInjectable from "../../common/k8s-api/endpoints/helm-charts.api/request-versions.injectable";
|
|
import requestHelmChartReadmeInjectable from "../../common/k8s-api/endpoints/helm-charts.api/request-readme.injectable";
|
|
import requestHelmChartValuesInjectable from "../../common/k8s-api/endpoints/helm-charts.api/request-values.injectable";
|
|
import { HelmChart } from "../../common/k8s-api/endpoints/helm-charts.api";
|
|
|
|
describe("showing details for helm release", () => {
|
|
let builder: ApplicationBuilder;
|
|
let requestHelmReleasesMock: AsyncFnMock<RequestHelmReleases>;
|
|
let requestDetailedHelmReleaseMock: AsyncFnMock<RequestDetailedHelmRelease>;
|
|
let requestHelmReleaseConfigurationMock: AsyncFnMock<RequestHelmReleaseConfiguration>;
|
|
let requestHelmReleaseUpdateMock: AsyncFnMock<RequestHelmReleaseUpdate>;
|
|
let requestHelmChartsMock: AsyncFnMock<RequestHelmCharts>;
|
|
let requestHelmChartVersionsMock: AsyncFnMock<RequestHelmChartVersions>;
|
|
let requestHelmChartReadmeMock: AsyncFnMock<RequestHelmChartReadme>;
|
|
let requestHelmChartValuesMock: AsyncFnMock<RequestHelmChartValues>;
|
|
let showSuccessNotificationMock: jest.Mock;
|
|
let showCheckedErrorNotificationMock: jest.Mock;
|
|
|
|
beforeEach(() => {
|
|
builder = getApplicationBuilder({
|
|
useFakeTime: {
|
|
dateTime: "2015-10-21T07:28:00Z",
|
|
},
|
|
});
|
|
|
|
builder.setEnvironmentToClusterFrame();
|
|
|
|
requestHelmReleasesMock = asyncFn();
|
|
requestDetailedHelmReleaseMock = asyncFn();
|
|
requestHelmReleaseConfigurationMock = asyncFn();
|
|
requestHelmReleaseUpdateMock = asyncFn();
|
|
requestHelmChartsMock = asyncFn();
|
|
requestHelmChartVersionsMock = asyncFn();
|
|
requestHelmChartReadmeMock = asyncFn();
|
|
requestHelmChartValuesMock = asyncFn();
|
|
|
|
showSuccessNotificationMock = jest.fn();
|
|
showCheckedErrorNotificationMock = jest.fn();
|
|
|
|
builder.beforeWindowStart((windowDi) => {
|
|
windowDi.override(getRandomUpgradeChartTabIdInjectable, () => () => "some-tab-id");
|
|
windowDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock);
|
|
windowDi.override(showCheckedErrorInjectable, () => showCheckedErrorNotificationMock);
|
|
windowDi.override(requestHelmReleasesInjectable, () => requestHelmReleasesMock);
|
|
windowDi.override(requestDetailedHelmReleaseInjectable, () => requestDetailedHelmReleaseMock);
|
|
windowDi.override(requestHelmReleaseConfigurationInjectable, () => requestHelmReleaseConfigurationMock);
|
|
windowDi.override(requestHelmReleaseUpdateInjectable, () => requestHelmReleaseUpdateMock);
|
|
windowDi.override(requestHelmChartsInjectable, () => requestHelmChartsMock);
|
|
windowDi.override(requestHelmChartVersionsInjectable, () => requestHelmChartVersionsMock);
|
|
windowDi.override(requestHelmChartReadmeInjectable, () => requestHelmChartReadmeMock);
|
|
windowDi.override(requestHelmChartValuesInjectable, () => requestHelmChartValuesMock);
|
|
});
|
|
|
|
builder.namespaces.add("some-namespace");
|
|
builder.namespaces.select("some-namespace");
|
|
builder.namespaces.add("some-namespace");
|
|
builder.namespaces.select("some-other-namespace");
|
|
});
|
|
|
|
describe("given application is started", () => {
|
|
let rendered: RenderResult;
|
|
|
|
beforeEach(async () => {
|
|
rendered = await builder.render();
|
|
});
|
|
|
|
describe("when navigating to helm releases", () => {
|
|
beforeEach(() => {
|
|
const windowDi = builder.applicationWindow.only.di;
|
|
|
|
const navigateToHelmReleases = windowDi.inject(
|
|
navigateToHelmReleasesInjectable,
|
|
);
|
|
|
|
navigateToHelmReleases();
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("calls for releases for each selected namespace", () => {
|
|
expect(requestHelmReleasesMock.mock.calls).toEqual([
|
|
["some-namespace"],
|
|
["some-other-namespace"],
|
|
]);
|
|
});
|
|
|
|
it("shows spinner", () => {
|
|
expect(
|
|
rendered.getByTestId("helm-releases-spinner"),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("when releases resolve but there is none, renders", async () => {
|
|
await requestHelmReleasesMock.resolve([]);
|
|
await requestHelmReleasesMock.resolve([]);
|
|
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
describe("when releases resolve", () => {
|
|
beforeEach(async () => {
|
|
await requestHelmReleasesMock.resolveSpecific(
|
|
([namespace]) => namespace === "some-namespace",
|
|
[
|
|
{
|
|
appVersion: "some-app-version",
|
|
name: "some-name",
|
|
namespace: "some-namespace",
|
|
chart: "some-chart-1.0.0",
|
|
status: "some-status",
|
|
updated: "some-updated",
|
|
revision: "some-revision",
|
|
},
|
|
],
|
|
);
|
|
|
|
await requestHelmReleasesMock.resolveSpecific(
|
|
([namespace]) => namespace === "some-other-namespace",
|
|
[
|
|
{
|
|
appVersion: "some-other-app-version",
|
|
name: "some-other-name",
|
|
namespace: "some-other-namespace",
|
|
chart: "some-other-chart-2.0.0",
|
|
status: "some-other-status",
|
|
updated: "some-other-updated",
|
|
revision: "some-other-revision",
|
|
},
|
|
],
|
|
);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not show spinner anymore", () => {
|
|
expect(
|
|
rendered.queryByTestId("helm-releases-spinner"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
describe("when selecting release to see details", () => {
|
|
beforeEach(() => {
|
|
const row = rendered.getByTestId(
|
|
"helm-release-row-for-some-namespace/some-name",
|
|
);
|
|
|
|
fireEvent.click(row);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("opens the details", () => {
|
|
expect(
|
|
rendered.getByTestId("helm-release-details-for-some-namespace/some-name"),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("calls for release", () => {
|
|
expect(requestDetailedHelmReleaseMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
);
|
|
});
|
|
|
|
it("shows spinner", () => {
|
|
expect(
|
|
rendered.getByTestId("helm-release-detail-content-spinner"),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
describe("when opening details for second release", () => {
|
|
beforeEach(() => {
|
|
requestDetailedHelmReleaseMock.mockClear();
|
|
|
|
const row = rendered.getByTestId(
|
|
"helm-release-row-for-some-other-namespace/some-other-name",
|
|
);
|
|
|
|
fireEvent.click(row);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("calls for another release", () => {
|
|
expect(requestDetailedHelmReleaseMock).toHaveBeenCalledWith(
|
|
"some-other-name",
|
|
"some-other-namespace",
|
|
);
|
|
});
|
|
|
|
it("closes details for first release", () => {
|
|
expect(
|
|
rendered.queryByTestId("helm-release-details-for-some-namespace/some-name"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("opens details for second release", () => {
|
|
expect(
|
|
rendered.getByTestId("helm-release-details-for-some-other-namespace/some-other-name"),
|
|
).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe("when details is closed", () => {
|
|
beforeEach(() => {
|
|
const closeButton = rendered.getByTestId(
|
|
"close-helm-release-detail",
|
|
);
|
|
|
|
fireEvent.click(closeButton);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("closes the details", () => {
|
|
expect(
|
|
rendered.queryByTestId("helm-release-details-for-some-namespace/some-name"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
describe("when opening details for same release", () => {
|
|
beforeEach(() => {
|
|
requestDetailedHelmReleaseMock.mockClear();
|
|
|
|
const row = rendered.getByTestId(
|
|
"helm-release-row-for-some-namespace/some-name",
|
|
);
|
|
|
|
fireEvent.click(row);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not reload", () => {
|
|
expect(requestDetailedHelmReleaseMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("when call for release resolves with error", () => {
|
|
beforeEach(async () => {
|
|
await requestDetailedHelmReleaseMock.resolve({
|
|
callWasSuccessful: false,
|
|
error: "some-error",
|
|
});
|
|
});
|
|
|
|
it("renders", async () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not show spinner anymore", () => {
|
|
expect(
|
|
rendered.queryByTestId("helm-release-detail-content-spinner"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("shows error message about missing release", () => {
|
|
expect(
|
|
rendered.getByTestId("helm-release-detail-error"),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("does not call for release configuration", () => {
|
|
expect(requestHelmReleaseConfigurationMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("when call for release resolve with release", () => {
|
|
beforeEach(async () => {
|
|
await requestDetailedHelmReleaseMock.resolve({
|
|
callWasSuccessful: true,
|
|
response: {
|
|
release: {
|
|
appVersion: "some-app-version",
|
|
chart: "some-chart-1.0.0",
|
|
status: "some-status",
|
|
updated: "some-updated",
|
|
revision: "some-revision",
|
|
name: "some-name",
|
|
namespace: "some-namespace",
|
|
},
|
|
|
|
details: {
|
|
name: "some-name",
|
|
namespace: "some-namespace",
|
|
version: "some-version",
|
|
config: "some-config",
|
|
manifest: "some-manifest",
|
|
|
|
info: {
|
|
deleted: "some-deleted",
|
|
description: "some-description",
|
|
first_deployed: "some-first-deployed",
|
|
last_deployed: "some-last-deployed",
|
|
notes: "some-notes",
|
|
status: "some-status",
|
|
},
|
|
|
|
resources: [
|
|
{
|
|
kind: "some-kind",
|
|
apiVersion: "some-api-version",
|
|
metadata: {
|
|
uid: "some-uid",
|
|
name: "some-resource",
|
|
namespace: "some-namespace",
|
|
creationTimestamp: "2015-10-22T07:28:00Z",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("calls for release configuration", () => {
|
|
expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
true,
|
|
);
|
|
});
|
|
|
|
describe("when configuration resolves", () => {
|
|
beforeEach(async () => {
|
|
await requestHelmReleaseConfigurationMock.resolve(
|
|
"some-configuration",
|
|
);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not have tab for upgrading chart yet", () => {
|
|
expect(
|
|
rendered.queryByTestId("dock-tab-for-some-tab-id"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
describe("when selecting to upgrade chart", () => {
|
|
beforeEach(() => {
|
|
const upgradeButton = rendered.getByTestId(
|
|
"helm-release-upgrade-button",
|
|
);
|
|
|
|
fireEvent.click(upgradeButton);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("opens tab for upgrading chart", () => {
|
|
expect(
|
|
rendered.getByTestId("dock-tab-for-some-tab-id"),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("closes the details", () => {
|
|
expect(
|
|
rendered.queryByTestId("helm-release-details-for-some-namespace/some-name"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe("when changing the configuration", () => {
|
|
beforeEach(() => {
|
|
const configuration = rendered.getByTestId(
|
|
"monaco-editor-for-helm-release-configuration",
|
|
);
|
|
|
|
fireEvent.change(configuration, {
|
|
target: { value: "some-new-configuration" },
|
|
});
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("has the configuration", () => {
|
|
const input = rendered.getByTestId(
|
|
"monaco-editor-for-helm-release-configuration",
|
|
);
|
|
|
|
expect(input).toHaveValue("some-new-configuration");
|
|
});
|
|
|
|
it("does not save changes yet", () => {
|
|
expect(requestHelmReleaseUpdateMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
describe("when toggling to see only user defined values", () => {
|
|
beforeEach(() => {
|
|
requestHelmReleaseConfigurationMock.mockClear();
|
|
|
|
const toggle = rendered.getByTestId(
|
|
"user-supplied-values-only-checkbox",
|
|
);
|
|
|
|
fireEvent.click(toggle);
|
|
});
|
|
|
|
it("calls for only user defined configuration", () => {
|
|
expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
false,
|
|
);
|
|
});
|
|
|
|
describe("when configuration resolves", () => {
|
|
beforeEach(async () => {
|
|
await requestHelmReleaseConfigurationMock.resolve(
|
|
"some-other-configuration",
|
|
);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("overrides the user inputted configuration with new configuration", () => {
|
|
const input = rendered.getByTestId(
|
|
"monaco-editor-for-helm-release-configuration",
|
|
);
|
|
|
|
expect(input).toHaveValue("some-other-configuration");
|
|
});
|
|
|
|
it("when toggling again, calls for all configuration", () => {
|
|
requestHelmReleaseConfigurationMock.mockClear();
|
|
|
|
const toggle = rendered.getByTestId(
|
|
"user-supplied-values-only-checkbox",
|
|
);
|
|
|
|
fireEvent.click(toggle);
|
|
|
|
expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
true,
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("when saving", () => {
|
|
beforeEach(() => {
|
|
const saveButton = rendered.getByTestId(
|
|
"helm-release-configuration-save-button",
|
|
);
|
|
|
|
fireEvent.click(saveButton);
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("shows spinner", () => {
|
|
const saveButton = rendered.getByTestId(
|
|
"helm-release-configuration-save-button",
|
|
);
|
|
|
|
expect(saveButton).toHaveClass("waiting");
|
|
});
|
|
|
|
describe("when requestHelmCharts resolves", () => {
|
|
beforeEach(async () => {
|
|
await requestHelmChartsMock.resolve([HelmChart.create({
|
|
apiVersion: "1.2.3",
|
|
version: "1.0.0",
|
|
created: "at-some-time",
|
|
name: "some-chart",
|
|
repo: "some-repo",
|
|
})]);
|
|
});
|
|
describe("when requestHelmChartVersions resolves", () => {
|
|
beforeEach(async () => {
|
|
await requestHelmChartVersionsMock.resolve([HelmChart.create({
|
|
apiVersion: "1.2.3",
|
|
version: "1.0.0",
|
|
created: "at-some-time",
|
|
name: "some-chart",
|
|
repo: "some-repo",
|
|
})]);
|
|
});
|
|
|
|
it("calls for update", () => {
|
|
expect(requestHelmReleaseUpdateMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
|
|
{
|
|
chart: "some-chart",
|
|
repo: "some-repo",
|
|
values: "some-new-configuration",
|
|
version: "1.0.0",
|
|
},
|
|
);
|
|
});
|
|
|
|
describe("when update resolves with success", () => {
|
|
beforeEach(async () => {
|
|
requestHelmReleasesMock.mockClear();
|
|
requestHelmReleaseConfigurationMock.mockClear();
|
|
|
|
await requestHelmReleaseUpdateMock.resolve({
|
|
callWasSuccessful: true,
|
|
});
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not show spinner anymore", () => {
|
|
const saveButton = rendered.getByTestId(
|
|
"helm-release-configuration-save-button",
|
|
);
|
|
|
|
expect(saveButton).not.toHaveClass("waiting");
|
|
});
|
|
|
|
it("reloads the configuration", () => {
|
|
expect(requestHelmReleaseConfigurationMock).toHaveBeenCalledWith(
|
|
"some-name",
|
|
"some-namespace",
|
|
true,
|
|
);
|
|
});
|
|
|
|
it("shows success notification", () => {
|
|
expect(showSuccessNotificationMock).toHaveBeenCalled();
|
|
});
|
|
|
|
it("does not show error notification", () => {
|
|
expect(showCheckedErrorNotificationMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("when update resolves with failure", () => {
|
|
beforeEach(async () => {
|
|
requestHelmReleasesMock.mockClear();
|
|
requestHelmReleaseConfigurationMock.mockClear();
|
|
|
|
await requestHelmReleaseUpdateMock.resolve({
|
|
callWasSuccessful: false,
|
|
error: "some-error",
|
|
});
|
|
});
|
|
|
|
it("renders", () => {
|
|
expect(rendered.baseElement).toMatchSnapshot();
|
|
});
|
|
|
|
it("does not show spinner anymore", () => {
|
|
const saveButton = rendered.getByTestId(
|
|
"helm-release-configuration-save-button",
|
|
);
|
|
|
|
expect(saveButton).not.toHaveClass("waiting");
|
|
});
|
|
|
|
it("does not reload the configuration", () => {
|
|
expect(requestHelmReleaseConfigurationMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("does not show success notification", () => {
|
|
expect(showSuccessNotificationMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("shows error notification", () => {
|
|
expect(showCheckedErrorNotificationMock).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|