Rename old directory for behaviours as "features" to better communicate new intent with new directory structure to organize code and tests around features instead of technicalities (#6033)

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Iku-tursoandJanne Savolainen authored and GitHub committed 2022-08-16 15:09:08 +03:00
1 parent 36077a9fea
commit 299922c8a7
107 files changed

No files matched your search

@@ -0,0 +1,382 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import { fireEvent } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import execFileInjectable from "../../common/fs/exec-file.injectable";
import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable";
import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
import type { HelmRepo } from "../../common/helm/helm-repo";
import callForPublicHelmRepositoriesInjectable from "../../renderer/components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
import isPathInjectable from "../../renderer/components/input/validators/is-path.injectable";
import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable";
import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable";
import type { AsyncResult } from "../../common/utils/async-result";
describe("add custom helm repository in preferences", () => {
let applicationBuilder: ApplicationBuilder;
let showSuccessNotificationMock: jest.Mock;
let showErrorNotificationMock: jest.Mock;
let rendered: RenderResult;
let execFileMock: AsyncFnMock<
ReturnType<typeof execFileInjectable["instantiate"]>
>;
let getActiveHelmRepositoriesMock: AsyncFnMock<() => Promise<AsyncResult<HelmRepo[]>>>;
beforeEach(async () => {
jest.useFakeTimers();
applicationBuilder = getApplicationBuilder();
execFileMock = asyncFn();
getActiveHelmRepositoriesMock = asyncFn();
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
rendererDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []);
showSuccessNotificationMock = jest.fn();
rendererDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock);
showErrorNotificationMock = jest.fn();
rendererDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock);
// TODO: Figure out how to make async validators unit testable
rendererDi.override(isPathInjectable, () => ({ debounce: 0, validate: async () => {} }));
mainDi.override(
getActiveHelmRepositoriesInjectable,
() => getActiveHelmRepositoriesMock,
);
mainDi.override(execFileInjectable, () => execFileMock);
mainDi.override(helmBinaryPathInjectable, () => "some-helm-binary-path");
});
rendered = await applicationBuilder.render();
});
describe("when navigating to preferences containing helm repositories", () => {
beforeEach(async () => {
applicationBuilder.preferences.navigate();
applicationBuilder.preferences.navigation.click("kubernetes");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when active repositories resolve", () => {
beforeEach(async () => {
await Promise.all([
getActiveHelmRepositoriesMock.resolve({
callWasSuccessful: true,
response: [
{ name: "Some active repository", url: "some-url" },
],
}),
]);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when selecting to add custom repository", () => {
beforeEach(() => {
const button = rendered.getByTestId("add-custom-helm-repo-button");
fireEvent.click(button);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("shows dialog", () => {
expect(
rendered.queryByTestId("add-custom-helm-repository-dialog"),
).toBeInTheDocument();
});
// TODO: Figure out how to close dialog by clicking outside of it
xdescribe("when closing the dialog by clicking outside", () => {
beforeEach(() => {});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show dialog anymore", () => {
expect(
rendered.queryByTestId("add-custom-helm-repository-dialog"),
).not.toBeInTheDocument();
});
});
describe("when closing the dialog by clicking cancel", () => {
beforeEach(() => {
const button = rendered.getByTestId("custom-helm-repository-cancel-button");
fireEvent.click(button);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show dialog anymore", () => {
expect(
rendered.queryByTestId("add-custom-helm-repository-dialog"),
).not.toBeInTheDocument();
});
});
describe("when inputted minimal options for the repository", () => {
beforeEach(() => {
getActiveHelmRepositoriesMock.mockClear();
const nameInput = rendered.getByTestId("custom-helm-repository-name-input");
fireEvent.change(nameInput, { target: { value: "some-custom-repository" }});
const urlInput = rendered.getByTestId("custom-helm-repository-url-input");
fireEvent.change(urlInput, { target: { value: "http://some.url" }});
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when submitted and some time passes", () => {
beforeEach(() => {
const submitButton = rendered.getByTestId("custom-helm-repository-submit-button");
fireEvent.click(submitButton);
// TODO: Remove when debounce is removed from WizardStep.submit
jest.runOnlyPendingTimers();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("adds the repository", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "add", "some-custom-repository", "http://some.url"],
);
});
it("does not reload active repositories yet", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
it("does not show notification yet", () => {
expect(showSuccessNotificationMock).not.toHaveBeenCalled();
});
describe("when activation rejects", () => {
beforeEach(async () => {
await execFileMock.reject(
"Some error",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Some error",
);
});
it("does not show success notification", () => {
expect(showSuccessNotificationMock).not.toHaveBeenCalled();
});
it("does not show dialog anymore", () => {
expect(rendered.queryByTestId("add-custom-helm-repository-dialog")).not.toBeInTheDocument();
});
it("does not reload active repositories", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
});
describe("when activation resolves with success", () => {
beforeEach(async () => {
await execFileMock.resolveSpecific(
[
"some-helm-binary-path",
["repo", "add", "some-custom-repository", "http://some.url"],
],
"",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show dialog anymore", () => {
expect(rendered.queryByTestId("add-custom-helm-repository-dialog")).not.toBeInTheDocument();
});
it("reloads active repositories", () => {
expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
});
it("shows success notification", () => {
expect(showSuccessNotificationMock).toHaveBeenCalledWith(
"Helm repository some-custom-repository has been added.",
);
});
describe("when adding custom repository again", () => {
beforeEach(() => {
const button = rendered.getByTestId("add-custom-helm-repo-button");
fireEvent.click(button);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("repository name is empty", () => {
const input = rendered.getByTestId("custom-helm-repository-name-input") as HTMLInputElement;
expect(input.value).toBe("");
});
it("repository url is empty", () => {
const input = rendered.getByTestId("custom-helm-repository-url-input") as HTMLInputElement;
expect(input.value).toBe("");
});
});
});
});
describe("when showing the maximal options", () => {
beforeEach(() => {
const button = rendered.getByTestId("toggle-maximal-options-for-custom-helm-repository-button");
fireEvent.click(button);
});
it("shows maximal options", () => {
const maximalOptions = rendered.getByTestId("maximal-options-for-custom-helm-repository-dialog");
expect(maximalOptions).toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("given closing the dialog, when reopening the dialog, still shows maximal options", () => {
const cancelButton = rendered.getByTestId("custom-helm-repository-cancel-button");
fireEvent.click(cancelButton);
const openButton = rendered.getByTestId("add-custom-helm-repo-button");
fireEvent.click(openButton);
const maximalOptions = rendered.getByTestId("maximal-options-for-custom-helm-repository-dialog");
expect(maximalOptions).toBeInTheDocument();
});
describe("when hiding maximal options", () => {
beforeEach(() => {
const button = rendered.getByTestId("toggle-maximal-options-for-custom-helm-repository-button");
fireEvent.click(button);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show maximal options anymore", () => {
const maximalOptions = rendered.queryByTestId("maximal-options-for-custom-helm-repository-dialog");
expect(maximalOptions).not.toBeInTheDocument();
});
});
describe("when inputted maximal options", () => {
beforeEach(async () => {
[
{ selector: "username-input", value: "some-username" },
{ selector: "password-input", value: "some-password" },
{ selector: "ca-cert-file-input", value: "some-ca-cert-file" },
{ selector: "cert-file-input", value: "some-cert-file" },
{ selector: "key-file-input", value: "some-key-file" },
].forEach(({ selector, value }) => {
const input = rendered.getByTestId(`custom-helm-repository-${selector}`);
fireEvent.change(input, { target: { value }});
});
const checkbox = rendered.getByTestId(`custom-helm-repository-verify-tls-input`);
fireEvent.click(checkbox);
jest.runOnlyPendingTimers();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("when submitted and some time passes, adds the repository with maximal options", () => {
const submitButton = rendered.getByTestId("custom-helm-repository-submit-button");
fireEvent.click(submitButton);
// TODO: Remove when debounce is removed from WizardStep.submit
jest.runOnlyPendingTimers();
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
[
"repo",
"add",
"some-custom-repository",
"http://some.url",
"--insecure-skip-tls-verify",
"--username",
"some-username",
"--password",
"some-password",
"--ca-file",
"some-ca-cert-file",
"--key-file",
"some-key-file",
"--cert-file",
"some-cert-file",
],
);
});
});
});
});
});
});
});
});
@@ -0,0 +1,273 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import execFileInjectable from "../../common/fs/exec-file.injectable";
import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable";
import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
import type { HelmRepo } from "../../common/helm/helm-repo";
import callForPublicHelmRepositoriesInjectable from "../../renderer/components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable";
import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable";
import type { AsyncResult } from "../../common/utils/async-result";
describe("add helm repository from list in preferences", () => {
let applicationBuilder: ApplicationBuilder;
let showSuccessNotificationMock: jest.Mock;
let showErrorNotificationMock: jest.Mock;
let rendered: RenderResult;
let execFileMock: AsyncFnMock<
ReturnType<typeof execFileInjectable["instantiate"]>
>;
let getActiveHelmRepositoriesMock: AsyncFnMock<() => Promise<AsyncResult<HelmRepo[]>>>;
let callForPublicHelmRepositoriesMock: AsyncFnMock<() => Promise<HelmRepo[]>>;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder();
execFileMock = asyncFn();
getActiveHelmRepositoriesMock = asyncFn();
callForPublicHelmRepositoriesMock = asyncFn();
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
showSuccessNotificationMock = jest.fn();
rendererDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock);
showErrorNotificationMock = jest.fn();
rendererDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock);
rendererDi.override(
callForPublicHelmRepositoriesInjectable,
() => callForPublicHelmRepositoriesMock,
);
mainDi.override(
getActiveHelmRepositoriesInjectable,
() => getActiveHelmRepositoriesMock,
);
mainDi.override(execFileInjectable, () => execFileMock);
mainDi.override(helmBinaryPathInjectable, () => "some-helm-binary-path");
});
rendered = await applicationBuilder.render();
});
describe("when navigating to preferences containing helm repositories", () => {
beforeEach(async () => {
applicationBuilder.preferences.navigate();
applicationBuilder.preferences.navigation.click("kubernetes");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("calls for public repositories", () => {
expect(callForPublicHelmRepositoriesMock).toHaveBeenCalled();
});
it("calls for active repositories", () => {
expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
});
describe("when both active and public repositories resolve", () => {
beforeEach(async () => {
await Promise.all([
callForPublicHelmRepositoriesMock.resolve([
{ name: "Some already active repository", url: "some-url" },
{ name: "Some to be added repository", url: "some-other-url" },
]),
getActiveHelmRepositoriesMock.resolve({
callWasSuccessful: true,
response: [
{ name: "Some already active repository", url: "some-url" },
],
}),
]);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when select for adding public repositories is clicked", () => {
beforeEach(() => {
applicationBuilder.select.openMenu(
"selection-of-active-public-helm-repository",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when deactive public repository is selected", () => {
beforeEach(async () => {
getActiveHelmRepositoriesMock.mockClear();
applicationBuilder.select.selectOption(
"selection-of-active-public-helm-repository",
"Some to be added repository",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("adds the repository", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "add", "Some to be added repository", "some-other-url"],
);
});
it("does not reload active repositories yet", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
describe("when adding rejects", () => {
beforeEach(async () => {
await execFileMock.reject(
"Some error",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Some error",
);
});
it("does not show success notification", () => {
expect(showSuccessNotificationMock).not.toHaveBeenCalled();
});
it("does not show dialog anymore", () => {
expect(rendered.queryByTestId("add-custom-helm-repository-dialog")).not.toBeInTheDocument();
});
it("does not reload active repositories", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
});
describe("when adding resolves", () => {
beforeEach(async () => {
await execFileMock.resolveSpecific(
[
"some-helm-binary-path",
["repo", "add", "Some to be added repository", "some-other-url"],
],
"",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("reloads active repositories", () => {
expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
});
it("shows success notification", () => {
expect(showSuccessNotificationMock).toHaveBeenCalledWith(
"Helm repository Some to be added repository has been added.",
);
});
describe("when active repositories resolve again", () => {
beforeEach(async () => {
await getActiveHelmRepositoriesMock.resolve({
callWasSuccessful: true,
response: [
{ name: "Some already active repository", url: "some-url" },
{ name: "Some to be added repository", url: "some-other-url" },
],
});
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when select for selecting active repositories is clicked", () => {
beforeEach(() => {
applicationBuilder.select.openMenu(
"selection-of-active-public-helm-repository",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when active repository is selected", () => {
beforeEach(() => {
execFileMock.mockClear();
getActiveHelmRepositoriesMock.mockClear();
applicationBuilder.select.selectOption(
"selection-of-active-public-helm-repository",
"Some already active repository",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("removes the repository", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "remove", "Some already active repository"],
);
});
it("does not reload active repositories yet", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
describe("when removing resolves", () => {
beforeEach(async () => {
await execFileMock.resolveSpecific(
[
"some-helm-binary-path",
["repo", "remove", "Some already active repository"],
],
"",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("reloads active repositories", () => {
expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
});
});
});
});
});
});
});
});
});
});
});
@@ -0,0 +1,255 @@
/**
* 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 { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
import { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api";
import getRandomInstallChartTabIdInjectable from "../../../renderer/components/dock/install-chart/get-random-install-chart-tab-id.injectable";
import type { CallForHelmChartValues } from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable";
import callForHelmChartValuesInjectable from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable";
import namespaceStoreInjectable from "../../../renderer/components/+namespaces/store.injectable";
import type { NamespaceStore } from "../../../renderer/components/+namespaces/store";
import type { CallForHelmChartVersions } from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable";
import callForHelmChartVersionsInjectable from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable";
import { overrideFsWithFakes } from "../../../test-utils/override-fs-with-fakes";
import writeJsonFileInjectable from "../../../common/fs/write-json-file.injectable";
import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable";
import { TabKind } from "../../../renderer/components/dock/dock/store";
import { controlWhenStoragesAreReady } from "../../../renderer/utils/create-storage/storages-are-ready";
import type { DiContainer } from "@ogre-tools/injectable";
import callForCreateHelmReleaseInjectable from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable";
describe("installing helm chart from previously opened tab", () => {
let builder: ApplicationBuilder;
let rendererDi: DiContainer;
let callForHelmChartVersionsMock: AsyncFnMock<CallForHelmChartVersions>;
let callForHelmChartValuesMock: AsyncFnMock<CallForHelmChartValues>;
let storagesAreReady: () => Promise<void>;
beforeEach(() => {
builder = getApplicationBuilder();
rendererDi = builder.dis.rendererDi;
overrideFsWithFakes(rendererDi);
callForHelmChartVersionsMock = asyncFn();
callForHelmChartValuesMock = asyncFn();
builder.beforeApplicationStart(({ rendererDi }) => {
rendererDi.override(
directoryForLensLocalStorageInjectable,
() => "/some-directory-for-lens-local-storage",
);
rendererDi.override(hostedClusterIdInjectable, () => "some-cluster-id");
storagesAreReady = controlWhenStoragesAreReady(rendererDi);
rendererDi.override(
callForHelmChartVersionsInjectable,
() => callForHelmChartVersionsMock,
);
rendererDi.override(
callForHelmChartValuesInjectable,
() => callForHelmChartValuesMock,
);
rendererDi.override(
callForHelmChartValuesInjectable,
() => callForHelmChartValuesMock,
);
rendererDi.override(
callForCreateHelmReleaseInjectable,
() => jest.fn(),
);
// TODO: Replace store mocking with mock for the actual side-effect (where the namespaces are coming from)
rendererDi.override(
namespaceStoreInjectable,
() =>
({
contextNamespaces: [],
items: [
{ getName: () => "default" },
{ getName: () => "some-other-namespace" },
],
selectNamespaces: () => {},
} as unknown as NamespaceStore),
);
rendererDi.override(getRandomInstallChartTabIdInjectable, () =>
jest
.fn(() => "some-irrelevant-tab-id")
.mockReturnValueOnce("some-first-tab-id"),
);
});
builder.setEnvironmentToClusterFrame();
});
describe("given tab for installing chart was previously opened, when application is started", () => {
let rendered: RenderResult;
beforeEach(async () => {
const writeJsonFile = rendererDi.inject(writeJsonFileInjectable);
writeJsonFile(
"/some-directory-for-lens-local-storage/some-cluster-id.json",
{
dock: {
height: 300,
tabs: [
{
id: "some-first-tab-id",
kind: TabKind.INSTALL_CHART,
title: "Helm Install: some-repository/some-name",
pinned: false,
},
],
isOpen: true,
},
install_charts: {
"some-first-tab-id": {
name: "some-name",
repo: "some-repository",
version: "some-other-version",
values: "some-stored-configuration",
releaseName: "some-stored-custom-name",
namespace: "some-other-namespace",
},
},
},
);
rendered = await builder.render();
await storagesAreReady();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("still has the dock tab for installing chart", () => {
expect(
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
).toBeInTheDocument();
});
it("shows dock tab for installing the chart", () => {
expect(
rendered.getByTestId("dock-tab-content-for-some-first-tab-id"),
).toBeInTheDocument();
});
it("shows spinner in dock tab", () => {
expect(
rendered.getByTestId("install-chart-tab-spinner"),
).toBeInTheDocument();
});
it("calls for default configuration of the chart", () => {
expect(callForHelmChartValuesMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
"some-other-version",
);
});
it("calls for available versions", () => {
expect(callForHelmChartVersionsMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
);
});
describe("when configuration and version resolves", () => {
beforeEach(async () => {
await callForHelmChartValuesMock.resolve(
"some-default-configuration",
);
await callForHelmChartVersionsMock.resolve([
HelmChart.create({
apiVersion: "some-api-version",
name: "some-name",
version: "some-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
HelmChart.create({
apiVersion: "some-api-version",
name: "some-name",
version: "some-other-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
]);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("has the stored configuration", () => {
const input = rendered.getByTestId(
"monaco-editor-for-some-first-tab-id",
);
expect(input).toHaveValue("some-stored-configuration");
});
it("has the stored custom name", () => {
const input = rendered.getByTestId(
"install-chart-custom-name-input-for-some-first-tab-id",
);
expect(input).toHaveValue("some-stored-custom-name");
});
it("has the stored version", () => {
const actual = builder.select.getValue(
"install-chart-version-select-for-some-first-tab-id",
);
expect(actual).toBe("some-other-version");
});
it("has the stored namespace", () => {
const actual = builder.select.getValue(
"install-chart-namespace-select-for-some-first-tab-id",
);
expect(actual).toBe("some-other-namespace");
});
});
});
});
@@ -0,0 +1,356 @@
/**
* 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 { RenderResult } from "@testing-library/react";
import { fireEvent } from "@testing-library/react";
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
import type { CallForHelmCharts } from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable";
import callForHelmChartsInjectable from "../../../renderer/components/+helm-charts/helm-charts/call-for-helm-charts.injectable";
import { HelmChart } from "../../../common/k8s-api/endpoints/helm-charts.api";
import getRandomInstallChartTabIdInjectable from "../../../renderer/components/dock/install-chart/get-random-install-chart-tab-id.injectable";
import callForHelmChartValuesInjectable from "../../../renderer/components/dock/install-chart/chart-data/call-for-helm-chart-values.injectable";
import callForCreateHelmReleaseInjectable from "../../../renderer/components/+helm-releases/create-release/call-for-create-helm-release.injectable";
import type { CallForHelmChartReadme } from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable";
import callForHelmChartReadmeInjectable from "../../../renderer/components/+helm-charts/details/readme/call-for-helm-chart-readme.injectable";
import type { CallForHelmChartVersions } from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable";
import callForHelmChartVersionsInjectable from "../../../renderer/components/+helm-charts/details/versions/call-for-helm-chart-versions.injectable";
import { flushPromises } from "../../../common/test-utils/flush-promises";
import { overrideFsWithFakes } from "../../../test-utils/override-fs-with-fakes";
import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable";
import dockStoreInjectable from "../../../renderer/components/dock/dock/store.injectable";
import type { DiContainer } from "@ogre-tools/injectable";
describe("opening dock tab for installing helm chart", () => {
let builder: ApplicationBuilder;
let rendererDi: DiContainer;
let callForHelmChartsMock: AsyncFnMock<CallForHelmCharts>;
let callForHelmChartVersionsMock: AsyncFnMock<CallForHelmChartVersions>;
let callForHelmChartReadmeMock: AsyncFnMock<CallForHelmChartReadme>;
let callForHelmChartValuesMock: jest.Mock;
beforeEach(() => {
builder = getApplicationBuilder();
rendererDi = builder.dis.rendererDi;
overrideFsWithFakes(rendererDi);
callForHelmChartsMock = asyncFn();
callForHelmChartVersionsMock = asyncFn();
callForHelmChartReadmeMock = asyncFn();
callForHelmChartValuesMock = jest.fn();
builder.beforeApplicationStart(({ rendererDi }) => {
rendererDi.override(
directoryForLensLocalStorageInjectable,
() => "/some-directory-for-lens-local-storage",
);
rendererDi.override(hostedClusterIdInjectable, () => "some-cluster-id");
rendererDi.override(
callForHelmChartsInjectable,
() => callForHelmChartsMock,
);
rendererDi.override(
callForHelmChartVersionsInjectable,
() => callForHelmChartVersionsMock,
);
rendererDi.override(
callForHelmChartReadmeInjectable,
() => callForHelmChartReadmeMock,
);
rendererDi.override(
callForHelmChartValuesInjectable,
() => callForHelmChartValuesMock,
);
rendererDi.override(
callForCreateHelmReleaseInjectable,
() => jest.fn(),
);
rendererDi.override(getRandomInstallChartTabIdInjectable, () =>
jest
.fn(() => "some-irrelevant-tab-id")
.mockReturnValueOnce("some-tab-id"),
);
});
builder.setEnvironmentToClusterFrame();
});
describe("given application is started, when navigating to helm charts", () => {
let rendered: RenderResult;
beforeEach(async () => {
rendered = await builder.render();
builder.helmCharts.navigate();
const dockStore = rendererDi.inject(dockStoreInjectable);
// TODO: Make TerminalWindow unit testable to allow realistic behaviour
dockStore.closeTab("terminal");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("calls for charts", () => {
expect(callForHelmChartsMock).toHaveBeenCalled();
});
describe("when charts resolve", () => {
beforeEach(async () => {
await callForHelmChartsMock.resolve([
HelmChart.create({
apiVersion: "some-api-version",
name: "some-name",
version: "some-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
HelmChart.create({
apiVersion: "some-api-version",
name: "some-other-name",
version: "some-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
]);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when opening details of a chart", () => {
beforeEach(() => {
const row = rendered.getByTestId(
"helm-chart-row-for-some-repository-some-name",
);
fireEvent.click(row);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("calls for chart versions", () => {
expect(callForHelmChartVersionsMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
);
});
it("shows spinner", () => {
expect(
rendered.getByTestId("spinner-for-chart-details"),
).toBeInTheDocument();
});
describe("when chart versions resolve", () => {
beforeEach(async () => {
await callForHelmChartVersionsMock.resolve([
HelmChart.create({
apiVersion: "some-api-version",
name: "some-name",
version: "some-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
HelmChart.create({
apiVersion: "some-api-version",
name: "some-name",
version: "some-other-version",
repo: "some-repository",
created: "2015-10-21T07:28:00Z",
description: "some-description",
keywords: [],
sources: [],
urls: [],
annotations: {},
dependencies: [],
maintainers: [],
deprecated: false,
}),
]);
});
it("calls for chart readme for the version", () => {
expect(callForHelmChartReadmeMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
"some-version",
);
});
it("has the latest version as selected", () => {
const actual = builder.select.getValue(
"helm-chart-version-selector-some-repository-some-name",
);
expect(actual).toBe("some-version");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not shows spinner for details", () => {
expect(
rendered.queryByTestId("spinner-for-chart-details"),
).not.toBeInTheDocument();
});
it("shows spinner for readme", () => {
expect(
rendered.getByTestId("spinner-for-chart-readme"),
).toBeInTheDocument();
});
describe("when readme resolves", () => {
beforeEach(async () => {
await callForHelmChartReadmeMock.resolve("some-readme");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show spinner anymore", () => {
expect(
rendered.queryByTestId("spinner-for-chart-readme"),
).not.toBeInTheDocument();
});
describe("when selecting different version", () => {
beforeEach(() => {
callForHelmChartReadmeMock.mockClear();
builder.select
.openMenu(
"helm-chart-version-selector-some-repository-some-name",
)
.selectOption("some-other-version");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("selects the version", () => {
const actual = builder.select.getValue(
"helm-chart-version-selector-some-repository-some-name",
);
expect(actual).toBe("some-other-version");
});
it("calls for chart readme for the version", () => {
expect(callForHelmChartReadmeMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
"some-other-version",
);
});
describe("when readme resolves", () => {
beforeEach(async () => {
await callForHelmChartReadmeMock.resolve("some-readme");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("when selecting to install chart, calls for the default configuration of the chart with specific version", async () => {
const installButton = rendered.getByTestId(
"install-chart-for-some-repository-some-name",
);
fireEvent.click(installButton);
await flushPromises();
expect(callForHelmChartValuesMock).toHaveBeenCalledWith(
"some-repository",
"some-name",
"some-other-version",
);
});
});
});
describe("when selecting to install the chart", () => {
beforeEach(() => {
callForHelmChartVersionsMock.mockClear();
const installButton = rendered.getByTestId(
"install-chart-for-some-repository-some-name",
);
fireEvent.click(installButton);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("has the dock tab for installing chart", () => {
expect(
rendered.getByTestId("dock-tab-for-some-tab-id"),
).toBeInTheDocument();
});
it("shows dock tab for installing chart", () => {
expect(
rendered.getByTestId(
"dock-tab-content-for-some-tab-id",
),
).toBeInTheDocument();
});
});
});
});
});
});
});
});
@@ -0,0 +1,453 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { ReadYamlFile } from "../../common/fs/read-yaml-file.injectable";
import readYamlFileInjectable from "../../common/fs/read-yaml-file.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { HelmRepositoriesFromYaml } from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
import execFileInjectable from "../../common/fs/exec-file.injectable";
import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable";
import loggerInjectable from "../../common/logger.injectable";
import type { Logger } from "../../common/logger";
import callForPublicHelmRepositoriesInjectable from "../../renderer/components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable";
describe("listing active helm repositories in preferences", () => {
let applicationBuilder: ApplicationBuilder;
let rendered: RenderResult;
let readYamlFileMock: AsyncFnMock<ReadYamlFile>;
let execFileMock: AsyncFnMock<ReturnType<typeof execFileInjectable["instantiate"]>>;
let loggerStub: Logger;
let showErrorNotificationMock: jest.Mock;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder();
readYamlFileMock = asyncFn();
execFileMock = asyncFn();
loggerStub = { error: jest.fn() } as unknown as Logger;
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
showErrorNotificationMock = jest.fn();
rendererDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock);
rendererDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []);
mainDi.override(readYamlFileInjectable, () => readYamlFileMock);
mainDi.override(execFileInjectable, () => execFileMock);
mainDi.override(helmBinaryPathInjectable, () => "some-helm-binary-path");
mainDi.override(loggerInjectable, () => loggerStub);
});
rendered = await applicationBuilder.render();
});
describe("when navigating to preferences containing helm repositories", () => {
beforeEach(async () => {
applicationBuilder.preferences.navigate();
applicationBuilder.preferences.navigation.click("kubernetes");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("shows loader for repositories", () => {
expect(
rendered.getByTestId("helm-repositories-are-loading"),
).toBeInTheDocument();
});
it("calls for helm configuration", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["env"],
);
});
it("does not call for updating of repositories yet", () => {
expect(execFileMock).not.toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "update"],
);
});
describe("when getting configuration rejects", () => {
beforeEach(async () => {
await execFileMock.reject("some-error");
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Error getting Helm configuration: some-error",
);
});
it("removes all helm controls", () => {
expect(
rendered.queryByTestId("helm-controls"),
).not.toBeInTheDocument();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when configuration resolves without path to repository config file", () => {
beforeEach(async () => {
execFileMock.mockClear();
await execFileMock.resolveSpecific(
["some-helm-binary-path", ["env"]],
"HELM_REPOSITORY_CACHE=some-helm-repository-cache-path",
);
});
it("logs error", () => {
expect(loggerStub.error).toHaveBeenCalledWith(
"Tried to get Helm repositories, but HELM_REPOSITORY_CONFIG was not present in `$ helm env`.",
);
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Error getting Helm configuration: Tried to get Helm repositories, but HELM_REPOSITORY_CONFIG was not present in `$ helm env`.",
);
});
it("removes all helm controls", () => {
expect(
rendered.queryByTestId("helm-controls"),
).not.toBeInTheDocument();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when configuration resolves without path to repository cache directory", () => {
beforeEach(async () => {
execFileMock.mockClear();
await execFileMock.resolveSpecific(
["some-helm-binary-path", ["env"]],
"HELM_REPOSITORY_CONFIG=some-helm-repository-config-file.yaml",
);
});
it("logs error", () => {
expect(loggerStub.error).toHaveBeenCalledWith(
"Tried to get Helm repositories, but HELM_REPOSITORY_CACHE was not present in `$ helm env`.",
);
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Error getting Helm configuration: Tried to get Helm repositories, but HELM_REPOSITORY_CACHE was not present in `$ helm env`.",
);
});
it("removes all helm controls", () => {
expect(
rendered.queryByTestId("helm-controls"),
).not.toBeInTheDocument();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when configuration resolves", () => {
beforeEach(async () => {
execFileMock.mockClear();
await execFileMock.resolveSpecific(
["some-helm-binary-path", ["env"]],
[
"HELM_REPOSITORY_CONFIG=some-helm-repository-config-file.yaml",
"HELM_REPOSITORY_CACHE=some-helm-repository-cache-path",
].join("\n"),
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("calls for update of repositories", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "update"],
);
});
it("does not call for repositories yet", () => {
expect(readYamlFileMock).not.toHaveBeenCalled();
});
describe("when updating repositories reject with any other error", () => {
beforeEach(async () => {
await execFileMock.reject("Some error");
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Error updating Helm repositories: Some error",
);
});
it("removes all helm controls", () => {
expect(
rendered.queryByTestId("helm-controls"),
).not.toBeInTheDocument();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when updating repositories reject with error about no existing repositories", () => {
beforeEach(async () => {
execFileMock.mockClear();
await execFileMock.reject(
"Error: no repositories found. You must add one before updating",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("still shows the loader for repositories", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).toBeInTheDocument();
});
it('adds "bitnami" as default repository', () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "add", "bitnami", "https://charts.bitnami.com/bitnami"],
);
});
describe("when adding default repository reject", () => {
beforeEach(async () => {
await execFileMock.reject("Some error");
});
it("shows error notification", () => {
expect(showErrorNotificationMock).toHaveBeenCalledWith(
"Error when adding default Helm repository: Some error",
);
});
it("removes all helm controls", () => {
expect(
rendered.queryByTestId("helm-controls"),
).not.toBeInTheDocument();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when adding of default repository resolves", () => {
beforeEach(async () => {
readYamlFileMock.mockClear();
await execFileMock.resolveSpecific(
[
"some-helm-binary-path",
[
"repo",
"add",
"bitnami",
"https://charts.bitnami.com/bitnami",
],
],
"",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("still shows the loader for repositories", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).toBeInTheDocument();
});
it("calls for repositories again", () => {
expect(readYamlFileMock).toHaveBeenCalledWith(
"some-helm-repository-config-file.yaml",
);
});
describe("when another call for repositories resolve", () => {
beforeEach(async () => {
await readYamlFileMock.resolveSpecific(
["some-helm-repository-config-file.yaml"],
{
repositories: [
{
name: "bitnami",
url: "https://charts.bitnami.com/bitnami",
caFile: "irrelevant",
certFile: "irrelevant",
insecure_skip_tls_verify: false,
keyFile: "irrelevant",
pass_credentials_all: false,
password: "irrelevant",
username: "irrelevant",
},
],
},
);
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("shows the added repository", () => {
const actual = rendered.getByTestId("helm-repository-bitnami");
expect(actual).toBeInTheDocument();
});
});
});
});
describe("when updating repositories resolve", () => {
beforeEach(async () => {
execFileMock.mockClear();
await execFileMock.resolveSpecific(
["some-helm-binary-path", ["repo", "update"]],
"",
);
});
it("loads repositories from file system", () => {
expect(readYamlFileMock).toHaveBeenCalledWith(
"some-helm-repository-config-file.yaml",
);
});
describe("when repositories resolves", () => {
beforeEach(async () => {
execFileMock.mockClear();
await readYamlFileMock.resolveSpecific(
["some-helm-repository-config-file.yaml"],
repositoryConfigStub,
);
});
it("does not add default repository", () => {
expect(execFileMock).not.toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "add", "bitnami", "https://charts.bitnami.com/bitnami"],
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show loader for repositories anymore", () => {
expect(
rendered.queryByTestId("helm-repositories-are-loading"),
).not.toBeInTheDocument();
});
it("shows repositories in use", () => {
const actual = rendered.getAllByTestId(
/^helm-repository-(some-repository|some-other-repository)$/,
);
expect(actual).toHaveLength(2);
});
});
});
});
});
});
const repositoryConfigStub: HelmRepositoriesFromYaml = {
repositories: [
{
name: "some-repository",
url: "some-repository-url",
caFile: "irrelevant",
certFile: "irrelevant",
insecure_skip_tls_verify: false,
keyFile: "irrelevant",
pass_credentials_all: false,
password: "irrelevant",
username: "irrelevant",
},
{
name: "some-other-repository",
url: "some-other-repository-url",
caFile: "irrelevant",
certFile: "irrelevant",
insecure_skip_tls_verify: false,
keyFile: "irrelevant",
pass_credentials_all: false,
password: "irrelevant",
username: "irrelevant",
},
],
};
@@ -0,0 +1,121 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import { fireEvent } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import execFileInjectable from "../../common/fs/exec-file.injectable";
import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable";
import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
import type { HelmRepo } from "../../common/helm/helm-repo";
import callForPublicHelmRepositoriesInjectable from "../../renderer/components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
import type { AsyncResult } from "../../common/utils/async-result";
describe("remove helm repository from list of active repositories in preferences", () => {
let applicationBuilder: ApplicationBuilder;
let rendered: RenderResult;
let getActiveHelmRepositoriesMock: AsyncFnMock<() => Promise<AsyncResult<HelmRepo[]>>>;
let execFileMock: AsyncFnMock<
ReturnType<typeof execFileInjectable["instantiate"]>
>;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder();
execFileMock = asyncFn();
getActiveHelmRepositoriesMock = asyncFn();
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
rendererDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []);
mainDi.override(
getActiveHelmRepositoriesInjectable,
() => getActiveHelmRepositoriesMock,
);
mainDi.override(execFileInjectable, () => execFileMock);
mainDi.override(helmBinaryPathInjectable, () => "some-helm-binary-path");
});
rendered = await applicationBuilder.render();
});
describe("when navigating to preferences containing helm repositories", () => {
beforeEach(async () => {
applicationBuilder.preferences.navigate();
applicationBuilder.preferences.navigation.click("kubernetes");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when active repositories resolve", () => {
beforeEach(async () => {
getActiveHelmRepositoriesMock.resolve({
callWasSuccessful: true,
response: [
{ name: "some-active-repository", url: "some-url" },
],
});
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when removing repository", () => {
beforeEach(() => {
execFileMock.mockClear();
getActiveHelmRepositoriesMock.mockClear();
const removeButton = rendered.getByTestId(
"remove-helm-repository-some-active-repository",
);
fireEvent.click(removeButton);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("removes the repository", () => {
expect(execFileMock).toHaveBeenCalledWith(
"some-helm-binary-path",
["repo", "remove", "some-active-repository"],
);
});
it("does not reload active repositories yet", () => {
expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
});
describe("when removing resolves", () => {
beforeEach(async () => {
await execFileMock.resolveSpecific(
[
"some-helm-binary-path",
["repo", "remove", "some-active-repository"],
],
"",
);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("reloads active repositories", () => {
expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
});
});
});
});
});
});