1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/features/helm-releases/showing-details-for-helm-release.test.ts
Sebastian Malton d83d223742 Better fake time impl
Signed-off-by: Sebastian Malton <sebastian@malton.name>
2023-01-20 10:01:22 -05:00

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();
});
});
});
});
});
});
});
});
});
});
});
});
});