Skip to content

Commit 84f83bd

Browse files
committed
fix: reworked fine-tuning button in about section
Signed-off-by: Brian <[email protected]>
1 parent 86e4a0a commit 84f83bd

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**********************************************************************
2+
* Copyright (C) 2025 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import '@testing-library/jest-dom/vitest';
20+
import { beforeEach, expect, test, vi } from 'vitest';
21+
import { render, screen } from '@testing-library/svelte';
22+
import { writable, type Writable } from 'svelte/store';
23+
import userEvent from '@testing-library/user-event';
24+
import AboutInstructLab from './AboutInstructLab.svelte';
25+
import type { ExtensionConfiguration } from '@shared/models/IExtensionConfiguration';
26+
import { configuration } from '/@/stores/extensionConfiguration';
27+
import { studioClient } from '/@/utils/client';
28+
import { router } from 'tinro';
29+
30+
vi.mock('/@/stores/extensionConfiguration', () => ({
31+
configuration: {
32+
subscribe: vi.fn(),
33+
unsubscribe: vi.fn(),
34+
},
35+
}));
36+
37+
vi.mock('tinro', () => ({
38+
router: {
39+
goto: vi.fn(),
40+
},
41+
}));
42+
43+
vi.mock('/@/utils/client', () => ({
44+
studioClient: {
45+
openURL: vi.fn(),
46+
},
47+
}));
48+
49+
class ResizeObserver {
50+
observe = vi.fn();
51+
disconnect = vi.fn();
52+
unobserve = vi.fn();
53+
}
54+
55+
const mockConfiguration: Writable<ExtensionConfiguration> = writable({
56+
experimentalGPU: false,
57+
modelsPath: '',
58+
apiPort: -1,
59+
modelUploadDisabled: false,
60+
experimentalTuning: false,
61+
showGPUPromotion: false,
62+
appearance: 'dark',
63+
});
64+
65+
beforeEach(() => {
66+
Object.defineProperty(window, 'ResizeObserver', { value: ResizeObserver });
67+
vi.resetAllMocks();
68+
vi.mocked(configuration).subscribe.mockImplementation(run => mockConfiguration.subscribe(run));
69+
});
70+
71+
test('renders Start Fine Tuning button if experimentalTuning is true', async () => {
72+
mockConfiguration.set({
73+
experimentalGPU: false,
74+
showGPUPromotion: true,
75+
modelUploadDisabled: false,
76+
modelsPath: '',
77+
experimentalTuning: true,
78+
apiPort: -1,
79+
appearance: 'dark',
80+
});
81+
render(AboutInstructLab);
82+
expect(await screen.findByText('Start Fine Tuning')).toBeInTheDocument();
83+
});
84+
85+
test('does not render Start Fine Tuning button if experimentalTuning is false', async () => {
86+
mockConfiguration.set({
87+
experimentalGPU: false,
88+
showGPUPromotion: true,
89+
modelUploadDisabled: false,
90+
modelsPath: '',
91+
experimentalTuning: false,
92+
apiPort: -1,
93+
appearance: 'dark',
94+
});
95+
render(AboutInstructLab);
96+
expect(screen.queryByText('Start Fine Tuning')).not.toBeInTheDocument();
97+
});
98+
99+
test('navigates to /tune/start when Start Fine Tuning is clicked', async () => {
100+
mockConfiguration.set({
101+
experimentalGPU: false,
102+
showGPUPromotion: true,
103+
modelUploadDisabled: false,
104+
modelsPath: '',
105+
experimentalTuning: true,
106+
apiPort: -1,
107+
appearance: 'dark',
108+
});
109+
render(AboutInstructLab);
110+
const btn = await screen.findByText('Start Fine Tuning');
111+
await userEvent.click(btn);
112+
expect(router.goto).toHaveBeenCalledWith('/tune/start');
113+
});
114+
115+
test('opens documentation link when clicked', async () => {
116+
render(AboutInstructLab);
117+
const docLink = await screen.findByText('Access InstructLab documentation');
118+
await userEvent.click(docLink);
119+
expect(studioClient.openURL).toHaveBeenCalledWith('https://docs.instructlab.ai/');
120+
});
121+
122+
test('opens HuggingFace link when clicked', async () => {
123+
render(AboutInstructLab);
124+
const hfLink = await screen.findByText('View InstructLab on HuggingFace');
125+
await userEvent.click(hfLink);
126+
expect(studioClient.openURL).toHaveBeenCalledWith('https://huggingface.co/instructlab');
127+
});

packages/frontend/src/pages/instructlab/AboutInstructLab.svelte

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ import howInstructLabsSyntheticDataGenerationEnhancesLLM from '/@/lib/images/how
1010
import instructLabTitleImage from '/@/lib/images/instructLabTitleImage.png';
1111
import AboutInstructLabDiscoverCard from '../../lib/instructlab/AboutInstructLabDiscoverCard.svelte';
1212
import AboutInstructLabExploreCard from '../../lib/instructlab/AboutInstructLabExploreCard.svelte';
13+
import { configuration } from '/@/stores/extensionConfiguration';
14+
import { onMount } from 'svelte';
15+
16+
let experimentalTuning = false;
17+
18+
onMount(() => {
19+
configuration.subscribe(val => {
20+
experimentalTuning = val?.experimentalTuning ?? false;
21+
});
22+
});
1323
1424
function start(): void {
1525
router.goto('/tune/start');
@@ -68,7 +78,9 @@ let cards: AboutInstructLabExploreCardInterface[] = [
6878

6979
<NavPage title="About InstructLab" searchEnabled={false}>
7080
<div slot="additional-actions">
71-
<Button icon={faPlusCircle} on:click={start}>Start Fine Tuning</Button>
81+
{#if experimentalTuning}
82+
<Button icon={faPlusCircle} on:click={start}>Start Fine Tuning</Button>
83+
{/if}
7284
</div>
7385
<div slot="content" class="flex flex-col min-w-full min-h-full">
7486
<div class="min-w-full min-h-full flex-1">

0 commit comments

Comments
 (0)