fix: add tests for PreflightChecks

Signed-off-by: lstocchi <lstocchi@redhat.com>
This commit is contained in:
lstocchi 2024-05-03 10:45:50 +02:00 committed by Florent BENOIT
parent 10b8e7d305
commit 4db328999b
3 changed files with 300 additions and 6 deletions

View file

@ -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();
});
});

View file

@ -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');
});

View file

@ -23,19 +23,22 @@ function openLink(e: MouseEvent, url: string): void {
{:else}
{preCheck.successful ? '✅' : '❌'}
{/if}
<div class="ml-2">{preCheck.name}</div>
<div aria-label="precheck-title" class="ml-2">{preCheck.name}</div>
</div>
{#if preCheck.description}
Details: <p class="text-gray-400 w-full break-all">{preCheck.description}</p>
Details: <p aria-label="precheck-description" class="text-gray-400 w-full break-all">
{preCheck.description}
</p>
{#if preCheck.docLinksDescription}
<p class="text-gray-400 w-full">
<p aria-label="precheck-docLinksDescription" class="text-gray-400 w-full">
{preCheck.docLinksDescription}
</p>
{/if}
{#if preCheck.docLinks}
See:
{#each preCheck.docLinks as link}
<a href="{link.url}" target="_blank" on:click="{e => openLink(e, link.url)}">{link.title}</a>
<a aria-label="precheck-link" href="{link.url}" target="_blank" on:click="{e => openLink(e, link.url)}"
>{link.title}</a>
{/each}
{/if}
{/if}