diff --git a/packages/backend/src/registries/ContainerRegistry.spec.ts b/packages/backend/src/registries/ContainerRegistry.spec.ts new file mode 100644 index 000000000..9928ad4e6 --- /dev/null +++ b/packages/backend/src/registries/ContainerRegistry.spec.ts @@ -0,0 +1,123 @@ +/********************************************************************** + * 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 { expect, test, vi } from 'vitest'; +import { ContainerRegistry } from './ContainerRegistry'; +import { ContainerJSONEvent } from '@podman-desktop/api'; + +const mocks = vi.hoisted(() => ({ + onEventMock: vi.fn(), + DisposableCreateMock: vi.fn(), +})); + +vi.mock('@podman-desktop/api', async () => { + return { + Disposable: { + create: mocks.DisposableCreateMock, + }, + containerEngine: { + onEvent: mocks.onEventMock, + }, + }; +}); + +test('ContainerRegistry init', () => { + const registry = new ContainerRegistry(); + registry.init(); + + expect(mocks.onEventMock).toHaveBeenCalledOnce(); +}); + +test('ContainerRegistry subscribe', () => { + // 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(); + + // Let's create a dummy subscriber + let subscribedStatus: undefined | string = undefined; + registry.subscribe('random', (status: string) => { + subscribedStatus = status; + }); + + // Generate a fake event + callback({ + status: 'die', + id: 'random', + type: 'container', + }); + + expect(subscribedStatus).toBe('die'); + expect(mocks.DisposableCreateMock).toHaveBeenCalledOnce(); +}); + +test('ContainerRegistry unsubscribe all if container remove', () => { + // 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(); + + // Let's create a dummy subscriber + const subscribeMock = vi.fn(); + registry.subscribe('random', subscribeMock); + + // Generate a remove event + callback({ status: 'remove', id: 'random', type: 'container' }); + + // Call it a second time + callback({ status: 'remove', id: 'random', type: 'container' }); + + // Our subscriber should only have been called once, the first, after it should have been removed. + expect(subscribeMock).toHaveBeenCalledOnce(); +}); + +test('ContainerRegistry subscriber disposed should not be called', () => { + // Get the callback created by the ContainerRegistry + let callback: (event: ContainerJSONEvent) => void; + mocks.onEventMock.mockImplementation((method: (event: ContainerJSONEvent) => void) => { + callback = method; + }); + + mocks.DisposableCreateMock.mockImplementation(callback => ({ + dispose: () => callback(), + })); + + // Create the ContainerRegistry and init + const registry = new ContainerRegistry(); + registry.init(); + + // Let's create a dummy subscriber + const subscribeMock = vi.fn(); + const disposable = registry.subscribe('random', subscribeMock); + disposable.dispose(); + + // Generate a random event + callback({ status: 'die', id: 'random', type: 'container' }); + + // never should have been called + expect(subscribeMock).toHaveBeenCalledTimes(0); +}); diff --git a/packages/backend/src/registries/ContainerRegistry.ts b/packages/backend/src/registries/ContainerRegistry.ts index cd8e9aacc..29aa7beb7 100644 --- a/packages/backend/src/registries/ContainerRegistry.ts +++ b/packages/backend/src/registries/ContainerRegistry.ts @@ -32,7 +32,7 @@ export class ContainerRegistry { this.subscribers.get(event.id).forEach(subscriber => subscriber.callback(event.status)); // If the event type is remove, we dispose all subscribers for the specific containers - if (event.type === 'remove') { + if (event.status === 'remove') { this.subscribers.delete(event.id); } }