mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Restructure to monorepo (#6907)
* wip: restructure to monorepo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor create-release-pr to a package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * github workflow fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix typo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add webpack-env types to core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix github workflows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor/fix integration tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * lint fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * yarn run dev Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * eslint settings for vscode Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * move templates to right package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * open-lens build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * integration test fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix nx task dependencies Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * use bash shell for unit tests in test workflow Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test:unit for windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix build:app on windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove ELECTRON_BUILDER_EXTRA_ARGS Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * sync src/ from master Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove Makefile from core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0066ca4ea2
commit
2657df2293
3321 files changed
+28699
-11447
No files matched your search
+11438
File diff suppressed because it is too large.
Load diff
+1236
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,930 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
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 navigateToNamespacesInjectable from "../../../common/front-end-routing/routes/cluster/namespaces/navigate-to-namespaces.injectable";
|
||||
import createEditResourceTabInjectable from "../../../renderer/components/dock/edit-resource/edit-resource-tab.injectable";
|
||||
import getRandomIdForEditResourceTabInjectable from "../../../renderer/components/dock/edit-resource/get-random-id-for-edit-resource-tab.injectable";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import type { CallForResource } from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-resource/call-for-resource.injectable";
|
||||
import callForResourceInjectable from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-resource/call-for-resource.injectable";
|
||||
import type { CallForPatchResource } from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-patch-resource/call-for-patch-resource.injectable";
|
||||
import callForPatchResourceInjectable from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-patch-resource/call-for-patch-resource.injectable";
|
||||
import dockStoreInjectable from "../../../renderer/components/dock/dock/store.injectable";
|
||||
import { Namespace } from "../../../common/k8s-api/endpoints";
|
||||
import showSuccessNotificationInjectable from "../../../renderer/components/notifications/show-success-notification.injectable";
|
||||
import showErrorNotificationInjectable from "../../../renderer/components/notifications/show-error-notification.injectable";
|
||||
import readJsonFileInjectable from "../../../common/fs/read-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";
|
||||
|
||||
describe("cluster/namespaces - edit namespace from new tab", () => {
|
||||
let builder: ApplicationBuilder;
|
||||
let callForResourceMock: AsyncFnMock<CallForResource>;
|
||||
let callForPatchResourceMock: AsyncFnMock<CallForPatchResource>;
|
||||
let showSuccessNotificationMock: jest.Mock;
|
||||
let showErrorNotificationMock: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
builder = getApplicationBuilder();
|
||||
|
||||
builder.setEnvironmentToClusterFrame();
|
||||
|
||||
builder.beforeWindowStart((windowDi) => {
|
||||
windowDi.override(
|
||||
directoryForLensLocalStorageInjectable,
|
||||
() => "/some-directory-for-lens-local-storage",
|
||||
);
|
||||
|
||||
windowDi.override(hostedClusterIdInjectable, () => "some-cluster-id");
|
||||
|
||||
showSuccessNotificationMock = jest.fn();
|
||||
windowDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock);
|
||||
|
||||
showErrorNotificationMock = jest.fn();
|
||||
windowDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock);
|
||||
|
||||
windowDi.override(getRandomIdForEditResourceTabInjectable, () =>
|
||||
jest
|
||||
.fn(() => "some-irrelevant-random-id")
|
||||
.mockReturnValueOnce("some-first-tab-id")
|
||||
.mockReturnValueOnce("some-second-tab-id"),
|
||||
);
|
||||
|
||||
callForResourceMock = asyncFn();
|
||||
windowDi.override(callForResourceInjectable, () => callForResourceMock);
|
||||
|
||||
callForPatchResourceMock = asyncFn();
|
||||
windowDi.override(callForPatchResourceInjectable, () => callForPatchResourceMock);
|
||||
});
|
||||
|
||||
builder.allowKubeResource({
|
||||
apiName: "namespaces",
|
||||
group: "",
|
||||
});
|
||||
});
|
||||
|
||||
describe("when navigating to namespaces", () => {
|
||||
let rendered: RenderResult;
|
||||
let windowDi: DiContainer;
|
||||
|
||||
beforeEach(async () => {
|
||||
rendered = await builder.render();
|
||||
|
||||
windowDi = builder.applicationWindow.only.di;
|
||||
|
||||
const navigateToNamespaces = windowDi.inject(navigateToNamespacesInjectable);
|
||||
const dockStore = windowDi.inject(dockStoreInjectable);
|
||||
|
||||
navigateToNamespaces();
|
||||
|
||||
// TODO: Make TerminalWindow unit testable to allow realistic behaviour
|
||||
dockStore.closeTab("terminal");
|
||||
});
|
||||
|
||||
// TODO: Implement skipped tests when loading of resources can be tested
|
||||
xit("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
xit("calls for namespaces", () => {
|
||||
|
||||
});
|
||||
|
||||
xit("shows spinner", () => {
|
||||
|
||||
});
|
||||
|
||||
describe("when namespaces resolve", () => {
|
||||
beforeEach(() => {
|
||||
|
||||
});
|
||||
|
||||
xit("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
xit("does not show spinner anymore", () => {
|
||||
|
||||
});
|
||||
|
||||
describe("when clicking the context menu for a namespace", () => {
|
||||
beforeEach(() => {
|
||||
|
||||
});
|
||||
|
||||
xit("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
xit("does not show edit resource tab yet", () => {
|
||||
|
||||
});
|
||||
|
||||
describe("when clicking to edit namespace", () => {
|
||||
beforeEach(() => {
|
||||
// TODO: Make implementation match the description (tests above)
|
||||
const namespaceStub = new Namespace(someNamespaceDataStub);
|
||||
|
||||
const createEditResourceTab = windowDi.inject(createEditResourceTabInjectable);
|
||||
|
||||
createEditResourceTab(namespaceStub);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows dock tab for editing namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows spinner in the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("edit-resource-tab-spinner"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("calls for namespace", () => {
|
||||
expect(callForResourceMock).toHaveBeenCalledWith(
|
||||
"/apis/some-api-version/namespaces/some-uid",
|
||||
);
|
||||
});
|
||||
|
||||
describe("when call for namespace resolves with namespace", () => {
|
||||
let someNamespace: Namespace;
|
||||
|
||||
beforeEach(async () => {
|
||||
someNamespace = new Namespace({
|
||||
apiVersion: "some-api-version",
|
||||
kind: "Namespace",
|
||||
|
||||
metadata: {
|
||||
uid: "some-uid",
|
||||
name: "some-name",
|
||||
resourceVersion: "some-resource-version",
|
||||
selfLink: "/apis/some-api-version/namespaces/some-uid",
|
||||
somePropertyToBeRemoved: "some-value",
|
||||
somePropertyToBeChanged: "some-old-value",
|
||||
},
|
||||
});
|
||||
|
||||
await callForResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: someNamespace,
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not show spinner anymore", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("edit-resource-tab-spinner"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("has the configuration in editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe(`apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeRemoved: some-value
|
||||
somePropertyToBeChanged: some-old-value
|
||||
`);
|
||||
});
|
||||
|
||||
describe("given no changes in the configuration, when selecting to save", () => {
|
||||
beforeEach(() => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("calls for save with empty values", () => {
|
||||
expect(callForPatchResourceMock).toHaveBeenCalledWith(
|
||||
someNamespace,
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it("shows spinner", () => {
|
||||
expect(
|
||||
rendered.getByTestId("saving-edit-resource-from-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("save button is disabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("save and close button is disabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
describe("when saving resolves with success", () => {
|
||||
beforeEach(async () => {
|
||||
await callForPatchResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: { name: "some-name", kind: "Namespace" },
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not show spinner anymore", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("saving-edit-resource-from-tab-for-some-first-tab-id"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("save button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("save and close button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("shows success notification", () => {
|
||||
expect(showSuccessNotificationMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not show error notification", () => {
|
||||
expect(showErrorNotificationMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not close the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when saving resolves with failure", () => {
|
||||
beforeEach(async () => {
|
||||
await callForPatchResourceMock.resolve({
|
||||
callWasSuccessful: false,
|
||||
error: "some-error",
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not show spinner anymore", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("edit-resource-tab-spinner"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("save button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("save and close button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("does not show success notification", () => {
|
||||
expect(showSuccessNotificationMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shows error notification", () => {
|
||||
expect(showErrorNotificationMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not close the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when selecting to save and close", () => {
|
||||
beforeEach(() => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not close the tab yet", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe("when saving resolves with success", () => {
|
||||
beforeEach(async () => {
|
||||
await callForPatchResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: { name: "some-name", kind: "Namespace" },
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("closes the dock tab", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when saving resolves with failure", () => {
|
||||
beforeEach(async () => {
|
||||
await callForPatchResourceMock.resolve({
|
||||
callWasSuccessful: false,
|
||||
error: "Some error",
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// TODO: Not doable at the moment because info panel controls closing of the tab
|
||||
xit("does not close the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when selecting to cancel", () => {
|
||||
beforeEach(() => {
|
||||
const cancelButton = rendered.getByTestId(
|
||||
"cancel-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(cancelButton);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not have dock tab anymore", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("given change in configuration", () => {
|
||||
beforeEach(() => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLInputElement;
|
||||
|
||||
fireEvent.change(input, {
|
||||
target: {
|
||||
value: `apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeChanged: some-changed-value
|
||||
someAddedProperty: some-new-value
|
||||
`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("has the changed configuration in editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe(`apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeChanged: some-changed-value
|
||||
someAddedProperty: some-new-value
|
||||
`);
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
expect(
|
||||
actual.edit_resource_store["some-first-tab-id"],
|
||||
).toEqual({
|
||||
resource: "/apis/some-api-version/namespaces/some-uid",
|
||||
firstDraft: `apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeRemoved: some-value
|
||||
somePropertyToBeChanged: some-old-value
|
||||
`,
|
||||
draft: `apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeChanged: some-changed-value
|
||||
someAddedProperty: some-new-value
|
||||
`,
|
||||
});
|
||||
});
|
||||
|
||||
describe("when selecting to save", () => {
|
||||
beforeEach(() => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
});
|
||||
|
||||
it("calls for save with changed configuration", () => {
|
||||
expect(callForPatchResourceMock).toHaveBeenCalledWith(
|
||||
someNamespace,
|
||||
[
|
||||
{
|
||||
op: "remove",
|
||||
path: "/metadata/somePropertyToBeRemoved",
|
||||
},
|
||||
{
|
||||
op: "add",
|
||||
path: "/metadata/someAddedProperty",
|
||||
value: "some-new-value",
|
||||
},
|
||||
{
|
||||
op: "replace",
|
||||
path: "/metadata/somePropertyToBeChanged",
|
||||
value: "some-changed-value",
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it("given save resolves and another change in configuration, when saving, calls for save with changed configuration", async () => {
|
||||
await callForPatchResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
|
||||
response: {
|
||||
name: "some-name",
|
||||
kind: "Namespace",
|
||||
},
|
||||
});
|
||||
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLInputElement;
|
||||
|
||||
fireEvent.change(input, {
|
||||
target: {
|
||||
value: `apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeChanged: some-changed-value
|
||||
someAddedProperty: some-new-value
|
||||
someOtherAddedProperty: some-other-new-value
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
callForPatchResourceMock.mockClear();
|
||||
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
expect(callForPatchResourceMock).toHaveBeenCalledWith(
|
||||
someNamespace,
|
||||
[
|
||||
{
|
||||
op: "add",
|
||||
path: "/metadata/someOtherAddedProperty",
|
||||
value: "some-other-new-value",
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("given invalid change in configuration", () => {
|
||||
beforeEach(() => {
|
||||
const 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("has the changed configuration in editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe(`@some-invalid-configuration@`);
|
||||
});
|
||||
|
||||
it("save button is disabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("save and close button is disabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
describe("when valid change in configuration", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLInputElement;
|
||||
|
||||
|
||||
fireEvent.change(input, {
|
||||
target: {
|
||||
value: `apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("save button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
|
||||
it("save and close button is enabled", () => {
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-and-close-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
expect(saveButton).not.toHaveAttribute("disabled");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("given clicking the context menu for second namespace, when clicking to edit namespace", () => {
|
||||
beforeEach(() => {
|
||||
callForResourceMock.mockClear();
|
||||
|
||||
// TODO: Make implementation match the description
|
||||
const namespaceStub = new Namespace(someOtherNamespaceDataStub);
|
||||
|
||||
const createEditResourceTab = windowDi.inject(createEditResourceTabInjectable);
|
||||
|
||||
createEditResourceTab(namespaceStub);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows dock tab for editing second namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-content-for-some-second-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("still has dock tab for first namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows spinner in the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("edit-resource-tab-spinner"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("calls for second namespace", () => {
|
||||
expect(callForResourceMock).toHaveBeenCalledWith(
|
||||
"/apis/some-api-version/namespaces/some-other-uid",
|
||||
);
|
||||
});
|
||||
|
||||
describe("when second namespace resolves", () => {
|
||||
let someOtherNamespace: Namespace;
|
||||
|
||||
beforeEach(async () => {
|
||||
someOtherNamespace = new Namespace({
|
||||
apiVersion: "some-api-version",
|
||||
kind: "Namespace",
|
||||
|
||||
metadata: {
|
||||
uid: "some-other-uid",
|
||||
name: "some-other-name",
|
||||
resourceVersion: "some-resource-version",
|
||||
selfLink:
|
||||
"/apis/some-api-version/namespaces/some-other-uid",
|
||||
},
|
||||
});
|
||||
|
||||
await callForResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: someOtherNamespace,
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("has the configuration in editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-second-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe(`apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-other-uid
|
||||
name: some-other-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-other-uid
|
||||
`);
|
||||
});
|
||||
|
||||
it("when selecting to save, calls for save of second namespace", () => {
|
||||
callForPatchResourceMock.mockClear();
|
||||
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-second-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
expect(callForPatchResourceMock).toHaveBeenCalledWith(
|
||||
someOtherNamespace,
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
describe("when clicking dock tab for the first namespace", () => {
|
||||
beforeEach(() => {
|
||||
callForResourceMock.mockClear();
|
||||
|
||||
const tab = rendered.getByTestId("dock-tab-for-some-first-tab-id");
|
||||
|
||||
fireEvent.click(tab);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows dock tab for editing first namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-content-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("still has dock tab for second namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-second-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not show spinner in the dock tab", () => {
|
||||
expect(
|
||||
rendered.queryByTestId("edit-resource-tab-spinner"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not call for namespace", () => {
|
||||
expect(callForResourceMock).not.toHaveBeenCalledWith("/apis/some-api-version/namespaces/some-uid");
|
||||
});
|
||||
|
||||
it("has configuration in the editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe(`apiVersion: some-api-version
|
||||
kind: Namespace
|
||||
metadata:
|
||||
uid: some-uid
|
||||
name: some-name
|
||||
resourceVersion: some-resource-version
|
||||
selfLink: /apis/some-api-version/namespaces/some-uid
|
||||
somePropertyToBeRemoved: some-value
|
||||
somePropertyToBeChanged: some-old-value
|
||||
`);
|
||||
});
|
||||
|
||||
it("when selecting to save, calls for save of first namespace", () => {
|
||||
callForPatchResourceMock.mockClear();
|
||||
|
||||
const saveButton = rendered.getByTestId(
|
||||
"save-edit-resource-from-tab-for-some-first-tab-id",
|
||||
);
|
||||
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
expect(callForPatchResourceMock).toHaveBeenCalledWith(
|
||||
someNamespace,
|
||||
[],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when call for namespace resolves without namespace", () => {
|
||||
beforeEach(async () => {
|
||||
await callForResourceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("still shows the dock tab for editing namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows error message", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-content-for-some-first-tab-id"),
|
||||
).toHaveTextContent("Resource not found");
|
||||
});
|
||||
|
||||
it("does not show error notification", () => {
|
||||
expect(showErrorNotificationMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when call for namespace resolves with failure", () => {
|
||||
beforeEach(async () => {
|
||||
await callForResourceMock.resolve({
|
||||
callWasSuccessful: false,
|
||||
error: "some-error",
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("still shows the dock tab for editing namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows error message", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-content-for-some-first-tab-id"),
|
||||
).toHaveTextContent("Resource not found");
|
||||
});
|
||||
|
||||
it("shows error notification", () => {
|
||||
expect(showErrorNotificationMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const someNamespaceDataStub = {
|
||||
apiVersion: "some-api-version",
|
||||
kind: "Namespace",
|
||||
metadata: {
|
||||
uid: "some-uid",
|
||||
name: "some-name",
|
||||
resourceVersion: "some-resource-version",
|
||||
selfLink: "/apis/some-api-version/namespaces/some-uid",
|
||||
},
|
||||
};
|
||||
|
||||
const someOtherNamespaceDataStub = {
|
||||
apiVersion: "some-api-version",
|
||||
kind: "Namespace",
|
||||
metadata: {
|
||||
uid: "some-other-uid",
|
||||
name: "some-other-name",
|
||||
resourceVersion: "some-resource-version",
|
||||
selfLink: "/apis/some-api-version/namespaces/some-other-uid",
|
||||
},
|
||||
};
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 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 { act } 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 type { CallForResource } from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-resource/call-for-resource.injectable";
|
||||
import callForResourceInjectable from "../../../renderer/components/dock/edit-resource/edit-resource-model/call-for-resource/call-for-resource.injectable";
|
||||
import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
||||
import writeJsonFileInjectable from "../../../common/fs/write-json-file.injectable";
|
||||
import { TabKind } from "../../../renderer/components/dock/dock/store";
|
||||
import { Namespace } from "../../../common/k8s-api/endpoints";
|
||||
|
||||
describe("cluster/namespaces - edit namespaces from previously opened tab", () => {
|
||||
let builder: ApplicationBuilder;
|
||||
let callForNamespaceMock: AsyncFnMock<CallForResource>;
|
||||
|
||||
beforeEach(() => {
|
||||
builder = getApplicationBuilder();
|
||||
|
||||
builder.setEnvironmentToClusterFrame();
|
||||
|
||||
callForNamespaceMock = asyncFn();
|
||||
|
||||
builder.beforeWindowStart((windowDi) => {
|
||||
windowDi.override(
|
||||
directoryForLensLocalStorageInjectable,
|
||||
() => "/some-directory-for-lens-local-storage",
|
||||
);
|
||||
|
||||
windowDi.override(callForResourceInjectable, () => callForNamespaceMock);
|
||||
});
|
||||
|
||||
builder.allowKubeResource({
|
||||
apiName: "namespaces",
|
||||
group: "",
|
||||
});
|
||||
});
|
||||
|
||||
describe("given tab was previously opened, when application is started", () => {
|
||||
let rendered: RenderResult;
|
||||
|
||||
beforeEach(async () => {
|
||||
builder.beforeWindowStart(async (windowDi) => {
|
||||
const writeJsonFile = windowDi.inject(writeJsonFileInjectable);
|
||||
|
||||
await writeJsonFile(
|
||||
"/some-directory-for-lens-local-storage/some-cluster-id.json",
|
||||
{
|
||||
dock: {
|
||||
height: 300,
|
||||
tabs: [
|
||||
{
|
||||
id: "some-first-tab-id",
|
||||
kind: TabKind.EDIT_RESOURCE,
|
||||
title: "Namespace: some-namespace",
|
||||
pinned: false,
|
||||
},
|
||||
],
|
||||
|
||||
isOpen: true,
|
||||
},
|
||||
|
||||
edit_resource_store: {
|
||||
"some-first-tab-id": {
|
||||
resource: "/apis/some-api-version/namespaces/some-uid",
|
||||
draft: "some-saved-configuration",
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
rendered = await builder.render();
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows dock tab for editing namespace", () => {
|
||||
expect(
|
||||
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows spinner in the dock tab", () => {
|
||||
expect(
|
||||
rendered.getByTestId("edit-resource-tab-spinner"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("calls for namespace", () => {
|
||||
expect(callForNamespaceMock).toHaveBeenCalledWith(
|
||||
"/apis/some-api-version/namespaces/some-uid",
|
||||
);
|
||||
});
|
||||
|
||||
describe("when call for namespace resolves with namespace", () => {
|
||||
let someNamespace: Namespace;
|
||||
|
||||
beforeEach(async () => {
|
||||
someNamespace = new Namespace({
|
||||
apiVersion: "some-api-version",
|
||||
kind: "Namespace",
|
||||
|
||||
metadata: {
|
||||
uid: "some-uid",
|
||||
name: "some-name",
|
||||
resourceVersion: "some-resource-version",
|
||||
selfLink: "/apis/some-api-version/namespaces/some-uid",
|
||||
somePropertyToBeRemoved: "some-value",
|
||||
somePropertyToBeChanged: "some-old-value",
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: Figure out why act is needed here. In CI it works without it.
|
||||
await act(async () => {
|
||||
await callForNamespaceMock.resolve({
|
||||
callWasSuccessful: true,
|
||||
response: someNamespace,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("has the saved configuration in editor", () => {
|
||||
const input = rendered.getByTestId(
|
||||
"monaco-editor-for-some-first-tab-id",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
expect(input.value).toBe("some-saved-configuration");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user