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.
feat: add a way to choose platform when building image (podman-deskto…
…p#5503) * feat: add a way to choose platform when building image fixes podman-desktop#5492 Signed-off-by: Florent Benoit <[email protected]>
- Loading branch information
Showing
6 changed files
with
476 additions
and
0 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
109 changes: 109 additions & 0 deletions
109
packages/renderer/src/lib/image/BuildImageFromContainerfileCard.spec.ts
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,109 @@ | ||
/********************************************************************** | ||
* 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 | ||
***********************************************************************/ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import '@testing-library/jest-dom/vitest'; | ||
import { test, expect } from 'vitest'; | ||
import { render, screen } from '@testing-library/svelte'; | ||
import userEvent from '@testing-library/user-event'; | ||
import BuildImageFromContainerfileCard from '/@/lib/image/BuildImageFromContainerfileCard.svelte'; | ||
|
||
test('check click', async () => { | ||
const component = render(BuildImageFromContainerfileCard, { | ||
title: 'ARM64', | ||
badge: 'arm64', | ||
isDefault: false, | ||
checked: false, | ||
value: 'arm64', | ||
icon: undefined, | ||
}); | ||
|
||
const events: { mode: string; value: string }[] = []; | ||
|
||
component.component.$on('card', (e: any) => { | ||
events.push(e.detail); | ||
}); | ||
|
||
// expect checkbox is unchecked | ||
expect(screen.getByRole('checkbox')).not.toBeChecked(); | ||
|
||
expect(events).toEqual([]); | ||
|
||
// click on the card and expect to be checked | ||
await userEvent.click(screen.getByRole('button')); | ||
|
||
expect(events).toEqual([{ mode: 'add', value: 'arm64' }]); | ||
}); | ||
|
||
test('Expect checked', async () => { | ||
render(BuildImageFromContainerfileCard, { | ||
title: 'ARM64', | ||
badge: 'arm64', | ||
isDefault: false, | ||
checked: true, | ||
value: 'arm64', | ||
icon: undefined, | ||
}); | ||
|
||
// expect checkbox is unchecked | ||
expect(screen.getByRole('checkbox')).toBeChecked(); | ||
}); | ||
|
||
test('Expect default tooltip', async () => { | ||
render(BuildImageFromContainerfileCard, { | ||
title: 'ARM64', | ||
badge: 'arm64', | ||
isDefault: true, | ||
checked: true, | ||
value: 'arm64', | ||
icon: undefined, | ||
}); | ||
|
||
// check we have a div tooltip with aria-label tooltip | ||
const tooltip = screen.getByText('Default platform of your computer'); | ||
expect(tooltip).toBeInTheDocument(); | ||
}); | ||
|
||
test('check we can add a new card', async () => { | ||
const component = render(BuildImageFromContainerfileCard, { | ||
title: '', | ||
badge: '', | ||
isDefault: false, | ||
checked: false, | ||
value: '', | ||
icon: undefined, | ||
additionalItem: true, | ||
}); | ||
|
||
const addCards: { value: string }[] = []; | ||
|
||
component.component.$on('addcard', (e: any) => { | ||
addCards.push(e.detail); | ||
}); | ||
|
||
expect(addCards).toEqual([]); | ||
|
||
// click on the card and expect to be checked | ||
await userEvent.click(screen.getByRole('button')); | ||
|
||
// add new name on the input field | ||
await userEvent.type(screen.getByRole('textbox'), 'my/platform{enter}'); | ||
|
||
expect(addCards).toEqual([{ value: 'my/platform' }]); | ||
}); |
113 changes: 113 additions & 0 deletions
113
packages/renderer/src/lib/image/BuildImageFromContainerfileCard.svelte
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,113 @@ | ||
<script lang="ts"> | ||
import { faSun } from '@fortawesome/free-solid-svg-icons'; | ||
import Fa from 'svelte-fa'; | ||
import Checkbox from '../ui/Checkbox.svelte'; | ||
import Tooltip from '../ui/Tooltip.svelte'; | ||
import { onMount, tick, createEventDispatcher } from 'svelte'; | ||
export let title: string = ''; | ||
export let badge: string = ''; | ||
export let isDefault: boolean = false; | ||
export let checked: boolean = false; | ||
export let value: string = ''; | ||
export let icon: any; | ||
let iconType: 'fontAwesome' | 'unknown' | undefined = undefined; | ||
export let additionalItem: boolean = false; | ||
let additionalValue: string = ''; | ||
let displayValueFieldInput = false; | ||
let inputHtmlElement: HTMLInputElement | undefined; | ||
const dispatch = createEventDispatcher(); | ||
function handleKeydownAdditionalField(event: KeyboardEvent) { | ||
if (event.key === 'Enter') { | ||
dispatch('addcard', { value: additionalValue }); | ||
displayValueFieldInput = false; | ||
} | ||
} | ||
function handleClick() { | ||
if (additionalItem) { | ||
// display the new field input | ||
displayValueFieldInput = true; | ||
additionalValue = ''; | ||
// make focus on the input field | ||
tick().then(() => { | ||
if (inputHtmlElement) { | ||
inputHtmlElement.focus(); | ||
} | ||
}); | ||
return; | ||
} | ||
checked = !checked; | ||
if (checked) { | ||
dispatch('card', { mode: 'add', value: value }); | ||
} else { | ||
dispatch('card', { mode: 'remove', value: value }); | ||
} | ||
} | ||
onMount(() => { | ||
if (icon?.prefix?.startsWith('fa')) { | ||
iconType = 'fontAwesome'; | ||
} else { | ||
iconType = 'unknown'; | ||
} | ||
if (isDefault) { | ||
dispatch('card', { mode: 'add', value: value }); | ||
} | ||
}); | ||
</script> | ||
|
||
<button | ||
class="rounded-md p-2 min-w-32 w-32 cursor-pointer hover:bg-charcoal-700 {checked | ||
? 'border-dustypurple-700' | ||
: 'border-gray-700'} border-2 flex flex-row" | ||
aria-label="{value}" | ||
on:click|preventDefault="{() => handleClick()}"> | ||
<div> | ||
{#if !additionalItem} | ||
<Checkbox bind:checked="{checked}" on:click="{() => handleClick()}" /> | ||
{:else} | ||
<div> </div> | ||
{/if} | ||
</div> | ||
<div class="mr-2 text-gray-700"> | ||
<div class="flex flex-row"> | ||
<div class="ml-1"> | ||
{#if iconType === 'fontAwesome'} | ||
<Fa class="text-gray-700 cursor-pointer" icon="{icon}" size="24" /> | ||
{:else if iconType === 'unknown'} | ||
<svelte:component this="{icon}" class="text-gray-700 cursor-pointer" size="24" /> | ||
{/if} | ||
</div> | ||
|
||
{#if isDefault} | ||
<Tooltip tip="Default platform of your computer"> | ||
<Fa size="14" class="text-dustypurple-700 cursor-pointer" icon="{faSun}" /> | ||
</Tooltip> | ||
{/if} | ||
</div> | ||
<div class="text-sm text-left truncate w-24">{title}</div> | ||
<div class="flex"> | ||
{#if badge} | ||
<div class="bg-dustypurple-700 text-white text-xs font-medium me-2 px-2.5 py-0.5 rounded">{badge}</div> | ||
{/if} | ||
{#if displayValueFieldInput} | ||
<input | ||
type="text" | ||
class="w-24 outline-none text-sm bg-dustypurple-900 rounded-sm text-gray-700 placeholder-gray-700" | ||
bind:value="{additionalValue}" | ||
bind:this="{inputHtmlElement}" | ||
on:keydown="{handleKeydownAdditionalField}" /> | ||
{/if} | ||
</div> | ||
</div> | ||
</button> |
65 changes: 65 additions & 0 deletions
65
packages/renderer/src/lib/image/BuildImageFromContainerfileCards.spec.ts
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,65 @@ | ||
/********************************************************************** | ||
* 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 | ||
***********************************************************************/ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import '@testing-library/jest-dom/vitest'; | ||
import { test, expect, beforeAll, vi } from 'vitest'; | ||
import { render } from '@testing-library/svelte'; | ||
import BuildImageFromContainerfileCards from './BuildImageFromContainerfileCards.svelte'; | ||
|
||
// fake the window.events object | ||
beforeAll(() => { | ||
(window.events as unknown) = { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
receive: (_channel: string, func: any) => { | ||
func(); | ||
}, | ||
}; | ||
(window as any).getOsArch = vi.fn(); | ||
}); | ||
|
||
test('check default on arm64', async () => { | ||
vi.mocked(window.getOsArch).mockResolvedValue('arm64'); | ||
|
||
const platforms = ''; | ||
const rendered = render(BuildImageFromContainerfileCards, { | ||
platforms, | ||
}); | ||
|
||
// wait a little with setTimeout | ||
await new Promise(resolve => setTimeout(resolve, 100)); | ||
|
||
// check we have a platform | ||
expect(rendered.component.$$.ctx[5]).toEqual('linux/arm64'); | ||
}); | ||
|
||
test('check default on amd64', async () => { | ||
vi.mocked(window.getOsArch).mockResolvedValue('x64'); | ||
|
||
const platforms = ''; | ||
const rendered = render(BuildImageFromContainerfileCards, { | ||
platforms, | ||
}); | ||
|
||
// wait a little with setTimeout | ||
await new Promise(resolve => setTimeout(resolve, 100)); | ||
|
||
// check we have a platform | ||
expect(rendered.component.$$.ctx[5]).toEqual('linux/amd64'); | ||
}); |
Oops, something went wrong.