Skip to content

Commit

Permalink
tests: ensuring everything is properly tested
Browse files Browse the repository at this point in the history
Signed-off-by: axel7083 <[email protected]>
  • Loading branch information
axel7083 committed Feb 5, 2025
1 parent 7684338 commit f7fab21
Show file tree
Hide file tree
Showing 7 changed files with 444 additions and 1 deletion.
76 changes: 76 additions & 0 deletions packages/backend/src/apis/quadlet-api-impl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**********************************************************************
* Copyright (C) 2025 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, beforeEach } from 'vitest';
import { QuadletApiImpl } from './quadlet-api-impl';
import type { QuadletService } from '../services/quadlet-service';
import type { SystemdService } from '../services/systemd-service';
import type { PodmanService } from '../services/podman-service';
import type { ProviderService } from '../services/provider-service';
import type { LoggerService } from '../services/logger-service';
import type { ProviderContainerConnection } from '@podman-desktop/api';
import type { ProviderContainerConnectionIdentifierInfo } from '/@shared/src/models/provider-container-connection-identifier-info';

const QUADLET_SERVICE: QuadletService = {
getKubeYAML: vi.fn(),
} as unknown as QuadletService;
const SYSTEMD_SERVICE: SystemdService = {} as unknown as SystemdService;
const PODMAN_SERVICE: PodmanService = {} as unknown as PodmanService;
const PROVIDER_SERVICE: ProviderService = {
getProviderContainerConnection: vi.fn(),
} as unknown as ProviderService;
const LOGGER_SERVICE: LoggerService = {} as unknown as LoggerService;

const WSL_PROVIDER_CONNECTION_MOCK: ProviderContainerConnection = {
connection: {
type: 'podman',
vmType: 'WSL',
name: 'podman-machine-default',
},
providerId: 'podman',
} as ProviderContainerConnection;

const WSL_PROVIDER_IDENTIFIER: ProviderContainerConnectionIdentifierInfo = {
name: WSL_PROVIDER_CONNECTION_MOCK.connection.name,
providerId: WSL_PROVIDER_CONNECTION_MOCK.providerId,
};

beforeEach(() => {
vi.resetAllMocks();

vi.mocked(PROVIDER_SERVICE.getProviderContainerConnection).mockReturnValue(WSL_PROVIDER_CONNECTION_MOCK);
});

function getQuadletApiImpl(): QuadletApiImpl {
return new QuadletApiImpl({
quadlet: QUADLET_SERVICE,
systemd: SYSTEMD_SERVICE,
podman: PODMAN_SERVICE,
providers: PROVIDER_SERVICE,
loggerService: LOGGER_SERVICE,
});
}

test('QuadletApiImpl#getKubeYAML should propagate result from QuadletService#getKubeYAML', async () => {
vi.mocked(QUADLET_SERVICE.getKubeYAML).mockResolvedValue('dummy-yaml-content');

const api = getQuadletApiImpl();

const result = await api.getKubeYAML(WSL_PROVIDER_IDENTIFIER, 'dummy-quadlet-id');
expect(result).toStrictEqual('dummy-yaml-content');
expect(PROVIDER_SERVICE.getProviderContainerConnection).toHaveBeenCalledWith(WSL_PROVIDER_IDENTIFIER);
});
37 changes: 37 additions & 0 deletions packages/backend/src/utils/parsers/quadlet-kube-parser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**********************************************************************
* Copyright (C) 2025 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 { test, expect } from 'vitest';
import { QuadletKubeParser } from './quadlet-kube-parser';

const KUBE_QUADLET_EXAMPLE = `
# example.kube
[X-Kube]
Yaml=/mnt/foo/bar.yaml
[Unit]
Wants=network-online.target
After=network-online.target
SourcePath=/home/user/.config/containers/systemd/nginx2.container
RequiresMountsFor=%t/containers
`;

test('expect parser to properly extract Yaml path', () => {
const xkube = new QuadletKubeParser(KUBE_QUADLET_EXAMPLE).parse();
expect(xkube.yaml).toStrictEqual('/mnt/foo/bar.yaml');
});
26 changes: 26 additions & 0 deletions packages/backend/src/utils/parsers/quadlet-type-parser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**********************************************************************
* Copyright (C) 2025 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 { test, expect } from 'vitest';
import { QuadletType } from '/@shared/src/utils/quadlet-type';
import { QuadletTypeParser } from './quadlet-type-parser';

