diff --git a/packages/backend/src/registries/ContainerRegistry.spec.ts b/packages/backend/src/registries/ContainerRegistry.spec.ts index 3e0eaac82..1adf180f4 100644 --- a/packages/backend/src/registries/ContainerRegistry.spec.ts +++ b/packages/backend/src/registries/ContainerRegistry.spec.ts @@ -15,9 +15,9 @@ * * SPDX-License-Identifier: Apache-2.0 ***********************************************************************/ -import { expect, test, vi } from 'vitest'; +import { beforeEach, expect, test, vi } from 'vitest'; import { ContainerRegistry } from './ContainerRegistry'; -import type { ContainerJSONEvent } from '@podman-desktop/api'; +import { type ContainerJSONEvent, EventEmitter } from '@podman-desktop/api'; const mocks = vi.hoisted(() => ({ onEventMock: vi.fn(), @@ -26,6 +26,7 @@ const mocks = vi.hoisted(() => ({ vi.mock('@podman-desktop/api', async () => { return { + EventEmitter: vi.fn(), Disposable: { create: mocks.DisposableCreateMock, }, @@ -35,6 +36,20 @@ vi.mock('@podman-desktop/api', async () => { }; }); +beforeEach(() => { + const listeners: ((value: unknown) => void)[] = []; + const eventSubscriber = (listener: (value: unknown) => void) => { + listeners.push(listener); + }; + const fire = (value: unknown) => { + listeners.forEach(listener => listener(value)); + }; + vi.mocked(EventEmitter).mockReturnValue({ + event: eventSubscriber, + fire: fire, + } as unknown as EventEmitter); +}); + test('ContainerRegistry init', () => { const registry = new ContainerRegistry(); registry.init(); @@ -121,3 +136,29 @@ test('ContainerRegistry subscriber disposed should not be called', () => { // never should have been called expect(subscribeMock).toHaveBeenCalledTimes(0); }); + +test('ContainerRegistry should fire ContainerStart when container start', () => { + // Get the callback created by the ContainerRegistry + let callback: (event: ContainerJSONEvent) => void; + mocks.onEventMock.mockImplementation((method: (event: ContainerJSONEvent) => void) => { + callback = method; + }); + + // Create the ContainerRegistry and init + const registry = new ContainerRegistry(); + registry.init(); + + const startListenerMock = vi.fn(); + registry.onStartContainerEvent(startListenerMock); + + // Generate a remove event + callback({ status: 'remove', id: 'random', type: 'container' }); + + expect(startListenerMock).not.toHaveBeenCalled(); + + // Call it a second time + callback({ status: 'start', id: 'random', type: 'container' }); + + // Our subscriber should only have been called once, the first, after it should have been removed. + expect(startListenerMock).toHaveBeenCalledOnce(); +}); diff --git a/packages/backend/src/registries/ContainerRegistry.ts b/packages/backend/src/registries/ContainerRegistry.ts index 29aa7beb7..a1622d5f6 100644 --- a/packages/backend/src/registries/ContainerRegistry.ts +++ b/packages/backend/src/registries/ContainerRegistry.ts @@ -22,12 +22,25 @@ export type Subscriber = { callback: (status: string) => void; }; +export interface ContainerStart { + id: string; +} + export class ContainerRegistry { private count: number = 0; private subscribers: Map = new Map(); + private readonly _onStartContainerEvent = new podmanDesktopApi.EventEmitter(); + readonly onStartContainerEvent: podmanDesktopApi.Event = this._onStartContainerEvent.event; + init(): podmanDesktopApi.Disposable { return podmanDesktopApi.containerEngine.onEvent(event => { + if (event.status === 'start') { + this._onStartContainerEvent.fire({ + id: event.id, + }); + } + if (this.subscribers.has(event.id)) { this.subscribers.get(event.id).forEach(subscriber => subscriber.callback(event.status));