mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-04-21 17:47:22 +00:00
chore: add extensions.customExtensions.enabled check for install custom extensions button (#16296)
* chore: add extensions.customExtensions.enabled check for install custom extensions button Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: add documentation Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: update according to reviews and fix tests Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: apply comments Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: update tests Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: apply comments Signed-off-by: Sonia Sandler <ssandler@redhat.com> * chore: fix typo Signed-off-by: Sonia Sandler <ssandler@redhat.com>
This commit is contained in:
parent
ab591ca11d
commit
7a93b8bd3b
4 changed files with 96 additions and 29 deletions
|
|
@ -388,10 +388,25 @@ export class ExtensionLoader implements IAsyncDisposable {
|
|||
},
|
||||
};
|
||||
|
||||
const allowCustomExtensions: IConfigurationNode = {
|
||||
id: 'preferences.extensions',
|
||||
title: 'Extensions',
|
||||
type: 'object',
|
||||
properties: {
|
||||
['extensions.customExtensions.enabled']: {
|
||||
description: 'When disabled, the `Install custom...` button on the Extensions page will not appear.',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
this.configurationRegistry.registerConfigurations([
|
||||
maxActivationTimeConfiguration,
|
||||
disabledExtensionConfiguration,
|
||||
developmentModeExtensionConfiguration,
|
||||
allowCustomExtensions,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import ExtensionList from './ExtensionList.svelte';
|
|||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.mocked(window.getConfigurationValue).mockResolvedValue(true);
|
||||
});
|
||||
|
||||
export const aFakeExtension: CatalogExtension = {
|
||||
|
|
@ -100,8 +101,10 @@ test('Expect to see extensions', async () => {
|
|||
|
||||
render(ExtensionList);
|
||||
|
||||
const headingExtensions = screen.getByRole('heading', { name: 'extensions' });
|
||||
expect(headingExtensions).toBeInTheDocument();
|
||||
await vi.waitFor(() => {
|
||||
const headingExtensions = screen.getByRole('heading', { name: 'extensions' });
|
||||
expect(headingExtensions).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// get first extension
|
||||
const myExtension1 = screen.getByRole('region', { name: 'idAInstalled' });
|
||||
|
|
@ -126,8 +129,12 @@ test('Expect to see empty screen on extension page only', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'A' });
|
||||
|
||||
let title = screen.queryByText(`No extensions matching 'A' found`);
|
||||
expect(title).toBeInTheDocument();
|
||||
let title: HTMLElement | null;
|
||||
|
||||
await vi.waitFor(() => {
|
||||
title = screen.queryByText(`No extensions matching 'A' found`);
|
||||
expect(title).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
|
|
@ -143,12 +150,16 @@ test('Expect to see empty screen on catalog page only', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'A' });
|
||||
|
||||
let title = screen.queryByText(`No extensions matching 'A' found`);
|
||||
expect(title).not.toBeInTheDocument();
|
||||
let title: HTMLElement | null;
|
||||
|
||||
// click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
await vi.waitFor(async () => {
|
||||
title = screen.queryByText(`No extensions matching 'A' found`);
|
||||
expect(title).not.toBeInTheDocument();
|
||||
|
||||
// click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
});
|
||||
|
||||
title = screen.queryByText(`No extensions matching 'A' found`);
|
||||
expect(title).toBeInTheDocument();
|
||||
|
|
@ -160,8 +171,12 @@ test('Expect to see empty screens on both pages', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'foo' });
|
||||
|
||||
let title = screen.getByText(`No extensions matching 'foo' found`);
|
||||
expect(title).toBeInTheDocument();
|
||||
let title: HTMLElement | null;
|
||||
|
||||
await vi.waitFor(() => {
|
||||
title = screen.getByText(`No extensions matching 'foo' found`);
|
||||
expect(title).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
|
|
@ -177,8 +192,10 @@ test('Search extension page searches also description', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'bar' });
|
||||
|
||||
const myExtension1 = screen.getByRole('region', { name: 'idAInstalled' });
|
||||
expect(myExtension1).toBeInTheDocument();
|
||||
await vi.waitFor(() => {
|
||||
const myExtension1 = screen.getByRole('region', { name: 'idAInstalled' });
|
||||
expect(myExtension1).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// second extension should not be there as only in catalog (not installed) and doesn't have "bar" in the description
|
||||
const extensionIdB = screen.queryByRole('group', { name: 'B Extension' });
|
||||
|
|
@ -200,9 +217,11 @@ test('Search catalog page searches also description', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'bar' });
|
||||
|
||||
// Click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
await vi.waitFor(async () => {
|
||||
// Click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
});
|
||||
|
||||
// Verify that the extension containing "bar" in the description is displayed
|
||||
const myExtension1 = screen.getByRole('group', { name: 'A Extension' });
|
||||
|
|
@ -217,11 +236,15 @@ test('Expect to see local extensions tab content', async () => {
|
|||
catalogExtensionInfos.set([]);
|
||||
extensionInfos.set([]);
|
||||
|
||||
vi.mocked(window.getConfigurationValue).mockResolvedValue(undefined);
|
||||
|
||||
render(ExtensionList);
|
||||
|
||||
// select the local extensions tab
|
||||
const localModeTab = screen.getByRole('button', { name: 'Local Extensions' });
|
||||
await fireEvent.click(localModeTab);
|
||||
await vi.waitFor(async () => {
|
||||
// select the local extensions tab
|
||||
const localModeTab = screen.getByRole('button', { name: 'Local Extensions' });
|
||||
await fireEvent.click(localModeTab);
|
||||
});
|
||||
|
||||
// expect to see empty screen
|
||||
const emptyText = screen.getByText('Enable Preferences > Extensions > Development Mode to test local extensions');
|
||||
|
|
@ -234,12 +257,34 @@ test('Switching tabs keeps only terms in search term', async () => {
|
|||
|
||||
render(ExtensionList, { searchTerm: 'bar category:bar not:installed' });
|
||||
|
||||
// Click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
await vi.waitFor(async () => {
|
||||
// Click on the catalog
|
||||
const catalogTab = screen.getByRole('button', { name: 'Catalog' });
|
||||
await fireEvent.click(catalogTab);
|
||||
});
|
||||
|
||||
// Verify that the extension containing "bar" in the description is displayed (which is not in bar category and is installed)
|
||||
// meaning that `category:bar not:installed` has been removed from search term
|
||||
const myExtension1 = screen.getByRole('group', { name: 'A Extension' });
|
||||
expect(myExtension1).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Expect install custom button is visible', async () => {
|
||||
render(ExtensionList);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
const installCustomButton = screen.getByRole('button', { name: 'Install custom' });
|
||||
expect(installCustomButton).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('Expect install custom button to not be visible if extensions.customExtensions.enabled is false', async () => {
|
||||
vi.mocked(window.getConfigurationValue).mockResolvedValue(false);
|
||||
|
||||
render(ExtensionList);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
const installCustomButton = screen.queryByRole('button', { name: 'Install custom' });
|
||||
expect(installCustomButton).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ let { searchTerm = '', screen = 'installed' }: Props = $props();
|
|||
|
||||
const extensionsUtils = new ExtensionsUtils();
|
||||
|
||||
let enableCustomExtensions = $derived(
|
||||
(await window.getConfigurationValue('extensions.customExtensions.enabled')) ?? true,
|
||||
);
|
||||
|
||||
const filteredInstalledExtensions: CombinedExtensionInfoUI[] = $derived(
|
||||
extensionsUtils.filterInstalledExtensions($combinedInstalledExtensions, searchTerm),
|
||||
);
|
||||
|
|
@ -63,13 +67,15 @@ function changeScreen(newScreen: 'installed' | 'catalog' | 'development'): void
|
|||
|
||||
<NavPage bind:searchTerm={searchTerm} title="extensions">
|
||||
{#snippet additionalActions()}
|
||||
<Button
|
||||
on:click={(): void => {
|
||||
installManualImageModal = true;
|
||||
}}
|
||||
icon={faCloudDownload}
|
||||
title="Install manually an extension"
|
||||
aria-label="Install custom">Install custom...</Button>
|
||||
{#if enableCustomExtensions}
|
||||
<Button
|
||||
on:click={(): void => {
|
||||
installManualImageModal = true;
|
||||
}}
|
||||
icon={faCloudDownload}
|
||||
title="Install manually an extension"
|
||||
aria-label="Install custom">Install custom...</Button>
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
{#snippet bottomAdditionalActions()}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import TabItem from '@theme/TabItem';
|
|||
| `editor.integrated.fontSize` | number | `10` | Editor font size (6-100 px) |
|
||||
| `extensions.autoCheckUpdates` | boolean | `true` | Auto-check for extension updates |
|
||||
| `extensions.autoUpdate` | boolean | `true` | Auto-install extension updates |
|
||||
| `extensions.customExtensions.enabled` | boolean | `true` | When disabled, the `Install custom...` button on the Extensions page will not appear. |
|
||||
| `extensions.ignoreBannerRecommendations` | boolean | `false` | Disable recommendation banners |
|
||||
| `extensions.ignoreRecommendations` | boolean | `false` | Disable extension recommendations |
|
||||
| `feedback.dialog` | boolean | `true` | Show experimental feature feedback dialog |
|
||||
|
|
|
|||
Loading…
Reference in a new issue