From b0cfeb292ec22293c22f4012f781e47c75d168f4 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Thu, 19 Dec 2024 14:43:18 +0100 Subject: [PATCH] fix: kube health store is inactive in non experimental mode (#10415) * fix: kube health store is inactive in non experimental mode Signed-off-by: Philippe Martin * fix: do not use any Signed-off-by: Philippe Martin * fix: do not mark window methods as writable Signed-off-by: Philippe Martin * fix: move Object.defineProperty into beforeAll Signed-off-by: Philippe Martin --- ...netes-context-health-experimental.spec.ts} | 55 +++++++------ ...es-context-health-non-experimental.spec.ts | 77 +++++++++++++++++++ .../src/stores/kubernetes-context-health.ts | 10 +++ 3 files changed, 118 insertions(+), 24 deletions(-) rename packages/renderer/src/stores/{kubernetes-context-health.spec.ts => kubernetes-context-health-experimental.spec.ts} (65%) create mode 100644 packages/renderer/src/stores/kubernetes-context-health-non-experimental.spec.ts diff --git a/packages/renderer/src/stores/kubernetes-context-health.spec.ts b/packages/renderer/src/stores/kubernetes-context-health-experimental.spec.ts similarity index 65% rename from packages/renderer/src/stores/kubernetes-context-health.spec.ts rename to packages/renderer/src/stores/kubernetes-context-health-experimental.spec.ts index a5fddef57..ebe2ec21c 100644 --- a/packages/renderer/src/stores/kubernetes-context-health.spec.ts +++ b/packages/renderer/src/stores/kubernetes-context-health-experimental.spec.ts @@ -17,29 +17,32 @@ ***********************************************************************/ import { get } from 'svelte/store'; -import { expect, test, vi } from 'vitest'; +import { beforeAll, expect, test, vi } from 'vitest'; import { kubernetesContextsHealths, kubernetesContextsHealthsStore } from './kubernetes-context-health'; -const callbacks = new Map(); +const callbacks = new Map Promise>(); const eventEmitter = { - receive: (message: string, callback: any) => { + receive: (message: string, callback: () => Promise) => { callbacks.set(message, callback); }, }; -Object.defineProperty(global, 'window', { - value: { - kubernetesGetContextsHealths: vi.fn(), - addEventListener: eventEmitter.receive, - events: { - receive: eventEmitter.receive, +beforeAll(() => { + Object.defineProperty(global, 'window', { + value: { + kubernetesGetContextsHealths: vi.fn(), + getConfigurationValue: vi.fn(), + addEventListener: eventEmitter.receive, + events: { + receive: eventEmitter.receive, + }, }, - }, - writable: true, + }); }); -test('kubernetesContextsHealths', async () => { +test('kubernetesContextsHealths in experimental states mode', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(true); const initialValues = [ { contextName: 'context1', @@ -68,27 +71,31 @@ test('kubernetesContextsHealths', async () => { vi.mocked(window.kubernetesGetContextsHealths).mockResolvedValue(initialValues); - const kubernetesContextsHealthsInfo = kubernetesContextsHealthsStore.setup(); - await kubernetesContextsHealthsInfo.fetch(); - let currentValue = get(kubernetesContextsHealths); - expect(currentValue).toEqual(initialValues); + kubernetesContextsHealthsStore.setup(); // send 'extensions-already-started' event const callbackExtensionsStarted = callbacks.get('extensions-already-started'); expect(callbackExtensionsStarted).toBeDefined(); - await callbackExtensionsStarted(); + await callbackExtensionsStarted!(); + + await vi.waitFor(() => { + const currentValue = get(kubernetesContextsHealths); + expect(currentValue).toEqual(initialValues); + }, 500); + + // data has been updated in the backend + vi.mocked(window.kubernetesGetContextsHealths).mockResolvedValue(nextValues); // send an event indicating the data is updated const event = 'kubernetes-contexts-healths'; const callback = callbacks.get(event); expect(callback).toBeDefined(); - await callback(); - - // data has been updated in the backend - vi.mocked(window.kubernetesGetContextsHealths).mockResolvedValue(nextValues); + await callback!(); // check received data is updated - await kubernetesContextsHealthsInfo.fetch(); - currentValue = get(kubernetesContextsHealths); - expect(currentValue).toEqual(nextValues); + await vi.waitFor(() => { + const currentValue = get(kubernetesContextsHealths); + expect(currentValue).toEqual(nextValues); + }, 500); + expect(vi.mocked(window.kubernetesGetContextsHealths)).toHaveBeenCalled(); }); diff --git a/packages/renderer/src/stores/kubernetes-context-health-non-experimental.spec.ts b/packages/renderer/src/stores/kubernetes-context-health-non-experimental.spec.ts new file mode 100644 index 000000000..27bf769a5 --- /dev/null +++ b/packages/renderer/src/stores/kubernetes-context-health-non-experimental.spec.ts @@ -0,0 +1,77 @@ +/********************************************************************** + * Copyright (C) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import { get } from 'svelte/store'; +import { beforeAll, expect, test, vi } from 'vitest'; + +import { kubernetesContextsHealths, kubernetesContextsHealthsStore } from './kubernetes-context-health'; + +// We need to have separate tests files to run different tests, as there are global variables in the store file, which cannot be reset between tests + +// This file can be removed as soon as the experimental states mode is adopted as non experimental + +const callbacks = new Map Promise>(); +const eventEmitter = { + receive: (message: string, callback: () => Promise) => { + callbacks.set(message, callback); + }, +}; + +beforeAll(() => { + Object.defineProperty(global, 'window', { + value: { + kubernetesGetContextsHealths: vi.fn(), + getConfigurationValue: vi.fn(), + addEventListener: eventEmitter.receive, + events: { + receive: eventEmitter.receive, + }, + }, + }); +}); + +test('kubernetesContextsHealths not in experimental states mode', async () => { + vi.mocked(window.getConfigurationValue).mockResolvedValue(false); + const initialValues = [ + { + contextName: 'context1', + checking: true, + reachable: false, + }, + { + contextName: 'context2', + checking: false, + reachable: true, + }, + ]; + + vi.mocked(window.kubernetesGetContextsHealths).mockResolvedValue(initialValues); + + kubernetesContextsHealthsStore.setup(); + + // send 'extensions-already-started' event + const callbackExtensionsStarted = callbacks.get('extensions-already-started'); + expect(callbackExtensionsStarted).toBeDefined(); + await callbackExtensionsStarted!(); + + // values are never fetched + await new Promise(resolve => setTimeout(resolve, 500)); + const currentValue = get(kubernetesContextsHealths); + expect(currentValue).toEqual([]); + expect(vi.mocked(window.kubernetesGetContextsHealths)).not.toHaveBeenCalled(); +}); diff --git a/packages/renderer/src/stores/kubernetes-context-health.ts b/packages/renderer/src/stores/kubernetes-context-health.ts index 19bd302c4..15e7ce0f7 100644 --- a/packages/renderer/src/stores/kubernetes-context-health.ts +++ b/packages/renderer/src/stores/kubernetes-context-health.ts @@ -25,8 +25,18 @@ import { EventStore } from './event-store'; const windowEvents = ['kubernetes-contexts-healths', 'extension-stopped', 'extensions-started']; const windowListeners = ['extensions-already-started']; +let experimentalStates: boolean | undefined = undefined; let readyToUpdate = false; + export async function checkForUpdate(eventName: string): Promise { + // check for update only in experimental states mode + if (experimentalStates === undefined) { + experimentalStates = (await window.getConfigurationValue('kubernetes.statesExperimental')) ?? false; + } + if (experimentalStates === false) { + return false; + } + if ('extensions-already-started' === eventName) { readyToUpdate = true; }