mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
383 lines
12 KiB
TypeScript
383 lines
12 KiB
TypeScript
/**
|
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
*/
|
|
|
|
import { anyObject } from "jest-mock-extended";
|
|
import mockFs from "mock-fs";
|
|
import type { CatalogEntity, CatalogEntityData, CatalogEntityKindData } from "../catalog";
|
|
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
|
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
|
import type { DiContainer } from "@ogre-tools/injectable";
|
|
import hotbarStoreInjectable from "../hotbars/store.injectable";
|
|
import type { HotbarStore } from "../hotbars/store";
|
|
import catalogEntityRegistryInjectable from "../../main/catalog/entity-registry.injectable";
|
|
import { computed } from "mobx";
|
|
import hasCategoryForEntityInjectable from "../catalog/has-category-for-entity.injectable";
|
|
import catalogCatalogEntityInjectable from "../catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
|
|
import loggerInjectable from "../logger.injectable";
|
|
import type { Logger } from "../logger";
|
|
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
|
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
|
|
|
function getMockCatalogEntity(data: Partial<CatalogEntityData> & CatalogEntityKindData): CatalogEntity {
|
|
return {
|
|
getName: jest.fn(() => data.metadata?.name),
|
|
getId: jest.fn(() => data.metadata?.uid),
|
|
getSource: jest.fn(() => data.metadata?.source ?? "unknown"),
|
|
isEnabled: jest.fn(() => data.status?.enabled ?? true),
|
|
onContextMenuOpen: jest.fn(),
|
|
onSettingsOpen: jest.fn(),
|
|
metadata: {},
|
|
spec: {},
|
|
status: {},
|
|
...data,
|
|
} as CatalogEntity;
|
|
}
|
|
|
|
describe("HotbarStore", () => {
|
|
let di: DiContainer;
|
|
let hotbarStore: HotbarStore;
|
|
let testCluster: CatalogEntity;
|
|
let minikubeCluster: CatalogEntity;
|
|
let awsCluster: CatalogEntity;
|
|
let loggerMock: jest.Mocked<Logger>;
|
|
|
|
beforeEach(async () => {
|
|
di = getDiForUnitTesting({ doGeneralOverrides: true });
|
|
|
|
(di as any).unoverride(hotbarStoreInjectable);
|
|
|
|
testCluster = getMockCatalogEntity({
|
|
apiVersion: "v1",
|
|
kind: "Cluster",
|
|
status: {
|
|
phase: "Running",
|
|
},
|
|
metadata: {
|
|
uid: "some-test-id",
|
|
name: "my-test-cluster",
|
|
source: "local",
|
|
labels: {},
|
|
},
|
|
});
|
|
minikubeCluster = getMockCatalogEntity({
|
|
apiVersion: "v1",
|
|
kind: "Cluster",
|
|
status: {
|
|
phase: "Running",
|
|
},
|
|
metadata: {
|
|
uid: "some-minikube-id",
|
|
name: "my-minikube-cluster",
|
|
source: "local",
|
|
labels: {},
|
|
},
|
|
});
|
|
awsCluster = getMockCatalogEntity({
|
|
apiVersion: "v1",
|
|
kind: "Cluster",
|
|
status: {
|
|
phase: "Running",
|
|
},
|
|
metadata: {
|
|
uid: "some-aws-id",
|
|
name: "my-aws-cluster",
|
|
source: "local",
|
|
labels: {},
|
|
},
|
|
});
|
|
|
|
di.override(hasCategoryForEntityInjectable, () => () => true);
|
|
|
|
loggerMock = {
|
|
warn: jest.fn(),
|
|
debug: jest.fn(),
|
|
error: jest.fn(),
|
|
info: jest.fn(),
|
|
silly: jest.fn(),
|
|
};
|
|
|
|
di.override(loggerInjectable, () => loggerMock);
|
|
|
|
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
|
|
|
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
|
const catalogCatalogEntity = di.inject(catalogCatalogEntityInjectable);
|
|
|
|
catalogEntityRegistry.addComputedSource("some-id", computed(() => [
|
|
testCluster,
|
|
minikubeCluster,
|
|
awsCluster,
|
|
catalogCatalogEntity,
|
|
]));
|
|
|
|
di.permitSideEffects(getConfigurationFileModelInjectable);
|
|
di.permitSideEffects(hotbarStoreInjectable);
|
|
});
|
|
|
|
afterEach(() => {
|
|
mockFs.restore();
|
|
});
|
|
|
|
describe("given no previous data in store, running all migrations", () => {
|
|
beforeEach(() => {
|
|
mockFs();
|
|
|
|
hotbarStore = di.inject(hotbarStoreInjectable);
|
|
|
|
hotbarStore.load();
|
|
});
|
|
|
|
describe("load", () => {
|
|
it("loads one hotbar by default", () => {
|
|
expect(hotbarStore.hotbars.length).toEqual(1);
|
|
});
|
|
});
|
|
|
|
describe("add", () => {
|
|
it("adds a hotbar", () => {
|
|
hotbarStore.add({ name: "hottest" });
|
|
expect(hotbarStore.hotbars.length).toEqual(2);
|
|
});
|
|
});
|
|
|
|
describe("hotbar items", () => {
|
|
it("initially creates 12 empty cells", () => {
|
|
expect(hotbarStore.getActive().items.length).toEqual(12);
|
|
});
|
|
|
|
it("initially adds catalog entity as first item", () => {
|
|
expect(hotbarStore.getActive().items[0]?.entity.name).toEqual("Catalog");
|
|
});
|
|
|
|
it("adds items", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
|
|
|
expect(items.length).toEqual(2);
|
|
});
|
|
|
|
it("removes items", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.removeFromHotbar("some-test-id");
|
|
hotbarStore.removeFromHotbar("catalog-entity");
|
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
|
|
|
expect(items).toStrictEqual([]);
|
|
});
|
|
|
|
it("does nothing if removing with invalid uid", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.removeFromHotbar("invalid uid");
|
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
|
|
|
expect(items.length).toEqual(2);
|
|
});
|
|
|
|
it("moves item to empty cell", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.addToHotbar(minikubeCluster);
|
|
hotbarStore.addToHotbar(awsCluster);
|
|
|
|
expect(hotbarStore.getActive().items[6]).toBeNull();
|
|
|
|
hotbarStore.restackItems(1, 5);
|
|
|
|
expect(hotbarStore.getActive().items[5]).toBeTruthy();
|
|
expect(hotbarStore.getActive().items[5]?.entity.uid).toEqual("some-test-id");
|
|
});
|
|
|
|
it("moves items down", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.addToHotbar(minikubeCluster);
|
|
hotbarStore.addToHotbar(awsCluster);
|
|
|
|
// aws -> catalog
|
|
hotbarStore.restackItems(3, 0);
|
|
|
|
const items = hotbarStore.getActive().items.map(item => item?.entity.uid || null);
|
|
|
|
expect(items.slice(0, 4)).toEqual(["some-aws-id", "catalog-entity", "some-test-id", "some-minikube-id"]);
|
|
});
|
|
|
|
it("moves items up", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.addToHotbar(minikubeCluster);
|
|
hotbarStore.addToHotbar(awsCluster);
|
|
|
|
// test -> aws
|
|
hotbarStore.restackItems(1, 3);
|
|
|
|
const items = hotbarStore.getActive().items.map(item => item?.entity.uid || null);
|
|
|
|
expect(items.slice(0, 4)).toEqual(["catalog-entity", "some-minikube-id", "some-aws-id", "some-test-id"]);
|
|
});
|
|
|
|
it("logs an error if cellIndex is out of bounds", () => {
|
|
hotbarStore.add({ name: "hottest", id: "hottest" });
|
|
hotbarStore.setActiveHotbar("hottest");
|
|
|
|
hotbarStore.addToHotbar(testCluster, -1);
|
|
expect(loggerMock.error).toBeCalledWith("[HOTBAR-STORE]: cannot pin entity to hotbar outside of index range", anyObject());
|
|
|
|
hotbarStore.addToHotbar(testCluster, 12);
|
|
expect(loggerMock.error).toBeCalledWith("[HOTBAR-STORE]: cannot pin entity to hotbar outside of index range", anyObject());
|
|
|
|
hotbarStore.addToHotbar(testCluster, 13);
|
|
expect(loggerMock.error).toBeCalledWith("[HOTBAR-STORE]: cannot pin entity to hotbar outside of index range", anyObject());
|
|
});
|
|
|
|
it("throws an error if getId is invalid or returns not a string", () => {
|
|
expect(() => hotbarStore.addToHotbar({} as any)).toThrowError(TypeError);
|
|
expect(() => hotbarStore.addToHotbar({ getId: () => true } as any)).toThrowError(TypeError);
|
|
});
|
|
|
|
it("throws an error if getName is invalid or returns not a string", () => {
|
|
expect(() => hotbarStore.addToHotbar({ getId: () => "" } as any)).toThrowError(TypeError);
|
|
expect(() => hotbarStore.addToHotbar({ getId: () => "", getName: () => 4 } as any)).toThrowError(TypeError);
|
|
});
|
|
|
|
it("does nothing when item moved to same cell", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.restackItems(1, 1);
|
|
|
|
expect(hotbarStore.getActive().items[1]?.entity.uid).toEqual("some-test-id");
|
|
});
|
|
|
|
it("new items takes first empty cell", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
hotbarStore.addToHotbar(awsCluster);
|
|
hotbarStore.restackItems(0, 3);
|
|
hotbarStore.addToHotbar(minikubeCluster);
|
|
|
|
expect(hotbarStore.getActive().items[0]?.entity.uid).toEqual("some-minikube-id");
|
|
});
|
|
|
|
it("throws if invalid arguments provided", () => {
|
|
// Prevent writing to stderr during this render.
|
|
const { error, warn } = console;
|
|
|
|
console.error = jest.fn();
|
|
console.warn = jest.fn();
|
|
|
|
hotbarStore.addToHotbar(testCluster);
|
|
|
|
expect(() => hotbarStore.restackItems(-5, 0)).toThrow();
|
|
expect(() => hotbarStore.restackItems(2, -1)).toThrow();
|
|
expect(() => hotbarStore.restackItems(14, 1)).toThrow();
|
|
expect(() => hotbarStore.restackItems(11, 112)).toThrow();
|
|
|
|
// Restore writing to stderr.
|
|
console.error = error;
|
|
console.warn = warn;
|
|
});
|
|
|
|
it("checks if entity already pinned to hotbar", () => {
|
|
hotbarStore.addToHotbar(testCluster);
|
|
|
|
expect(hotbarStore.isAddedToActive(testCluster)).toBeTruthy();
|
|
expect(hotbarStore.isAddedToActive(awsCluster)).toBeFalsy();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("given data from 5.0.0-beta.3 and version being 5.0.0-beta.10", () => {
|
|
beforeEach(() => {
|
|
const configurationToBeMigrated = {
|
|
"some-directory-for-user-data": {
|
|
"lens-hotbar-store.json": JSON.stringify({
|
|
__internal__: {
|
|
migrations: {
|
|
version: "5.0.0-beta.3",
|
|
},
|
|
},
|
|
hotbars: [
|
|
{
|
|
id: "3caac17f-aec2-4723-9694-ad204465d935",
|
|
name: "myhotbar",
|
|
items: [
|
|
{
|
|
entity: {
|
|
uid: "some-aws-id",
|
|
},
|
|
},
|
|
{
|
|
entity: {
|
|
uid: "55b42c3c7ba3b04193416cda405269a5",
|
|
},
|
|
},
|
|
{
|
|
entity: {
|
|
uid: "176fd331968660832f62283219d7eb6e",
|
|
},
|
|
},
|
|
{
|
|
entity: {
|
|
uid: "61c4fb45528840ebad1badc25da41d14",
|
|
name: "user1-context",
|
|
source: "local",
|
|
},
|
|
},
|
|
{
|
|
entity: {
|
|
uid: "27d6f99fe9e7548a6e306760bfe19969",
|
|
name: "foo2",
|
|
source: "local",
|
|
},
|
|
},
|
|
null,
|
|
{
|
|
entity: {
|
|
uid: "c0b20040646849bb4dcf773e43a0bf27",
|
|
name: "multinode-demo",
|
|
source: "local",
|
|
},
|
|
},
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
},
|
|
};
|
|
|
|
mockFs(configurationToBeMigrated);
|
|
|
|
di.override(storeMigrationVersionInjectable, () => "5.0.0-beta.10");
|
|
|
|
hotbarStore = di.inject(hotbarStoreInjectable);
|
|
|
|
hotbarStore.load();
|
|
});
|
|
|
|
it("allows to retrieve a hotbar", () => {
|
|
const hotbar = hotbarStore.findById("3caac17f-aec2-4723-9694-ad204465d935");
|
|
|
|
expect(hotbar?.id).toBe("3caac17f-aec2-4723-9694-ad204465d935");
|
|
});
|
|
|
|
it("clears cells without entity", () => {
|
|
const items = hotbarStore.hotbars[0].items;
|
|
|
|
expect(items[2]).toBeNull();
|
|
});
|
|
|
|
it("adds extra data to cells with according entity", () => {
|
|
const items = hotbarStore.hotbars[0].items;
|
|
|
|
expect(items[0]).toEqual({
|
|
entity: {
|
|
name: "my-aws-cluster",
|
|
source: "local",
|
|
uid: "some-aws-id",
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|