From 4db328999ba9b17ae9ac0e3c021a5949fa70ce97 Mon Sep 17 00:00:00 2001 From: lstocchi Date: Fri, 3 May 2024 10:45:50 +0200 Subject: [PATCH] fix: add tests for PreflightChecks Signed-off-by: lstocchi --- .../main/src/plugin/provider-registry.spec.ts | 216 +++++++++++++++++- .../src/lib/dashboard/PreflightChecks.spec.ts | 79 +++++++ .../src/lib/dashboard/PreflightChecks.svelte | 11 +- 3 files changed, 300 insertions(+), 6 deletions(-) create mode 100644 packages/renderer/src/lib/dashboard/PreflightChecks.spec.ts diff --git a/packages/main/src/plugin/provider-registry.spec.ts b/packages/main/src/plugin/provider-registry.spec.ts index 0bbaed415a9..218fdd8391a 100644 --- a/packages/main/src/plugin/provider-registry.spec.ts +++ b/packages/main/src/plugin/provider-registry.spec.ts @@ -19,16 +19,23 @@ /* eslint-disable @typescript-eslint/no-empty-function */ import type { + CheckResult, ContainerProviderConnection, + InstallCheck, KubernetesProviderConnection, ProviderCleanup, ProviderInstallation, ProviderUpdate, } from '@podman-desktop/api'; -import { beforeEach, expect, test, vi } from 'vitest'; +import { beforeEach, describe, expect, test, vi } from 'vitest'; import type { ApiSenderType } from './api.js'; -import type { ProviderContainerConnectionInfo, ProviderKubernetesConnectionInfo } from './api/provider-info.js'; +import type { + CheckStatus, + PreflightChecksCallback, + ProviderContainerConnectionInfo, + ProviderKubernetesConnectionInfo, +} from './api/provider-info.js'; import type { AutostartEngine } from './autostart-engine.js'; import type { ContainerProviderRegistry } from './container-registry.js'; import { LifecycleContextImpl } from './lifecycle-context.js'; @@ -783,3 +790,208 @@ test('registerUpdate should notify when an update is registered or unregistered' // check we have been notified expect(apiSenderSendMock).toBeCalledWith('provider-change', {}); }); + +describe('runPreflightChecks', () => { + test('throw error if there is no installation for the provider', async () => { + await expect(() => + providerRegistry.runPreflightChecks('id', {} as unknown as PreflightChecksCallback, true), + ).rejects.toThrowError('No matching installation for provider id'); + }); + test('return true if there are no preflightChecks', async () => { + providerRegistry.registerUpdate( + { + internalId: 'id', + } as unknown as ProviderImpl, + { + version: 'next', + preflightChecks: undefined, + update: async () => {}, + }, + ); + const run = await providerRegistry.runPreflightChecks('id', {} as unknown as PreflightChecksCallback, true); + expect(run).toBeTruthy(); + }); + test('callback called with checkResult having/not having docLinksDescription and return true if successful', async () => { + providerRegistry.registerUpdate( + { + internalId: 'id', + } as unknown as ProviderImpl, + { + version: 'next', + preflightChecks: (): InstallCheck[] => + [ + { + title: 'check-1', + execute: (): CheckResult => { + return { + title: 'title-1', + successful: true, + description: 'description-1', + } as CheckResult; + }, + }, + { + title: 'check-2', + execute: (): CheckResult => { + return { + title: 'title-2', + successful: true, + description: 'description-2', + docLinksDescription: 'doc-description-2', + docLinks: [ + { + title: 'link-2', + url: 'url-2', + }, + ], + } as CheckResult; + }, + }, + ] as unknown as InstallCheck[], + update: async () => {}, + }, + ); + const callback: PreflightChecksCallback = { + startCheck: (_status: CheckStatus) => {}, + endCheck: (_status: CheckStatus) => {}, + }; + const startCheckMock = vi.spyOn(callback, 'startCheck'); + const endCheckMock = vi.spyOn(callback, 'endCheck'); + const run = await providerRegistry.runPreflightChecks('id', callback, true); + + expect(startCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + }); + expect(endCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + successful: true, + description: 'description-1', + }); + expect(startCheckMock).toHaveBeenNthCalledWith(2, { + name: 'check-2', + }); + expect(endCheckMock).toHaveBeenNthCalledWith(2, { + name: 'check-2', + successful: true, + description: 'description-2', + docLinksDescription: 'doc-description-2', + docLinks: [ + { + title: 'link-2', + url: 'url-2', + }, + ], + }); + expect(run).toBeTruthy(); + }); + test('callback called with checkResult having/not having docLinksDescription and return false if not successful', async () => { + providerRegistry.registerUpdate( + { + internalId: 'id', + } as unknown as ProviderImpl, + { + version: 'next', + preflightChecks: (): InstallCheck[] => + [ + { + title: 'check-1', + execute: (): CheckResult => { + return { + title: 'title-1', + successful: true, + description: 'description-1', + } as CheckResult; + }, + }, + { + title: 'check-2', + execute: (): CheckResult => { + return { + title: 'title-2', + successful: false, + description: 'description-2', + docLinksDescription: 'doc-description-2', + docLinks: [ + { + title: 'link-2', + url: 'url-2', + }, + ], + } as CheckResult; + }, + }, + ] as unknown as InstallCheck[], + update: async () => {}, + }, + ); + const callback: PreflightChecksCallback = { + startCheck: (_status: CheckStatus) => {}, + endCheck: (_status: CheckStatus) => {}, + }; + const startCheckMock = vi.spyOn(callback, 'startCheck'); + const endCheckMock = vi.spyOn(callback, 'endCheck'); + const run = await providerRegistry.runPreflightChecks('id', callback, true); + + expect(startCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + }); + expect(endCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + successful: true, + description: 'description-1', + }); + expect(startCheckMock).toHaveBeenNthCalledWith(2, { + name: 'check-2', + }); + expect(endCheckMock).toHaveBeenNthCalledWith(2, { + name: 'check-2', + successful: false, + description: 'description-2', + docLinksDescription: 'doc-description-2', + docLinks: [ + { + title: 'link-2', + url: 'url-2', + }, + ], + }); + expect(run).toBeFalsy(); + }); + test('callback called with error checkResult if execution fails and return false', async () => { + providerRegistry.registerUpdate( + { + internalId: 'id', + } as unknown as ProviderImpl, + { + version: 'next', + preflightChecks: (): InstallCheck[] => + [ + { + title: 'check-1', + execute: (): CheckResult => { + throw new Error('error'); + }, + }, + ] as unknown as InstallCheck[], + update: async () => {}, + }, + ); + const callback: PreflightChecksCallback = { + startCheck: (_status: CheckStatus) => {}, + endCheck: (_status: CheckStatus) => {}, + }; + const startCheckMock = vi.spyOn(callback, 'startCheck'); + const endCheckMock = vi.spyOn(callback, 'endCheck'); + const run = await providerRegistry.runPreflightChecks('id', callback, true); + + expect(startCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + }); + expect(endCheckMock).toHaveBeenNthCalledWith(1, { + name: 'check-1', + successful: false, + description: 'error', + }); + expect(run).toBeFalsy(); + }); +}); diff --git a/packages/renderer/src/lib/dashboard/PreflightChecks.spec.ts b/packages/renderer/src/lib/dashboard/PreflightChecks.spec.ts new file mode 100644 index 00000000000..7080b1f9e78 --- /dev/null +++ b/packages/renderer/src/lib/dashboard/PreflightChecks.spec.ts @@ -0,0 +1,79 @@ +/********************************************************************** + * 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 '@testing-library/jest-dom/vitest'; + +import { render, screen } from '@testing-library/svelte'; +import { expect, test } from 'vitest'; + +import PreflightChecks from './PreflightChecks.svelte'; + +test('Expect preCheck to be displayed when having just title and description', async () => { + render(PreflightChecks, { + preflightChecks: [ + { + name: 'name', + description: 'description', + successful: true, + }, + ], + }); + + const title = screen.getByLabelText('precheck-title'); + expect(title).toBeInTheDocument(); + expect(title.textContent).equals('name'); + const description = screen.getByLabelText('precheck-description'); + expect(description).toBeInTheDocument(); + expect(description.textContent).equals('description'); + const docLinksDescription = screen.queryByLabelText('precheck-docLinksDescription'); + expect(docLinksDescription).not.toBeInTheDocument(); + const link = screen.queryByLabelText('precheck-link'); + expect(link).not.toBeInTheDocument(); +}); + +test('Expect preCheck to be displayed when having all props', async () => { + render(PreflightChecks, { + preflightChecks: [ + { + name: 'name', + description: 'description', + docLinksDescription: 'docLinkDescription', + docLinks: [ + { + title: 'link', + url: 'url', + }, + ], + successful: true, + }, + ], + }); + + const title = screen.getByLabelText('precheck-title'); + expect(title).toBeInTheDocument(); + expect(title.textContent).equals('name'); + const description = screen.getByLabelText('precheck-description'); + expect(description).toBeInTheDocument(); + expect(description.textContent).equals('description'); + const docLinksDescription = screen.getByLabelText('precheck-docLinksDescription'); + expect(docLinksDescription).toBeInTheDocument(); + expect(docLinksDescription.textContent).equals('docLinkDescription'); + const docLinks = screen.getByLabelText('precheck-link'); + expect(docLinks).toBeInTheDocument(); + expect(docLinks.textContent).equals('link'); + expect(docLinks.getAttribute('href')).equals('url'); +}); diff --git a/packages/renderer/src/lib/dashboard/PreflightChecks.svelte b/packages/renderer/src/lib/dashboard/PreflightChecks.svelte index 5f3841f82bc..2d4c43f32d4 100644 --- a/packages/renderer/src/lib/dashboard/PreflightChecks.svelte +++ b/packages/renderer/src/lib/dashboard/PreflightChecks.svelte @@ -23,19 +23,22 @@ function openLink(e: MouseEvent, url: string): void { {:else} {preCheck.successful ? '✅' : '❌'} {/if} -
{preCheck.name}
+
{preCheck.name}
{#if preCheck.description} - Details:

{preCheck.description}

+ Details:

+ {preCheck.description} +

{#if preCheck.docLinksDescription} -

+

{preCheck.docLinksDescription}

{/if} {#if preCheck.docLinks} See: {#each preCheck.docLinks as link} - {link.title} + {link.title} {/each} {/if} {/if}