test.each(Object.values(QuadletType))('parsing quadlet %s', (type: QuadletType) => {
const result = new QuadletTypeParser(`[${type}]\nfoo=bar`).parse();
expect(result).toStrictEqual(type);
});
139 changes: 139 additions & 0 deletions packages/frontend/src/lib/monaco-editor/KubeYamlEditor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**********************************************************************
* Copyright (C) 2025 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, fireEvent } from '@testing-library/svelte';
import { beforeEach, test, vi, expect } from 'vitest';
import KubeYamlEditor from '/@/lib/monaco-editor/KubeYamlEditor.svelte';
import type { QuadletInfo } from '/@shared/src/models/quadlet-info';
import { QuadletType } from '/@shared/src/utils/quadlet-type';
import type { ProviderContainerConnectionIdentifierInfo } from '/@shared/src/models/provider-container-connection-identifier-info';
import { quadletAPI } from '/@/api/client';
import MonacoEditor from '/@/lib/monaco-editor/MonacoEditor.svelte';

// mock monaco editor
vi.mock('/@/lib/monaco-editor/MonacoEditor.svelte');
// mock clients
vi.mock('/@/api/client', () => ({
quadletAPI: {
getKubeYAML: vi.fn(),
},
}));

const MOCK_YAML = `
foo=bar
`;

beforeEach(() => {
vi.resetAllMocks();

vi.mocked(quadletAPI.getKubeYAML).mockResolvedValue(MOCK_YAML);
});

const PODMAN_MACHINE_DEFAULT: ProviderContainerConnectionIdentifierInfo = {
name: 'podman-machine-default',
providerId: 'podman',
};

const KUBE_QUADLET: QuadletInfo & { type: QuadletType.KUBE } = {
type: QuadletType.KUBE,
id: `foo.bar`,
path: `/mnt/foo/bar.kube`,
content: 'dummy-content',
state: 'active',
connection: PODMAN_MACHINE_DEFAULT,
};

test('ensure reload button is visible', async () => {
const { getByTitle } = render(KubeYamlEditor, {
quadlet: KUBE_QUADLET,
loading: false,
});

const reloadBtn = getByTitle('Reload file');
expect(reloadBtn).toBeInTheDocument();
// onmount pull the yaml so need to wait for completion
await vi.waitFor(() => {
expect(reloadBtn).toBeEnabled();
});
});

test('ensure reload button is disabled when loading true', async () => {
const { getByTitle } = render(KubeYamlEditor, {
quadlet: KUBE_QUADLET,
loading: true,
});

const reloadBtn = getByTitle('Reload file');
expect(reloadBtn).toBeInTheDocument();
expect(reloadBtn).toBeDisabled();
});

test('expect reload button to call quadletAPI#getKubeYAML', async () => {
const { getByTitle } = render(KubeYamlEditor, {
quadlet: KUBE_QUADLET,
loading: false,
});

const reloadBtn = getByTitle('Reload file');
vi.mocked(quadletAPI.getKubeYAML).mockReset();
await fireEvent.click(reloadBtn);

await vi.waitFor(() => {
expect(quadletAPI.getKubeYAML).toHaveBeenCalledOnce();
});
});

test('expect result from quadletAPI#getKubeYAML to be displayed in monaco editor', async () => {
render(KubeYamlEditor, {
quadlet: KUBE_QUADLET,
loading: false,
});

await vi.waitFor(() => {
expect(quadletAPI.getKubeYAML).toHaveBeenCalled();
});

await vi.waitFor(() => {
expect(MonacoEditor).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({
content: MOCK_YAML,
}),
);
});
});

test('expect error from quadletAPI#getKubeYAML to be displayed', async () => {
vi.mocked(quadletAPI.getKubeYAML).mockRejectedValue(new Error('Dummy foo error'));

const { getByRole } = render(KubeYamlEditor, {
quadlet: KUBE_QUADLET,
loading: false,
});

await vi.waitFor(() => {
expect(quadletAPI.getKubeYAML).toHaveBeenCalled();
});

await vi.waitFor(() => {
const alert = getByRole('alert');
expect(alert).toHaveTextContent('Something went wrong: Error: Dummy foo error');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ onMount(() => {

<div class="flex py-2 h-[40px]">
<span class="block w-auto text-sm font-medium whitespace-nowrap leading-6 text-[var(--pd-content-text)] pl-2 pr-2">
<Button icon={faRotateRight} padding="px-2" disabled={loading} title="reload file" on:click={pull}>Reload</Button>
<Button icon={faRotateRight} padding="px-2" disabled={loading} title="Reload file" on:click={pull}>Reload</Button>
</span>
</div>
{#if error}
Expand Down
Loading

0 comments on commit f7fab21

Please sign in to comment.