-
Notifications
You must be signed in to change notification settings - Fork 4
feat: use kubernetes dashboard api #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| /********************************************************************** | ||
| * 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 { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; | ||
| import { DashboardStatesManager } from './dashboard-states-manager'; | ||
| import { type Disposable, type Extension, extensions } from '@podman-desktop/api'; | ||
| import { | ||
| type KubernetesDashboardExtensionApi, | ||
| type KubernetesDashboardSubscriber, | ||
| } from '@podman-desktop/kubernetes-dashboard-extension-api'; | ||
|
|
||
| describe('dashboard extension is not installed', () => { | ||
| let manager: DashboardStatesManager; | ||
| const onDidChangeDisposable: () => void = vi.fn(); | ||
|
|
||
| beforeEach(() => { | ||
| vi.mocked(extensions.onDidChange).mockReturnValue({ | ||
| dispose: onDidChangeDisposable, | ||
| } as unknown as Disposable); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| manager?.dispose(); | ||
| }); | ||
|
|
||
| test('subscriber is undefined', () => { | ||
| manager = new DashboardStatesManager(); | ||
| manager.init(); | ||
| expect(manager.getSubscriber()).toBeUndefined(); | ||
| }); | ||
|
|
||
| test('onDidChangeDisposable is called', () => { | ||
| manager = new DashboardStatesManager(); | ||
| manager.init(); | ||
| manager.dispose(); | ||
| expect(onDidChangeDisposable).toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('dashboard extension is installed', () => { | ||
| let manager: DashboardStatesManager; | ||
| const onDidChangeDisposable: () => void = vi.fn(); | ||
| const subscriber: () => KubernetesDashboardSubscriber = vi.fn(); | ||
| const disposeSubscriber: () => void = vi.fn(); | ||
|
|
||
| beforeEach(() => { | ||
| vi.mocked(extensions.onDidChange).mockImplementation(f => { | ||
| setTimeout(() => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Why is it necessary to use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without this, |
||
| f(); | ||
| }, 0); | ||
| return { | ||
| dispose: onDidChangeDisposable, | ||
| } as unknown as Disposable; | ||
| }); | ||
| vi.mocked(extensions.getExtension).mockImplementation(id => { | ||
| vi.mocked(subscriber).mockReturnValue({ | ||
| onContextsHealth: vi.fn(), | ||
| onContextsPermissions: vi.fn(), | ||
| onResourcesCount: vi.fn(), | ||
| dispose: disposeSubscriber, | ||
| } as unknown as KubernetesDashboardSubscriber); | ||
| if (id === 'redhat.kubernetes-dashboard') { | ||
| return { | ||
| exports: { | ||
| getSubscriber: subscriber, | ||
| }, | ||
| } as unknown as Extension<KubernetesDashboardExtensionApi>; | ||
| } | ||
| return undefined; | ||
| }); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| manager?.dispose(); | ||
| }); | ||
|
|
||
| test('subscriber is eventually defined', async () => { | ||
| manager = new DashboardStatesManager(); | ||
| manager.init(); | ||
| await vi.waitFor(() => { | ||
| expect(manager.getSubscriber()).toBeDefined(); | ||
| }); | ||
| }); | ||
|
|
||
| test('onDidChangeDisposable is called', () => { | ||
| manager = new DashboardStatesManager(); | ||
| manager.init(); | ||
| manager.dispose(); | ||
| expect(onDidChangeDisposable).toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| test('subscriber is disposed on dispose', () => { | ||
| manager = new DashboardStatesManager(); | ||
| manager.init(); | ||
| manager.dispose(); | ||
| expect(disposeSubscriber).toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /********************************************************************** | ||
| * 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 { Disposable, extensions } from '@podman-desktop/api'; | ||
| import { | ||
| KubernetesDashboardExtensionApi, | ||
| KubernetesDashboardSubscriber, | ||
| } from '@podman-desktop/kubernetes-dashboard-extension-api'; | ||
| import { injectable } from 'inversify'; | ||
|
|
||
| @injectable() | ||
| export class DashboardStatesManager implements Disposable { | ||
| #subscriptions: Disposable[] = []; | ||
| #subscriber: KubernetesDashboardSubscriber | undefined; | ||
|
|
||
| init(): void { | ||
| const didChangeSubscription = extensions.onDidChange(() => { | ||
| const api = extensions.getExtension<KubernetesDashboardExtensionApi>('redhat.kubernetes-dashboard')?.exports; | ||
| if (api) { | ||
| this.#subscriber = api.getSubscriber(); | ||
| // dispose the subscriber when the extension is deactivated | ||
| this.#subscriptions.push(this.#subscriber); | ||
| // stop being notified when the extension is changed | ||
| didChangeSubscription.dispose(); | ||
| } | ||
| }); | ||
| // stop being notified when the extension is deactivated | ||
| this.#subscriptions.push(didChangeSubscription); | ||
| } | ||
feloy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| dispose(): void { | ||
| for (const subscription of this.#subscriptions) { | ||
| subscription.dispose(); | ||
| } | ||
| this.#subscriptions = []; | ||
| } | ||
|
|
||
| getSubscriber(): KubernetesDashboardSubscriber | undefined { | ||
| return this.#subscriber; | ||
| } | ||
| } | ||
feloy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: the update of
__mocks__/@podman-desktop/api.jsseems to be more an upstream fix than just here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll need to use the auto-generated mock used in other extensions. In the meantime, I'm adding the methods used when necessary