forked from podman-desktop/podman-desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: always show image push button (podman-desktop#5857)
### What does this PR do? * Allows the image push button to always appear * Instead, we will show an unauthenticated warning in the modal with the button disabled, if the image is unauthenticated / unable to push to a registry. ### Screenshot / video of UI <!-- If this PR is changing UI, please include screenshots or screencasts showing the difference --> ### What issues does this PR fix or reference? <!-- Include any related issues from Podman Desktop repository (or from another issue tracker). --> Closes podman-desktop#5506 ### How to test this PR? <!-- Please explain steps to reproduce --> 1. Go to push on any image, the push button should be there. 2. If unauthenticated, the warning should appear. Signed-off-by: Charlie Drage <[email protected]>
- Loading branch information
Showing
4 changed files
with
247 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/********************************************************************** | ||
* Copyright (C) 2024 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 { test, expect, vi, beforeAll, type Mock } from 'vitest'; | ||
import { render, screen } from '@testing-library/svelte'; | ||
import PushImageModal from './PushImageModal.svelte'; | ||
import type { ImageInfoUI } from './ImageInfoUI'; | ||
import type { ImageInspectInfo } from '../../../../main/src/plugin/api/image-inspect-info'; | ||
import { fireEvent } from '@testing-library/dom'; | ||
|
||
vi.mock('xterm', () => { | ||
return { | ||
Terminal: vi.fn().mockReturnValue({ loadAddon: vi.fn(), open: vi.fn(), write: vi.fn(), clear: vi.fn() }), | ||
}; | ||
}); | ||
|
||
const getConfigurationValueMock = vi.fn(); | ||
const hasAuthMock = vi.fn(); | ||
const pushImageMock = vi.fn(); | ||
|
||
beforeAll(() => { | ||
(window.events as unknown) = { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
receive: (_channel: string, func: any) => { | ||
func(); | ||
}, | ||
}; | ||
(window as any).ResizeObserver = vi.fn().mockReturnValue({ observe: vi.fn(), unobserve: vi.fn() }); | ||
(window as any).getImageInspect = vi.fn().mockImplementation(() => Promise.resolve({})); | ||
(window as any).logsContainer = vi.fn().mockResolvedValue(undefined); | ||
(window as any).refreshTerminal = vi.fn(); | ||
(window as any).getConfigurationValue = getConfigurationValueMock; | ||
(window as any).hasAuthconfigForImage = hasAuthMock; | ||
(window as any).showMessageBox = vi.fn(); | ||
(window as any).pushImage = pushImageMock; | ||
}); | ||
|
||
// fake ImageInfoUI | ||
const fakedImage: ImageInfoUI = { | ||
id: 'id', | ||
shortId: 'shortId', | ||
name: 'name', | ||
engineId: 'engineId', | ||
engineName: 'engineName', | ||
tag: 'tag', | ||
createdAt: 0, | ||
age: 'age', | ||
size: 0, | ||
humanSize: 'humanSize', | ||
base64RepoTag: 'base64RepoTag', | ||
selected: false, | ||
status: 'UNUSED', | ||
icon: {}, | ||
badges: [], | ||
}; | ||
const fakedImageInspect: ImageInspectInfo = { | ||
Architecture: '', | ||
Author: '', | ||
Comment: '', | ||
Config: { | ||
ArgsEscaped: false, | ||
AttachStderr: false, | ||
AttachStdin: false, | ||
AttachStdout: false, | ||
Cmd: [], | ||
Domainname: '', | ||
Entrypoint: [], | ||
Env: [], | ||
ExposedPorts: {}, | ||
Hostname: '', | ||
Image: '', | ||
Labels: {}, | ||
OnBuild: [], | ||
OpenStdin: false, | ||
StdinOnce: false, | ||
Tty: false, | ||
User: '', | ||
Volumes: {}, | ||
WorkingDir: '', | ||
}, | ||
Container: '', | ||
ContainerConfig: { | ||
ArgsEscaped: false, | ||
AttachStderr: false, | ||
AttachStdin: false, | ||
AttachStdout: false, | ||
Cmd: [], | ||
Domainname: '', | ||
Env: [], | ||
ExposedPorts: {}, | ||
Hostname: '', | ||
Image: '', | ||
Labels: {}, | ||
OpenStdin: false, | ||
StdinOnce: false, | ||
Tty: false, | ||
User: '', | ||
Volumes: {}, | ||
WorkingDir: '', | ||
}, | ||
Created: '', | ||
DockerVersion: '', | ||
GraphDriver: { Data: { DeviceId: '', DeviceName: '', DeviceSize: '' }, Name: '' }, | ||
Id: '', | ||
Os: '', | ||
Parent: '', | ||
RepoDigests: [], | ||
RepoTags: [], | ||
RootFS: { | ||
Type: '', | ||
}, | ||
Size: 0, | ||
VirtualSize: 0, | ||
engineId: 'engineid', | ||
engineName: 'engineName', | ||
}; | ||
|
||
async function waitRender(customProperties: object): Promise<void> { | ||
const result = render(PushImageModal, { ...customProperties }); | ||
// wait that result.component.$$.ctx[2] is set | ||
while (result.component.$$.ctx[2] === undefined) { | ||
await new Promise(resolve => setTimeout(resolve, 100)); | ||
} | ||
} | ||
|
||
test('Expect "Push Image" button to be disabled if window.hasAuthconfigForImage returns false', async () => { | ||
hasAuthMock.mockImplementation(() => { | ||
return new Promise(() => false); | ||
}); | ||
(window.getImageInspect as Mock).mockResolvedValue(fakedImageInspect); | ||
|
||
await waitRender({ | ||
imageInfoToPush: fakedImage, | ||
closeCallback: vi.fn(), | ||
}); | ||
|
||
// Get the push button | ||
const pushButton = screen.getByRole('button', { name: 'Push image' }); | ||
expect(pushButton).toBeInTheDocument(); | ||
expect(pushButton).toBeDisabled(); | ||
}); | ||
|
||
test('Expect "Push Image" button to actually be clickable if window.hasAuthconfigForImage is true', async () => { | ||
hasAuthMock.mockImplementation(() => { | ||
return new Promise(() => true); | ||
}); | ||
(window.getImageInspect as Mock).mockResolvedValue(fakedImageInspect); | ||
|
||
await waitRender({ | ||
imageInfoToPush: fakedImage, | ||
closeCallback: vi.fn(), | ||
}); | ||
|
||
// Get the push button | ||
const pushButton = screen.getByRole('button', { name: 'Push image' }); | ||
expect(pushButton).toBeInTheDocument(); | ||
|
||
// Actually able to click it | ||
fireEvent.click(pushButton); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters