Skip to content

Commit 6a79514

Browse files
committed
fix: handle ids with spaces for extensions
fixes podman-desktop#6955 Signed-off-by: Florent Benoit <[email protected]>
1 parent 811c6d1 commit 6a79514

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

packages/renderer/src/lib/extensions/ExtensionDetails.spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,31 @@ export const aFakeExtension: CatalogExtension = {
6565
],
6666
};
6767

68+
export const withSpacesFakeExtension: CatalogExtension = {
69+
id: 'id A Installed',
70+
publisherName: 'FooPublisher',
71+
shortDescription: 'this is short A',
72+
publisherDisplayName: 'Foo Publisher',
73+
extensionName: 'a-extension',
74+
displayName: 'A Extension',
75+
categories: [],
76+
unlisted: false,
77+
versions: [
78+
{
79+
version: '1.0.0A',
80+
preview: false,
81+
files: [
82+
{
83+
assetType: 'icon',
84+
data: 'iconA',
85+
},
86+
],
87+
ociUri: 'linkA',
88+
lastUpdated: new Date(),
89+
},
90+
],
91+
};
92+
6893
const combined: CombinedExtensionInfoUI[] = [
6994
{
7095
id: 'idAInstalled',
@@ -109,3 +134,15 @@ test('Expect empty screen', async () => {
109134
const extensionNotFound = screen.getByText('Extension not found');
110135
expect(extensionNotFound).toBeInTheDocument();
111136
});
137+
138+
test('Expect to have details page with id with spaces', async () => {
139+
const extensionId = 'id A Installed';
140+
141+
catalogExtensionInfos.set([withSpacesFakeExtension]);
142+
extensionInfos.set(combined);
143+
144+
await waitRender({ extensionId });
145+
146+
const heading = screen.getByRole('heading', { name: 'A Extension extension' });
147+
expect(heading).toBeInTheDocument();
148+
});

packages/renderer/src/lib/extensions/ExtensionDetails.svelte

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ let extension: Readable<ExtensionDetailsUI | undefined>;
2727
$: extension = derived(
2828
[catalogExtensionInfos, combinedInstalledExtensions],
2929
([$catalogExtensionInfos, $combinedInstalledExtensions]) => {
30-
return extensionsUtils.extractExtensionDetail($catalogExtensionInfos, $combinedInstalledExtensions, extensionId);
30+
return extensionsUtils.extractExtensionDetail(
31+
$catalogExtensionInfos,
32+
$combinedInstalledExtensions,
33+
decodeURIComponent(extensionId),
34+
);
3135
},
3236
);
3337
</script>

packages/renderer/src/lib/extensions/ExtensionDetailsLink.spec.ts

+28
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,31 @@ test('Expect to have link with displayIcon', async () => {
6969
// expect the router to be called
7070
expect(vi.mocked(router.goto)).toHaveBeenCalledWith('/extensions/details/myId/');
7171
});
72+
73+
test('Expect to have link with spaces', async () => {
74+
const extension: CombinedExtensionInfoUI = {
75+
type: 'pd',
76+
id: 'my Id with spaces',
77+
name: 'foo',
78+
description: 'my description',
79+
displayName: 'This is the display name',
80+
publisher: '',
81+
removable: false,
82+
version: 'v1.2.3',
83+
state: 'started',
84+
path: '',
85+
readme: '',
86+
icon: 'iconOfMyExtension.png',
87+
};
88+
89+
render(ExtensionDetailsLink, { extension });
90+
91+
const detailsButton = screen.getByRole('button', { name: 'foo extension details' });
92+
expect(detailsButton).toBeInTheDocument();
93+
94+
// click the button
95+
await fireEvent.click(detailsButton);
96+
97+
// expect the router to be called
98+
expect(vi.mocked(router.goto)).toHaveBeenCalledWith('/extensions/details/my%20Id%20with%20spaces/');
99+
});

packages/renderer/src/lib/extensions/ExtensionDetailsLink.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export let extension: CombinedExtensionInfoUI;
1111
export let displayIcon: boolean = true;
1212
1313
function openDetailsExtension() {
14-
router.goto(`/extensions/details/${extension.id}/`);
14+
router.goto(`/extensions/details/${encodeURIComponent(extension.id)}/`);
1515
}
1616
</script>
1717

0 commit comments

Comments
 (0)