diff --git a/packages/main/src/plugin/api.ts b/packages/main/src/plugin/api.ts index 3c4553934c3f..7e30add9f26f 100644 --- a/packages/main/src/plugin/api.ts +++ b/packages/main/src/plugin/api.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -17,6 +17,7 @@ ***********************************************************************/ import type { ContainerInfo } from './api/container-info.js'; +import type { IDisposable } from './types/disposable.js'; export interface RemoteAPI { // eslint-disable-next-line @typescript-eslint/ban-types @@ -24,8 +25,6 @@ export interface RemoteAPI { } export type ApiSenderType = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - send: (channel: string, data?: any) => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - receive: (channel: string, func: any) => void; + send: (channel: string, data?: unknown) => void; + receive: (channel: string, func: (...args: unknown[]) => void) => IDisposable; }; diff --git a/packages/main/src/plugin/container-registry.ts b/packages/main/src/plugin/container-registry.ts index d90df0221e9c..5a50b66898fa 100644 --- a/packages/main/src/plugin/container-registry.ts +++ b/packages/main/src/plugin/container-registry.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022-2023 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -200,24 +200,24 @@ export class ContainerProviderRegistry { } setupListeners() { - const cleanStreamMap = (containerId: string) => { - this.streamsPerContainerId.delete(containerId); - this.streamsOutputPerContainerId.delete(containerId); + const cleanStreamMap = (containerId: unknown) => { + this.streamsPerContainerId.delete(String(containerId)); + this.streamsOutputPerContainerId.delete(String(containerId)); }; - this.apiSender.receive('container-stopped-event', (containerId: string) => { + this.apiSender.receive('container-stopped-event', (containerId: unknown) => { cleanStreamMap(containerId); }); - this.apiSender.receive('container-die-event', (containerId: string) => { + this.apiSender.receive('container-die-event', (containerId: unknown) => { cleanStreamMap(containerId); }); - this.apiSender.receive('container-kill-event', (containerId: string) => { + this.apiSender.receive('container-kill-event', (containerId: unknown) => { cleanStreamMap(containerId); }); - this.apiSender.receive('container-removed-event', (containerId: string) => { + this.apiSender.receive('container-removed-event', (containerId: unknown) => { cleanStreamMap(containerId); }); } diff --git a/packages/main/src/plugin/contribution-manager.spec.ts b/packages/main/src/plugin/contribution-manager.spec.ts index 021b4f45162c..12c0b4264e0c 100644 --- a/packages/main/src/plugin/contribution-manager.spec.ts +++ b/packages/main/src/plugin/contribution-manager.spec.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -32,6 +32,7 @@ import type { RunResult } from '@podman-desktop/api'; import { EventEmitter } from 'stream-json/Assembler.js'; import type { ContributionInfo } from './api/contribution-info.js'; import type { Proxy } from './proxy.js'; +import type { IDisposable } from './types/disposable.js'; let contributionManager: TestContributionManager; let composeFileExample: any; @@ -42,14 +43,17 @@ const portNumber = 10000; const eventEmitter = new EventEmitter(); -const send = (channel: string, data?: any) => { +const send = (channel: string, data?: unknown) => { eventEmitter.emit(channel, data); }; -const receive = (channel: string, func: any) => { - eventEmitter.on(channel, data => { - func(data); - }); +const receive = (channel: string, func: any): IDisposable => { + eventEmitter.on(channel, func); + return { + dispose: () => { + eventEmitter.off(channel, func); + }, + } as unknown as IDisposable; }; const apiSender: ApiSenderType = { diff --git a/packages/main/src/plugin/index.ts b/packages/main/src/plugin/index.ts index 8a04f0a74c9d..99a4f4348fb9 100644 --- a/packages/main/src/plugin/index.ts +++ b/packages/main/src/plugin/index.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022-2023 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -149,6 +149,7 @@ import type { KubeContext } from './kubernetes-context.js'; import { KubernetesInformerManager } from './kubernetes-informer-registry.js'; import type { KubernetesInformerResourcesType } from './api/kubernetes-informer-info.js'; import { OpenDevToolsInit } from './open-devtools-init.js'; +import type { IDisposable } from './types/disposable.js'; type LogType = 'log' | 'warn' | 'trace' | 'debug' | 'error'; @@ -286,7 +287,7 @@ export class PluginSystem { } getApiSender(webContents: WebContents): ApiSenderType { - const queuedEvents: { channel: string; data: string }[] = []; + const queuedEvents: { channel: string; data: unknown }[] = []; const flushQueuedEvents = () => { // flush queued events ? @@ -307,8 +308,7 @@ export class PluginSystem { const eventEmitter = new EventEmitter(); return { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - send: (channel: string, data: any) => { + send: (channel: string, data: unknown) => { // send only when the UI is ready if (this.uiReady && this.isReady) { flushQueuedEvents(); @@ -319,11 +319,13 @@ export class PluginSystem { } eventEmitter.emit(channel, data); }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - receive: (channel: string, func: any) => { - eventEmitter.on(channel, data => { - func(data); - }); + receive: (channel: string, func: (...args: unknown[]) => void): IDisposable => { + eventEmitter.on(channel, func); + return { + dispose: () => { + eventEmitter.removeListener(channel, func); + }, + }; }, }; } diff --git a/packages/main/src/plugin/kubernetes-client-kubeconfig.spec.ts b/packages/main/src/plugin/kubernetes-client-kubeconfig.spec.ts index 728436667d16..6fefbb013269 100644 --- a/packages/main/src/plugin/kubernetes-client-kubeconfig.spec.ts +++ b/packages/main/src/plugin/kubernetes-client-kubeconfig.spec.ts @@ -1,3 +1,21 @@ +/********************************************************************** + * Copyright (C) 2023-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 type { Cluster, Context, User, KubeConfig } from '@kubernetes/client-node'; import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import type { ConfigurationRegistry } from './configuration-registry.js'; @@ -52,7 +70,7 @@ describe('context tests', () => { } as unknown as Telemetry; const apiSender: ApiSenderType = { send: apiSendMock, - receive: () => {}, + receive: vi.fn(), }; const client = new TestKubernetesClient( diff --git a/packages/preload/src/index.spec.ts b/packages/preload/src/index.spec.ts new file mode 100644 index 000000000000..2c957b102dec --- /dev/null +++ b/packages/preload/src/index.spec.ts @@ -0,0 +1,71 @@ +/********************************************************************** + * 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 { beforeEach, expect, test, vi } from 'vitest'; +import { buildApiSender } from '.'; + +vi.mock('electron', async () => { + return { + contextBridge: { + exposeInMainWorld: vi.fn(), + }, + ipcRenderer: { + on: vi.fn(), + emit: vi.fn(), + handle: vi.fn(), + }, + ipcMain: { + on: vi.fn(), + emit: vi.fn(), + handle: vi.fn(), + }, + }; +}); + +beforeEach(() => { + vi.resetAllMocks(); +}); + +test('build Api Sender', () => { + const apiSender = buildApiSender(); + + expect(apiSender).toBeDefined(); + + // add a receiver + const received: string[] = []; + const disposable = apiSender.receive('channel', (...val: unknown[]) => { + received.push(String(val)); + }); + + // send a message + apiSender.send('channel', 'message'); + expect(received.length).toBe(1); + expect(received[0]).toBe('message'); + + // send another message + apiSender.send('channel', 'message2'); + expect(received.length).toBe(2); + expect(received[1]).toBe('message2'); + + // dispose the receiver + disposable.dispose(); + + // send another message + apiSender.send('channel', 'message3'); + // should not be received anymore as we disposed the listener + expect(received.length).toBe(2); +}); diff --git a/packages/preload/src/index.ts b/packages/preload/src/index.ts index 0a0ba0861f05..326c3d3ccc78 100644 --- a/packages/preload/src/index.ts +++ b/packages/preload/src/index.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022-2023 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -90,6 +90,8 @@ import type { KubeContext } from '../../main/src/plugin/kubernetes-context'; import type { KubernetesGeneratorInfo } from '../../main/src/plugin/api/KubernetesGeneratorInfo'; import type { NotificationCard, NotificationCardOptions } from '../../main/src/plugin/api/notification'; +import type { ApiSenderType } from '../../main/src/plugin/api'; +import type { IDisposable } from '../../main/src/plugin/types/disposable'; export type DialogResultCallback = (openDialogReturnValue: Electron.OpenDialogReturnValue) => void; @@ -112,21 +114,27 @@ export interface KeyLogger { warn(key: symbol, ...data: any[]): void; } -// initialize extension loader mechanism -function initExposure(): void { +export const buildApiSender = (): ApiSenderType => { const eventEmitter = new EventEmitter(); - const apiSender = { - send: (channel: string, data: string) => { + + return { + send: (channel: string, data: unknown) => { eventEmitter.emit(channel, data); }, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - // eslint-disable-next-line @typescript-eslint/no-explicit-any - receive: (channel: string, func: any) => { - eventEmitter.on(channel, data => { - func(data); - }); + receive: (channel: string, func: (...args: unknown[]) => void): IDisposable => { + eventEmitter.on(channel, func); + return { + dispose: () => { + eventEmitter.removeListener(channel, func); + }, + }; }, }; +}; + +// initialize extension loader mechanism +function initExposure(): void { + const apiSender = buildApiSender(); interface ErrorMessage { name: string; diff --git a/packages/renderer/src/Loader.svelte b/packages/renderer/src/Loader.svelte index 6e04b2d4ca58..f829f8aa99ba 100644 --- a/packages/renderer/src/Loader.svelte +++ b/packages/renderer/src/Loader.svelte @@ -72,7 +72,7 @@ window.events?.receive('install-extension:from-id', (extensionId: any) => { }); // Wait that the server-side is ready -window.events.receive('starting-extensions', (value: string) => { +window.events.receive('starting-extensions', (value: unknown) => { systemReady = value === 'true'; if (systemReady) { window.dispatchEvent(new CustomEvent('system-ready', {})); diff --git a/packages/renderer/src/lib/dialogs/CustomPick.svelte b/packages/renderer/src/lib/dialogs/CustomPick.svelte index 876ffbe0d22e..d5df27f35715 100644 --- a/packages/renderer/src/lib/dialogs/CustomPick.svelte +++ b/packages/renderer/src/lib/dialogs/CustomPick.svelte @@ -29,7 +29,8 @@ onMount(() => { window.events?.receive('showCustomPick:add', showCustomPickCallback); }); -async function showCustomPickCallback(options?: CustomPickOptions) { +function showCustomPickCallback(customQuickPickParameter: unknown) { + const options: CustomPickOptions | undefined = customQuickPickParameter as CustomPickOptions; id = options?.id || 0; title = options?.title || ''; description = options?.description || ''; diff --git a/packages/renderer/src/lib/dialogs/MessageBox.svelte b/packages/renderer/src/lib/dialogs/MessageBox.svelte index c4c01f6ef086..d16e96233f52 100644 --- a/packages/renderer/src/lib/dialogs/MessageBox.svelte +++ b/packages/renderer/src/lib/dialogs/MessageBox.svelte @@ -23,7 +23,8 @@ let display = false; let inputElement: HTMLInputElement | undefined = undefined; let messageBox: HTMLDivElement; -const showMessageBoxCallback = async (options?: MessageBoxOptions) => { +const showMessageBoxCallback = (messageBoxParameter: unknown) => { + const options: MessageBoxOptions | undefined = messageBoxParameter as MessageBoxOptions; currentId = options?.id || 0; title = options?.title || ''; message = options?.message || ''; @@ -74,11 +75,15 @@ const showMessageBoxCallback = async (options?: MessageBoxOptions) => { display = true; - await tick(); - - if (display && inputElement) { - inputElement.focus(); - } + tick() + .then(() => { + if (display && inputElement) { + inputElement.focus(); + } + }) + .catch((error: unknown) => { + console.error('Unable to focus on input element', error); + }); }; onMount(() => { diff --git a/packages/renderer/src/lib/dialogs/QuickPickInput.svelte b/packages/renderer/src/lib/dialogs/QuickPickInput.svelte index dc481dae681b..0518aafc3da5 100644 --- a/packages/renderer/src/lib/dialogs/QuickPickInput.svelte +++ b/packages/renderer/src/lib/dialogs/QuickPickInput.svelte @@ -32,7 +32,8 @@ let quickPickCanPickMany = false; let inputElement: HTMLInputElement | HTMLTextAreaElement | undefined = undefined; let outerDiv: HTMLDivElement | undefined = undefined; -const showInputCallback = async (options?: InputBoxOptions) => { +const showInputCallback = (inputCallpackParameter: unknown) => { + const options: InputBoxOptions | undefined = inputCallpackParameter as InputBoxOptions; mode = 'InputBox'; inputValue = options?.value; placeHolder = options?.placeHolder; @@ -48,17 +49,22 @@ const showInputCallback = async (options?: InputBoxOptions) => { validationEnabled = options?.validate || false; display = true; - await tick(); - - if (display && inputElement) { - inputElement.focus(); - if (options?.valueSelection) { - inputElement.setSelectionRange(options.valueSelection[0], options.valueSelection[1]); - } - } + tick() + .then(() => { + if (display && inputElement) { + inputElement.focus(); + if (options?.valueSelection) { + inputElement.setSelectionRange(options.valueSelection[0], options.valueSelection[1]); + } + } + }) + .catch((error: unknown) => { + console.error('Unable to focus/select input box', error); + }); }; -const showQuickPickCallback = async (options?: QuickPickOptions) => { +const showQuickPickCallback = (quickpickParameter: unknown) => { + const options: QuickPickOptions | undefined = quickpickParameter as QuickPickOptions; mode = 'QuickPick'; placeHolder = options?.placeHolder; title = options?.title; @@ -96,11 +102,15 @@ const showQuickPickCallback = async (options?: QuickPickOptions) => { display = true; - await tick(); - - if (display && inputElement) { - inputElement.focus(); - } + tick() + .then(() => { + if (display && inputElement) { + inputElement.focus(); + } + }) + .catch((error: unknown) => { + console.error('Unable to focus input box', error); + }); }; onMount(() => { diff --git a/packages/renderer/src/lib/toast/ToastHandler.svelte b/packages/renderer/src/lib/toast/ToastHandler.svelte index d9d2cc78e809..bba9af0bf599 100644 --- a/packages/renderer/src/lib/toast/ToastHandler.svelte +++ b/packages/renderer/src/lib/toast/ToastHandler.svelte @@ -43,8 +43,9 @@ onMount(() => { toast.push(object.message, { pausable: true, theme }); }; - window.events?.receive('toast:handler', (object: { type: string; message: string }) => { - callback(object); + window.events?.receive('toast:handler', (object: unknown) => { + const value = object as { type: string; message: string }; + callback(value); }); }); diff --git a/packages/renderer/src/stores/configurationProperties.ts b/packages/renderer/src/stores/configurationProperties.ts index a5807b03db30..5462844110cb 100644 --- a/packages/renderer/src/stores/configurationProperties.ts +++ b/packages/renderer/src/stores/configurationProperties.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022-2023 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -63,8 +63,8 @@ class ConfigurationChangeEvent extends CustomEvent { export function setupConfigurationChange() { // be notified when a specific property is being changed - window.events?.receive('onDidChangeConfiguration', async (data: IConfigurationChangeEvent) => { - onDidChangeConfiguration.dispatchEvent(new ConfigurationChangeEvent(data)); + window.events?.receive('onDidChangeConfiguration', (data: unknown) => { + onDidChangeConfiguration.dispatchEvent(new ConfigurationChangeEvent(data as IConfigurationChangeEvent)); }); } diff --git a/packages/renderer/src/stores/context.ts b/packages/renderer/src/stores/context.ts index 74b1c6ff3806..6eb3d0abe4ab 100644 --- a/packages/renderer/src/stores/context.ts +++ b/packages/renderer/src/stores/context.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -22,16 +22,18 @@ import { ContextUI } from '../lib/context/context'; export const context: Writable = writable(new ContextUI()); -window.events?.receive('context-value-updated', async (value: { key: string; value: string }) => { +window.events?.receive('context-value-updated', (value: unknown) => { + const typedValue = value as { key: string; value: string }; context.update(ctx => { - ctx.setValue(value.key, value.value); + ctx.setValue(typedValue.key, typedValue.value); return ctx; }); }); -window.events?.receive('context-key-removed', async (value: { key: string; value: string }) => { +window.events?.receive('context-key-removed', (value: unknown) => { + const typedValue = value as { key: string; value: string }; context.update(ctx => { - ctx.removeValue(value.key); + ctx.removeValue(typedValue.key); return ctx; }); }); diff --git a/packages/renderer/src/stores/event-store.spec.ts b/packages/renderer/src/stores/event-store.spec.ts index 3534c9b0c3ca..dd87a9c304ec 100644 --- a/packages/renderer/src/stores/event-store.spec.ts +++ b/packages/renderer/src/stores/event-store.spec.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2022 Red Hat, Inc. + * Copyright (C) 2022-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. @@ -90,6 +90,11 @@ test('should call fetch method using window event', async () => { await callback(); + // wait updater method being called + while (updater.mock.calls.length === 0) { + await new Promise(resolve => setTimeout(resolve, 100)); + } + // check the updater is called expect(updater).toHaveBeenCalled(); @@ -228,6 +233,11 @@ test('should call fetch method using window event and object argument', async () await callback({}); + // wait updater method being called + while (updater.mock.calls.length === 0) { + await new Promise(resolve => setTimeout(resolve, 100)); + } + // check the updater is called expect(updater).toHaveBeenCalledWith({}); }); diff --git a/packages/renderer/src/stores/event-store.ts b/packages/renderer/src/stores/event-store.ts index 3e1474458032..537c01535d1c 100644 --- a/packages/renderer/src/stores/event-store.ts +++ b/packages/renderer/src/stores/event-store.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -258,8 +258,10 @@ export class EventStore { }; this.windowEvents.forEach(eventName => { - window.events?.receive(eventName, async (args?: unknown[]) => { - await update(eventName, args); + window.events?.receive(eventName, (args?: unknown) => { + update(eventName, args as unknown[]).catch((error: unknown) => { + console.error(`Failed to update ${this.name}`, error); + }); }); }); diff --git a/packages/renderer/src/stores/kubernetes-informer-event-store.ts b/packages/renderer/src/stores/kubernetes-informer-event-store.ts index 3b5145ce5785..f7d8b041c02c 100644 --- a/packages/renderer/src/stores/kubernetes-informer-event-store.ts +++ b/packages/renderer/src/stores/kubernetes-informer-event-store.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -38,13 +38,13 @@ export class EventStoreWithKubernetesInformer { setup() { this.informerEvents.forEach(eventName => { - window.events?.receive(eventName, async (args?: unknown[]) => { + window.events?.receive(eventName, (args: unknown) => { this.informerListener(eventName, args); }); }); this.informerRefreshEvents.forEach(eventName => { - window.events?.receive(eventName, async (_args?: unknown[]) => { + window.events?.receive(eventName, (_: unknown) => { const informerId = this.store.getInformerId(); if (informerId) { window.kubernetesRefreshInformer(informerId); @@ -52,7 +52,7 @@ export class EventStoreWithKubernetesInformer { }); }); - window.events?.receive(`kubernetes-informer-refresh`, async (id: number) => { + window.events?.receive(`kubernetes-informer-refresh`, (id: unknown) => { const informerId = this.store.getInformerId(); // if informer has been refreshed we reset the store, most probably the kubeconfig changed and we're connected to a new namespace/cluster if (informerId === id) { diff --git a/packages/renderer/src/stores/notifications.spec.ts b/packages/renderer/src/stores/notifications.spec.ts index ccbd0d3c0963..1cbff0c18284 100644 --- a/packages/renderer/src/stores/notifications.spec.ts +++ b/packages/renderer/src/stores/notifications.spec.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -83,6 +83,9 @@ test('notifications should be updated in case of an extension is stopped', async expect(extensionStoppedCallback).toBeDefined(); await extensionStoppedCallback(); + // wait a little + await new Promise(resolve => setTimeout(resolve, 100)); + // check if the notifications are updated const notificationQueue2 = get(notificationQueue); expect(notificationQueue2.length).toBe(0); diff --git a/packages/renderer/src/stores/onboarding.spec.ts b/packages/renderer/src/stores/onboarding.spec.ts index 4f7d3a8c48a8..e5d1ff72e1db 100644 --- a/packages/renderer/src/stores/onboarding.spec.ts +++ b/packages/renderer/src/stores/onboarding.spec.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -82,6 +82,9 @@ test('onboarding should be updated in case of an extension is stopped', async () expect(extensionStoppedCallback).toBeDefined(); await extensionStoppedCallback(); + // wait a little + await new Promise(resolve => setTimeout(resolve, 100)); + // check if the onboardings are updated const onboardingList2 = get(onboardingList); expect(onboardingList2.length).toBe(0); diff --git a/packages/renderer/src/stores/tasks.ts b/packages/renderer/src/stores/tasks.ts index 3c550cea8fa7..0a746904bc52 100644 --- a/packages/renderer/src/stores/tasks.ts +++ b/packages/renderer/src/stores/tasks.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -64,14 +64,14 @@ export function createTask(name: string): StatefulTask { return task; } -window.events?.receive('task-created', (task: Task) => { - tasksInfo.update(tasks => [...tasks, task]); +window.events?.receive('task-created', (task: unknown) => { + tasksInfo.update(tasks => [...tasks, task as Task]); }); -window.events?.receive('task-updated', (task: Task) => { - updateTask(task); +window.events?.receive('task-updated', (task: unknown) => { + updateTask(task as Task); }); -window.events?.receive('task-removed', (task: Task) => { - removeTask(task.id); +window.events?.receive('task-removed', (task: unknown) => { + removeTask((task as Task).id); }); export function isStatefulTask(task: Task): task is StatefulTask { diff --git a/packages/renderer/src/stores/view.spec.ts b/packages/renderer/src/stores/view.spec.ts index 3cf73b8a4fe3..c0fe6f251b29 100644 --- a/packages/renderer/src/stores/view.spec.ts +++ b/packages/renderer/src/stores/view.spec.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * Copyright (C) 2023-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. @@ -82,6 +82,9 @@ test('views should be updated in case of an extension is stopped', async () => { expect(extensionStoppedCallback).toBeDefined(); await extensionStoppedCallback(); + // wait a little + await new Promise(resolve => setTimeout(resolve, 100)); + // check if the volumes are updated const views2 = get(viewsContributions); expect(views2.length).toBe(0); diff --git a/packages/renderer/src/stores/views.spec.ts b/packages/renderer/src/stores/views.spec.ts index 3cf73b8a4fe3..208c0f303009 100644 --- a/packages/renderer/src/stores/views.spec.ts +++ b/packages/renderer/src/stores/views.spec.ts @@ -82,6 +82,9 @@ test('views should be updated in case of an extension is stopped', async () => { expect(extensionStoppedCallback).toBeDefined(); await extensionStoppedCallback(); + // wait a little + await new Promise(resolve => setTimeout(resolve, 100)); + // check if the volumes are updated const views2 = get(viewsContributions); expect(views2.length).toBe(0);