Skip to content

Commit 7ae9fcf

Browse files
committed
tests: ensuring everything is properly tested
Signed-off-by: axel7083 <[email protected]>
1 parent cdd7441 commit 7ae9fcf

File tree

7 files changed

+444
-1
lines changed

7 files changed

+444
-1
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
import { expect, test, vi, beforeEach } from 'vitest';
19+
import { QuadletApiImpl } from './quadlet-api-impl';
20+
import type { QuadletService } from '../services/quadlet-service';
21+
import type { SystemdService } from '../services/systemd-service';
22+
import type { PodmanService } from '../services/podman-service';
23+
import type { ProviderService } from '../services/provider-service';
24+
import type { LoggerService } from '../services/logger-service';
25+
import type { ProviderContainerConnection } from '@podman-desktop/api';
26+
import type { ProviderContainerConnectionIdentifierInfo } from '/@shared/src/models/provider-container-connection-identifier-info';
27+
28+
const QUADLET_SERVICE: QuadletService = {
29+
getKubeYAML: vi.fn(),
30+
} as unknown as QuadletService;
31+
const SYSTEMD_SERVICE: SystemdService = {} as unknown as SystemdService;
32+
const PODMAN_SERVICE: PodmanService = {} as unknown as PodmanService;
33+
const PROVIDER_SERVICE: ProviderService = {
34+
getProviderContainerConnection: vi.fn(),
35+
} as unknown as ProviderService;
36+
const LOGGER_SERVICE: LoggerService = {} as unknown as LoggerService;
37+
38+
const WSL_PROVIDER_CONNECTION_MOCK: ProviderContainerConnection = {
39+
connection: {
40+
type: 'podman',
41+
vmType: 'WSL',
42+
name: 'podman-machine-default',
43+
},
44+
providerId: 'podman',
45+
} as ProviderContainerConnection;
46+
47+
const WSL_PROVIDER_IDENTIFIER: ProviderContainerConnectionIdentifierInfo = {
48+
name: WSL_PROVIDER_CONNECTION_MOCK.connection.name,
49+
providerId: WSL_PROVIDER_CONNECTION_MOCK.providerId,
50+
};
51+
52+
beforeEach(() => {
53+
vi.resetAllMocks();
54+
55+
vi.mocked(PROVIDER_SERVICE.getProviderContainerConnection).mockReturnValue(WSL_PROVIDER_CONNECTION_MOCK);
56+
});
57+
58+
function getQuadletApiImpl(): QuadletApiImpl {
59+
return new QuadletApiImpl({
60+
quadlet: QUADLET_SERVICE,
61+
systemd: SYSTEMD_SERVICE,
62+
podman: PODMAN_SERVICE,
63+
providers: PROVIDER_SERVICE,
64+
loggerService: LOGGER_SERVICE,
65+
});
66+
}
67+
68+
test('QuadletApiImpl#getKubeYAML should propagate result from QuadletService#getKubeYAML', async () => {
69+
vi.mocked(QUADLET_SERVICE.getKubeYAML).mockResolvedValue('dummy-yaml-content');
70+
71+
const api = getQuadletApiImpl();
72+
73+
const result = await api.getKubeYAML(WSL_PROVIDER_IDENTIFIER, 'dummy-quadlet-id');
74+
expect(result).toStrictEqual('dummy-yaml-content');
75+
expect(PROVIDER_SERVICE.getProviderContainerConnection).toHaveBeenCalledWith(WSL_PROVIDER_IDENTIFIER);
76+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { test, expect } from 'vitest';
20+
import { QuadletKubeParser } from './quadlet-kube-parser';
21+
22+
const KUBE_QUADLET_EXAMPLE = `
23+
# example.kube
24+
[X-Kube]
25+
Yaml=/mnt/foo/bar.yaml
26+
27+
[Unit]
28+
Wants=network-online.target
29+
After=network-online.target
30+
SourcePath=/home/user/.config/containers/systemd/nginx2.container
31+
RequiresMountsFor=%t/containers
32+
`;
33+
34+
test('expect parser to properly extract Yaml path', () => {
35+
const xkube = new QuadletKubeParser(KUBE_QUADLET_EXAMPLE).parse();
36+
expect(xkube.yaml).toStrictEqual('/mnt/foo/bar.yaml');
37+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { test, expect } from 'vitest';
20+
import { QuadletType } from '/@shared/src/utils/quadlet-type';
21+
import { QuadletTypeParser } from './quadlet-type-parser';
22+
23+
test.each(Object.values(QuadletType))('parsing quadlet %s', (type: QuadletType) => {
24+
const result = new QuadletTypeParser(`[${type}]\nfoo=bar`).parse();
25+
expect(result).toStrictEqual(type);
26+
});
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import '@testing-library/jest-dom/vitest';
20+
21+
import { render, fireEvent } from '@testing-library/svelte';
22+
import { beforeEach, test, vi, expect } from 'vitest';
23+
import KubeYamlEditor from '/@/lib/monaco-editor/KubeYamlEditor.svelte';
24+
import type { QuadletInfo } from '/@shared/src/models/quadlet-info';
25+
import { QuadletType } from '/@shared/src/utils/quadlet-type';
26+
import type { ProviderContainerConnectionIdentifierInfo } from '/@shared/src/models/provider-container-connection-identifier-info';
27+
import { quadletAPI } from '/@/api/client';
28+
import MonacoEditor from '/@/lib/monaco-editor/MonacoEditor.svelte';
29+
30+
// mock monaco editor
31+
vi.mock('/@/lib/monaco-editor/MonacoEditor.svelte');
32+
// mock clients
33+
vi.mock('/@/api/client', () => ({
34+
quadletAPI: {
35+
getKubeYAML: vi.fn(),
36+
},
37+
}));
38+
39+
const MOCK_YAML = `
40+
foo=bar
41+
`;
42+
43+
beforeEach(() => {
44+
vi.resetAllMocks();
45+
46+
vi.mocked(quadletAPI.getKubeYAML).mockResolvedValue(MOCK_YAML);
47+
});
48+
49+
const PODMAN_MACHINE_DEFAULT: ProviderContainerConnectionIdentifierInfo = {
50+
name: 'podman-machine-default',
51+
providerId: 'podman',
52+
};
53+
54+
const KUBE_QUADLET: QuadletInfo & { type: QuadletType.KUBE } = {
55+
type: QuadletType.KUBE,
56+
id: `foo.bar`,
57+
path: `/mnt/foo/bar.kube`,
58+
content: 'dummy-content',
59+
state: 'active',
60+
connection: PODMAN_MACHINE_DEFAULT,
61+
};
62+
63+
test('ensure reload button is visible', async () => {
64+
const { getByTitle } = render(KubeYamlEditor, {
65+
quadlet: KUBE_QUADLET,
66+
loading: false,
67+
});
68+
69+
const reloadBtn = getByTitle('Reload file');
70+
expect(reloadBtn).toBeInTheDocument();
71+
// onmount pull the yaml so need to wait for completion
72+
await vi.waitFor(() => {
73+
expect(reloadBtn).toBeEnabled();
74+
});
75+
});
76+
77+
test('ensure reload button is disabled when loading true', async () => {
78+
const { getByTitle } = render(KubeYamlEditor, {
79+
quadlet: KUBE_QUADLET,
80+
loading: true,
81+
});
82+
83+
const reloadBtn = getByTitle('Reload file');
84+
expect(reloadBtn).toBeInTheDocument();
85+
expect(reloadBtn).toBeDisabled();
86+
});
87+
88+
test('expect reload button to call quadletAPI#getKubeYAML', async () => {
89+
const { getByTitle } = render(KubeYamlEditor, {
90+
quadlet: KUBE_QUADLET,
91+
loading: false,
92+
});
93+
94+
const reloadBtn = getByTitle('Reload file');
95+
vi.mocked(quadletAPI.getKubeYAML).mockReset();
96+
await fireEvent.click(reloadBtn);
97+
98+
await vi.waitFor(() => {
99+
expect(quadletAPI.getKubeYAML).toHaveBeenCalledOnce();
100+
});
101+
});
102+
103+
test('expect result from quadletAPI#getKubeYAML to be displayed in monaco editor', async () => {
104+
render(KubeYamlEditor, {
105+
quadlet: KUBE_QUADLET,
106+
loading: false,
107+
});
108+
109+
await vi.waitFor(() => {
110+
expect(quadletAPI.getKubeYAML).toHaveBeenCalled();
111+
});
112+
113+
await vi.waitFor(() => {
114+
expect(MonacoEditor).toHaveBeenCalledWith(
115+
expect.anything(),
116+
expect.objectContaining({
117+
content: MOCK_YAML,
118+
}),
119+
);
120+
});
121+
});
122+
123+
test('expect error from quadletAPI#getKubeYAML to be displayed', async () => {
124+
vi.mocked(quadletAPI.getKubeYAML).mockRejectedValue(new Error('Dummy foo error'));
125+
126+
const { getByRole } = render(KubeYamlEditor, {
127+
quadlet: KUBE_QUADLET,
128+
loading: false,
129+
});
130+
131+
await vi.waitFor(() => {
132+
expect(quadletAPI.getKubeYAML).toHaveBeenCalled();
133+
});
134+
135+
await vi.waitFor(() => {
136+
const alert = getByRole('alert');
137+
expect(alert).toHaveTextContent('Something went wrong: Error: Dummy foo error');
138+
});
139+
});

packages/frontend/src/lib/monaco-editor/KubeYamlEditor.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ onMount(() => {
3737

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

0 commit comments

Comments
 (0)