/**
 * 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 { 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 { RequestCreateHelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api/request-create.injectable";
import requestCreateHelmReleaseInjectable from "../../../common/k8s-api/endpoints/helm-releases.api/request-create.injectable";
import currentPathInjectable from "../../../renderer/routes/current-path.injectable";
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 dockStoreInjectable from "../../../renderer/components/dock/dock/store.injectable";
import readJsonFileInjectable from "../../../common/fs/read-json-file.injectable";
import type { DiContainer } from "@ogre-tools/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 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 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 { flushPromises } from "@k8slens/test-utils";

describe("installing helm chart from new tab", () => {
  let builder: ApplicationBuilder;
  let requestDetailedHelmReleaseMock: AsyncFnMock<RequestDetailedHelmRelease>;
  let requestHelmChartsMock: AsyncFnMock<RequestHelmCharts>;
  let requestHelmChartVersionsMock: AsyncFnMock<RequestHelmChartVersions>;
  let requestHelmChartReadmeMock: AsyncFnMock<RequestHelmChartReadme>;
  let requestHelmChartValuesMock: AsyncFnMock<RequestHelmChartValues>;
  let requestCreateHelmReleaseMock: AsyncFnMock<RequestCreateHelmRelease>;
  let requestHelmReleasesMock: AsyncFnMock<RequestHelmReleases>;

  beforeEach(() => {
    builder = getApplicationBuilder();

    builder.setEnvironmentToClusterFrame();

    requestDetailedHelmReleaseMock = asyncFn();
    requestHelmChartsMock = asyncFn();
    requestHelmChartVersionsMock = asyncFn();
    requestHelmChartReadmeMock = asyncFn();
    requestHelmChartValuesMock = asyncFn();
    requestCreateHelmReleaseMock = asyncFn();
    requestHelmReleasesMock = asyncFn();

    builder.beforeWindowStart(({ windowDi }) => {
      windowDi.override(directoryForLensLocalStorageInjectable, () => "/some-directory-for-lens-local-storage");
      windowDi.override(requestDetailedHelmReleaseInjectable, () => requestDetailedHelmReleaseMock);
      windowDi.override(requestHelmChartsInjectable, () => requestHelmChartsMock);
      windowDi.override(requestHelmChartVersionsInjectable, () => requestHelmChartVersionsMock);
      windowDi.override(requestHelmChartReadmeInjectable, () => requestHelmChartReadmeMock);
      windowDi.override(requestHelmChartValuesInjectable, () => requestHelmChartValuesMock);
      windowDi.override(requestCreateHelmReleaseInjectable, () => requestCreateHelmReleaseMock);
      windowDi.override(requestHelmReleasesInjectable, () => requestHelmReleasesMock);

      windowDi.override(getRandomInstallChartTabIdInjectable, () =>
        jest
          .fn(() => "some-irrelevant-tab-id")
          .mockReturnValueOnce("some-first-tab-id")
          .mockReturnValueOnce("some-second-tab-id"),
      );
    });

    builder.namespaces.add("default");
    builder.namespaces.add("some-other-namespace");
  });

  describe("given tab for installing chart was not previously opened and application is started", () => {
    let rendered: RenderResult;
    let windowDi: DiContainer;

    beforeEach(async () => {
      rendered = await builder.render();

      windowDi = builder.applicationWindow.only.di;

      const writeJsonFile = windowDi.inject(writeJsonFileInjectable);

      await writeJsonFile(
        "/some-directory-for-lens-local-storage/some-cluster-id.json",
        {
          dock: {
            height: 300,
            tabs: [],
            isOpen: false,
          },
        },
      );

      const dockStore = windowDi.inject(dockStoreInjectable);

      // TODO: Make TerminalWindow unit testable to allow realistic behaviour
      dockStore.closeTab("terminal");
    });

    it("renders", () => {
      expect(rendered.baseElement).toMatchSnapshot();
    });

    describe("when navigating to helm charts", () => {
      beforeEach(async () => {
        builder.helmCharts.navigate({
          chartName: "some-name",
          repo: "some-repository",
        });

        await requestHelmChartsMock.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,
          }),
        ]);

        await requestHelmChartVersionsMock.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,
          }),
        ]);

        await requestHelmChartReadmeMock.resolve({
          callWasSuccessful: true,
          response: "some-readme",
        });
      });

      it("renders", () => {
        expect(rendered.baseElement).toMatchSnapshot();
      });

      describe("when selecting to install the chart", () => {
        beforeEach(() => {
          requestHelmChartVersionsMock.mockClear();

          const installButton = rendered.getByTestId(
            "install-chart-for-some-repository-some-name",
          );

          fireEvent.click(installButton);
        });

        it("renders", () => {
          expect(rendered.baseElement).toMatchSnapshot();
        });

        it("shows dock tab for installing the chart", () => {
          expect(
            rendered.getByTestId("dock-tab-content-for-some-first-tab-id"),
          ).toBeInTheDocument();
        });

        it("calls for default configuration of the chart", () => {
          expect(requestHelmChartValuesMock).toHaveBeenCalledWith(
            "some-repository",
            "some-name",
            "some-version",
          );
        });

        it("calls for available versions", () => {
          expect(requestHelmChartVersionsMock).toHaveBeenCalledWith(
            "some-repository",
            "some-name",
          );
        });

        it("shows spinner in dock tab", () => {
          expect(
            rendered.getByTestId("install-chart-tab-spinner"),
          ).toBeInTheDocument();
        });

        it("given versions resolve but default configuration has not resolved yet, still shows the spinner", async () => {
          await requestHelmChartVersionsMock.resolve([]);

          expect(
            rendered.getByTestId("install-chart-tab-spinner"),
          ).toBeInTheDocument();
        });

        describe("when default configuration and versions resolve", () => {
          beforeEach(async () => {
            await requestHelmChartValuesMock.resolve({
              callWasSuccessful: true,
              response: "some-default-configuration",
            });

            await requestHelmChartVersionsMock.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("does not show spinner anymore", () => {
            expect(
              rendered.queryByTestId("install-chart-tab-spinner"),
            ).not.toBeInTheDocument();
          });

          describe("when cancelled", () => {
            beforeEach(() => {
              const cancelButton = rendered.getByTestId(
                "cancel-install-chart-from-tab-for-some-first-tab-id",
              );

              fireEvent.click(cancelButton);
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            it("closes the tab", () => {
              expect(
                rendered.queryByTestId("dock-tab-for-some-first-tab-id"),
              ).not.toBeInTheDocument();
            });
          });

          describe("given no changes in configuration, when installing the chart", () => {
            let installButton: HTMLButtonElement;

            beforeEach(() => {
              installButton = rendered.getByTestId(
                "install-chart-from-tab-for-some-first-tab-id",
              ) as HTMLButtonElement;

              fireEvent.click(installButton);
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            it("shows spinner in dock tab", () => {
              expect(
                rendered.getByTestId(
                  "installing-chart-from-tab-some-first-tab-id",
                ),
              ).toBeInTheDocument();
            });

            it("install button is disabled", () => {
              expect(installButton).toHaveAttribute("disabled");
            });

            it("calls for installation with default configuration", () => {
              expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({
                chart: "some-name",
                name: undefined,
                namespace: "default",
                repo: "some-repository",
                values: "some-default-configuration",
                version: "some-version",
              });
            });

            describe("when installation resolves", () => {
              beforeEach(async () => {
                await requestCreateHelmReleaseMock.resolve({
                  log: "some-execution-output",

                  release: {
                    resources: [],
                    name: "some-release",
                    namespace: "default",
                    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",
                    },
                  },
                });
              });

              it("renders", () => {
                expect(rendered.baseElement).toMatchSnapshot();
              });

              it("does not show spinner anymore", () => {
                expect(
                  rendered.queryByTestId(
                    "installing-chart-from-tab-some-first-tab-id",
                  ),
                ).not.toBeInTheDocument();
              });

              describe("when selected to see the installed release", () => {
                beforeEach(async () => {
                  const releaseButton = rendered.getByTestId(
                    "show-release-some-release-for-some-first-tab-id",
                  );

                  fireEvent.click(releaseButton);

                  await flushPromises();
                  await requestHelmReleasesMock.resolve([]);
                });

                it("renders", () => {
                  expect(rendered.baseElement).toMatchSnapshot();
                });

                it("shows the details of installed release", () => {
                  const currentPath = windowDi
                    .inject(currentPathInjectable)
                    .get();

                  expect(currentPath).toBe(
                    "/helm/releases/default/some-release",
                  );
                });

                it("closes the dock tab", () => {
                  expect(
                    rendered.queryByTestId(
                      "dock-tab-for-some-first-tab-id",
                    ),
                  ).not.toBeInTheDocument();
                });
              });

              describe("when selected to show execution output", () => {
                beforeEach(() => {
                  const showNotesButton = rendered.getByTestId(
                    "show-execution-output-for-some-release-in-some-first-tab-id",
                  );

                  fireEvent.click(showNotesButton);
                });

                it("renders", () => {
                  expect(rendered.baseElement).toMatchSnapshot();
                });

                it("shows the execution output", () => {
                  expect(
                    rendered.getByTestId(
                      "logs-dialog-for-helm-chart-install",
                    ),
                  ).toHaveTextContent("some-execution-output");
                });

                it("does not close the dock tab", () => {
                  expect(
                    rendered.getByTestId("dock-tab-for-some-first-tab-id"),
                  ).toBeInTheDocument();
                });
              });
            });
          });

          describe("given opening details for second chart, when details resolve", () => {
            beforeEach(async () => {
              requestHelmChartReadmeMock.mockClear();
              requestHelmChartVersionsMock.mockClear();

              const row = rendered.getByTestId(
                "helm-chart-row-for-some-repository-some-other-name",
              );

              fireEvent.click(row);

              await requestHelmChartVersionsMock.resolve([
                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,
                }),
              ]);

              await requestHelmChartReadmeMock.resolve({
                callWasSuccessful: true,
                response: "some-readme",
              });
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            describe("when selecting to install second chart", () => {
              beforeEach(() => {
                requestHelmChartVersionsMock.mockClear();

                const installButton = rendered.getByTestId(
                  "install-chart-for-some-repository-some-other-name",
                );

                fireEvent.click(installButton);
              });

              it("renders", () => {
                expect(rendered.baseElement).toMatchSnapshot();
              });

              it("shows dock tab for installing second chart", () => {
                expect(
                  rendered.getByTestId(
                    "dock-tab-content-for-some-second-tab-id",
                  ),
                ).toBeInTheDocument();
              });

              it("still has the dock tab for installing first chart", () => {
                expect(
                  rendered.getByTestId("dock-tab-for-some-first-tab-id"),
                ).toBeInTheDocument();
              });

              it("calls for default configuration of the second chart", () => {
                expect(requestHelmChartValuesMock).toHaveBeenCalledWith(
                  "some-repository",
                  "some-other-name",
                  "some-version",
                );
              });

              it("calls for available versions for the second chart", () => {
                expect(requestHelmChartVersionsMock).toHaveBeenCalledWith(
                  "some-repository",
                  "some-other-name",
                );
              });

              it("shows spinner in dock tab", () => {
                expect(
                  rendered.getByTestId("install-chart-tab-spinner"),
                ).toBeInTheDocument();
              });

              describe("when configuration and versions resolve", () => {
                beforeEach(async () => {
                  await requestHelmChartValuesMock.resolve({
                    callWasSuccessful: true,
                    response: "some-other-default-configuration",
                  });

                  await requestHelmChartVersionsMock.resolve([]);
                });

                it("renders", () => {
                  expect(rendered.baseElement).toMatchSnapshot();
                });

                it("does not show spinner anymore", () => {
                  expect(
                    rendered.queryByTestId("install-chart-tab-spinner"),
                  ).not.toBeInTheDocument();
                });

                it("when installing the second chart, calls for installation of second chart", () => {
                  const installButton = rendered.getByTestId(
                    "install-chart-from-tab-for-some-second-tab-id",
                  );

                  fireEvent.click(installButton);

                  expect(
                    requestCreateHelmReleaseMock,
                  ).toHaveBeenCalledWith({
                    chart: "some-other-name",
                    name: undefined,
                    namespace: "default",
                    repo: "some-repository",
                    values: "some-other-default-configuration",
                    version: "some-version",
                  });
                });

                describe("when selecting the dock tab for installing first chart", () => {
                  beforeEach(() => {
                    requestHelmChartValuesMock.mockClear();
                    requestHelmChartVersionsMock.mockClear();

                    const tab = rendered.getByTestId(
                      "dock-tab-for-some-first-tab-id",
                    );

                    fireEvent.click(tab);
                  });

                  it("renders", () => {
                    expect(rendered.baseElement).toMatchSnapshot();
                  });

                  it("does not call for default configuration", () => {
                    expect(
                      requestHelmChartValuesMock,
                    ).not.toHaveBeenCalled();
                  });

                  it("does not call for available versions", () => {
                    expect(
                      requestHelmChartVersionsMock,
                    ).not.toHaveBeenCalled();
                  });

                  it("does not show spinner", () => {
                    expect(
                      rendered.queryByTestId("install-chart-tab-spinner"),
                    ).not.toBeInTheDocument();
                  });

                  it("when installing the first chart, calls for installation of first chart", () => {
                    const installButton = rendered.getByTestId(
                      "install-chart-from-tab-for-some-first-tab-id",
                    );

                    fireEvent.click(installButton);

                    expect(
                      requestCreateHelmReleaseMock,
                    ).toHaveBeenCalledWith({
                      chart: "some-name",
                      name: undefined,
                      namespace: "default",
                      repo: "some-repository",
                      values: "some-default-configuration",
                      version: "some-version",
                    });
                  });
                });
              });
            });
          });

          describe("given changing version to be installed", () => {
            let menu: { selectOption: (labelText: string) => void };

            beforeEach(() => {
              requestHelmChartVersionsMock.mockClear();
              requestHelmChartValuesMock.mockClear();

              const menuId =
                "install-chart-version-select-for-some-first-tab-id";

              menu = builder.select.openMenu(menuId);
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            describe("when version is selected", () => {
              let installButton: HTMLButtonElement;

              beforeEach(() => {
                installButton = rendered.getByTestId(
                  "install-chart-from-tab-for-some-first-tab-id",
                ) as HTMLButtonElement;

                menu.selectOption("some-other-version");
              });

              it("renders", () => {
                expect(rendered.baseElement).toMatchSnapshot();
              });

              it("calls for default configuration for the version of chart", () => {
                expect(requestHelmChartValuesMock).toHaveBeenCalledWith(
                  "some-repository",
                  "some-name",
                  "some-other-version",
                );
              });

              it("shows spinner", () => {
                expect(
                  rendered.getByTestId(
                    "install-chart-configuration-spinner",
                  ),
                ).toBeInTheDocument();
              });

              it("does not call for versions again", () => {
                expect(
                  requestHelmChartVersionsMock,
                ).not.toHaveBeenCalled();
              });

              it("install button is disabled", () => {
                expect(installButton).toHaveAttribute("disabled");
              });

              it("stores the selected version", async () => {
                const readJsonFile = windowDi.inject(readJsonFileInjectable);

                const actual = await readJsonFile(
                  "/some-directory-for-lens-local-storage/some-cluster-id.json",
                ) as any;

                const version = actual.install_charts["some-first-tab-id"].version;

                expect(version).toBe("some-other-version");
              });

              describe("when default configuration resolves", () => {
                beforeEach(async () => {
                  await requestHelmChartValuesMock.resolve({
                    callWasSuccessful: true,
                    response: "some-default-configuration-for-other-version",
                  });
                });

                it("renders", () => {
                  expect(rendered.baseElement).toMatchSnapshot();
                });

                it("does not show spinner", () => {
                  expect(
                    rendered.queryByTestId(
                      "install-chart-configuration-spinner",
                    ),
                  ).not.toBeInTheDocument();
                });

                it("install button is enabled", () => {
                  expect(installButton).not.toHaveAttribute("disabled");
                });

                it("when installing the chart, calls for installation with changed version and default configuration", () => {
                  fireEvent.click(installButton);

                  expect(
                    requestCreateHelmReleaseMock,
                  ).toHaveBeenCalledWith({
                    chart: "some-name",
                    name: undefined,
                    namespace: "default",
                    repo: "some-repository",
                    values:
                      "some-default-configuration-for-other-version",
                    version: "some-other-version",
                  });
                });
              });
            });
          });

          describe("given namespace selection is opened", () => {
            let menu: { selectOption: (labelText: string) => void };

            beforeEach(() => {
              const menuId =
                "install-chart-namespace-select-for-some-first-tab-id";

              menu = builder.select.openMenu(menuId);
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            describe("when namespace is selected", () => {
              beforeEach(() => {
                menu.selectOption("some-other-namespace");
              });

              it("renders", () => {
                expect(rendered.baseElement).toMatchSnapshot();
              });

              it("stores the selected namespace", async () => {
                const readJsonFile = windowDi.inject(readJsonFileInjectable);

                const actual = await readJsonFile(
                  "/some-directory-for-lens-local-storage/some-cluster-id.json",
                ) as any;

                const namespace = actual.install_charts["some-first-tab-id"].namespace;

                expect(namespace).toBe("some-other-namespace");
              });

              it("when installing the chart, calls for installation with changed namespace", () => {
                const installButton = rendered.getByTestId(
                  "install-chart-from-tab-for-some-first-tab-id",
                );

                fireEvent.click(installButton);

                expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith(
                  {
                    chart: "some-name",
                    name: undefined,
                    namespace: "some-other-namespace",
                    repo: "some-repository",
                    values: "some-default-configuration",
                    version: "some-version",
                  },
                );
              });
            });
          });

          describe("given invalid change in configuration", () => {
            let installButton: HTMLButtonElement;
            let input: HTMLInputElement;

            beforeEach(() => {
              installButton = rendered.getByTestId(
                "install-chart-from-tab-for-some-first-tab-id",
              ) as HTMLButtonElement;

              input = rendered.getByTestId(
                "monaco-editor-for-some-first-tab-id",
              ) as HTMLInputElement;

              fireEvent.change(input, {
                target: { value: "@some-invalid-configuration@" },
              });
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            it("updates the editor with the changed value", () => {
              const input = rendered.getByTestId(
                "monaco-editor-for-some-first-tab-id",
              );

              expect(input).toHaveValue("@some-invalid-configuration@");
            });

            it("install button is disabled", () => {
              expect(installButton).toHaveAttribute("disabled");
            });

            it("when valid change in configuration, install button is enabled", () => {
              fireEvent.change(input, {
                target: { value: "some-valid-configuration" },
              });

              expect(installButton).not.toHaveAttribute("disabled");
            });

            it("given change in version, when default configuration resolves, install button is enabled", async () => {
              builder.select
                .openMenu(
                  "install-chart-version-select-for-some-first-tab-id",
                )
                .selectOption("some-other-version");

              await requestHelmChartValuesMock.resolve({
                callWasSuccessful: true,
                response: "some-default-configuration-for-other-version",
              });

              expect(installButton).not.toHaveAttribute("disabled");
            });
          });

          describe("given valid change in configuration", () => {
            beforeEach(() => {
              const input = rendered.getByTestId(
                "monaco-editor-for-some-first-tab-id",
              );

              fireEvent.change(input, {
                target: { value: "some-valid-configuration" },
              });
            });

            it("updates the editor with the changed value", () => {
              const input = rendered.getByTestId(
                "monaco-editor-for-some-first-tab-id",
              );

              expect(input).toHaveValue("some-valid-configuration");
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            it("stores the changed configuration", async () => {
              const readJsonFile = windowDi.inject(readJsonFileInjectable);

              const actual = await readJsonFile(
                "/some-directory-for-lens-local-storage/some-cluster-id.json",
              ) as any;

              const configuration = actual.install_charts["some-first-tab-id"].values;

              expect(configuration).toBe("some-valid-configuration");
            });

            it("does not show spinner", () => {
              expect(
                rendered.queryByTestId("install-chart-tab-spinner"),
              ).not.toBeInTheDocument();
            });

            it("when installing the chart, calls for installation with changed configuration", () => {
              const installButton = rendered.getByTestId(
                "install-chart-from-tab-for-some-first-tab-id",
              );

              fireEvent.click(installButton);

              expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({
                chart: "some-name",
                name: undefined,
                namespace: "default",
                repo: "some-repository",
                values: "some-valid-configuration",
                version: "some-version",
              });
            });

            it("given version is changed, when default configuration resolves, defaults back to default configuration", async () => {
              builder.select
                .openMenu(
                  "install-chart-version-select-for-some-first-tab-id",
                )
                .selectOption("some-other-version");

              await requestHelmChartValuesMock.resolve({
                callWasSuccessful: true,
                response: "some-default-configuration-for-other-version",
              });

              const input = rendered.getByTestId(
                "monaco-editor-for-some-first-tab-id",
              );

              expect(input).toHaveValue(
                "some-default-configuration-for-other-version",
              );
            });
          });

          describe("given custom name is inputted", () => {
            beforeEach(() => {
              const input = rendered.getByTestId(
                "install-chart-custom-name-input-for-some-first-tab-id",
              );

              fireEvent.change(input, {
                target: { value: "some-custom-name" },
              });

            });

            it("stores the changed custom name", async () => {
              const readJsonFile = windowDi.inject(readJsonFileInjectable);

              const actual = await readJsonFile(
                "/some-directory-for-lens-local-storage/some-cluster-id.json",
              ) as any;

              const customName = actual.install_charts["some-first-tab-id"].releaseName;

              expect(customName).toBe("some-custom-name");
            });

            it("renders", () => {
              expect(rendered.baseElement).toMatchSnapshot();
            });

            it("when installed, calls for installation with custom name", () => {
              const installButton = rendered.getByTestId(
                "install-chart-from-tab-for-some-first-tab-id",
              );

              fireEvent.click(installButton);

              expect(requestCreateHelmReleaseMock).toHaveBeenCalledWith({
                chart: "some-name",
                name: "some-custom-name",
                namespace: "default",
                repo: "some-repository",
                values: "some-default-configuration",
                version: "some-version",
              });
            });
          });
        });
      });
    });
  });
});
