diff --git a/packages/suite-base/src/components/PanelSettings/settingsTree.test.ts b/packages/suite-base/src/components/PanelSettings/settingsTree.test.ts new file mode 100644 index 0000000000..b16b3f5be1 --- /dev/null +++ b/packages/suite-base/src/components/PanelSettings/settingsTree.test.ts @@ -0,0 +1,176 @@ +/** @jest-environment jsdom */ +// SPDX-FileCopyrightText: Copyright (C) 2023-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// SPDX-License-Identifier: MPL-2.0 + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { SettingsTreeNode } from "@lichtblick/suite"; +import { + buildSettingsTree, + BuildSettingsTreeProps, +} from "@lichtblick/suite-base/components/PanelSettings/settingsTree"; +import { PanelStateStore } from "@lichtblick/suite-base/context/PanelStateContext"; +import { maybeCast } from "@lichtblick/suite-base/util/maybeCast"; + +jest.mock("@lichtblick/suite-base/util/maybeCast"); + +describe("buildSettingsTree", () => { + function setup(): Pick< + BuildSettingsTreeProps, + "state" | "extensionSettings" | "topicToSchemaNameMap" | "config" + > { + const config: Record | undefined = { + topics: { + topic1: { someConfig: "valueFromConfig" }, + }, + }; + (maybeCast as jest.Mock).mockReturnValue(config); + + return { + state: { + settingsTrees: { + panel1: { + nodes: { + topics: { + children: { + topic1: {}, + }, + }, + }, + }, + }, + } as unknown as PanelStateStore, + extensionSettings: { + myPanelType: { + schema1: { + settings: jest.fn( + (_config): SettingsTreeNode => ({ + label: "valueFromExtension", + children: {}, + }), + ), + handler: jest.fn(), + }, + }, + }, + topicToSchemaNameMap: { + topic1: "schema1", + topic2: "schema2", + }, + config, + }; + } + + beforeEach(() => { + (console.error as jest.Mock).mockClear(); + }); + + it.each>([ + { panelType: undefined, selectedPanelId: "value" }, + { panelType: "value", selectedPanelId: undefined }, + ])( + "should return undefined if selectedPanelId or panelType is undefined", + ({ panelType, selectedPanelId }) => { + const { config, extensionSettings, state, topicToSchemaNameMap } = setup(); + + const result = buildSettingsTree({ + config, + extensionSettings, + panelType, + selectedPanelId, + state, + topicToSchemaNameMap, + }); + expect(result).toBeUndefined(); + }, + ); + + it("should return undefined if selected panel is not found in state", () => { + const { config, extensionSettings, state, topicToSchemaNameMap } = setup(); + + const result = buildSettingsTree({ + config, + extensionSettings, + panelType: "myPanelType", + selectedPanelId: "invalidPanel", + state, + topicToSchemaNameMap, + }); + expect(result).toBeUndefined(); + }); + + it("should return the correct settingsTree when valid panelId and panelType are provided", () => { + const { config, extensionSettings, state, topicToSchemaNameMap } = setup(); + + const result = buildSettingsTree({ + config, + extensionSettings, + panelType: "myPanelType", + selectedPanelId: "panel1", + state, + topicToSchemaNameMap, + }); + + expect(result).toEqual({ + nodes: { + topics: { + children: { + topic1: { label: "valueFromExtension", children: {} }, + }, + }, + }, + }); + }); + + it("should return the settingsTree even if topics are empty", () => { + const { config, extensionSettings, topicToSchemaNameMap } = setup(); + + const emptyState = { + settingsTrees: { + panel1: { + nodes: { + topics: { + children: {}, + }, + }, + }, + }, + } as unknown as PanelStateStore; + + const result = buildSettingsTree({ + config, + extensionSettings, + panelType: "myPanelType", + selectedPanelId: "panel1", + state: emptyState, + topicToSchemaNameMap, + }); + + expect(result).toEqual({ + nodes: { + topics: { + children: {}, + }, + }, + }); + }); + + it("should merge topicsSettings with existing children in the settingsTree", () => { + const { config, extensionSettings, state, topicToSchemaNameMap } = setup(); + + const result = buildSettingsTree({ + config, + extensionSettings, + panelType: "myPanelType", + selectedPanelId: "panel1", + state, + topicToSchemaNameMap, + }); + + expect(result?.nodes.topics?.children).toEqual({ + topic1: { label: "valueFromExtension", children: {} }, + }); + }); +});