diff --git a/packages/frontend/src/pages/Models.spec.ts b/packages/frontend/src/pages/Models.spec.ts new file mode 100644 index 000000000..da8637a52 --- /dev/null +++ b/packages/frontend/src/pages/Models.spec.ts @@ -0,0 +1,81 @@ +import { vi, test, expect } from 'vitest'; +import { screen, render, waitFor } from '@testing-library/svelte'; +import Models from './Models.svelte'; +import type { RecipeStatus } from '@shared/src/models/IRecipeStatus'; + +const mocks = vi.hoisted(() => { + return { + getCatalogMock: vi.fn(), + getPullingStatusesMock: vi.fn().mockResolvedValue(new Map()), + getLocalModelsMock: vi.fn().mockResolvedValue([]), + localModelsSubscribeMock: vi.fn(), + localModelsQueriesMock: { + subscribe: (f: (msg: any) => void) => { + f(mocks.localModelsSubscribeMock()); + return () => {}; + }, + }, + getLocalModels: vi.fn().mockResolvedValue([]), + }; +}); + +vi.mock('/@/utils/client', async () => { + return { + studioClient: { + getLocalModels: mocks.getLocalModels, + getPullingStatuses: mocks.getPullingStatusesMock, + }, + rpcBrowser: { + subscribe: () => { + return { + unsubscribe: () => {}, + }; + }, + }, + }; +}); + +vi.mock('../stores/local-models', async () => { + return { + localModels: mocks.localModelsQueriesMock, + }; +}); + +test('should display There is no model yet', async () => { + mocks.localModelsSubscribeMock.mockReturnValue([]); + + render(Models); + + const status = screen.getByRole('status'); + expect(status).toBeDefined(); +}); + +test('should display There is no model yet and have a task running', async () => { + mocks.localModelsSubscribeMock.mockReturnValue([]); + const map = new Map(); + map.set('random', { + recipeId: 'random-recipe-id', + state: 'loading', + tasks: [ + { + id: 'random', + name: 'random', + state: 'loading', + labels: { + 'model-pulling': 'random-models-id', + }, + }, + ], + }); + mocks.getPullingStatusesMock.mockResolvedValue(map); + + render(Models); + + const status = screen.getByRole('status'); + expect(status).toBeDefined(); + + await waitFor(() => { + const title = screen.getByText('Downloading models'); + expect(title).toBeDefined(); + }); +}); diff --git a/packages/frontend/src/pages/Models.svelte b/packages/frontend/src/pages/Models.svelte index 783d47695..abc91747d 100644 --- a/packages/frontend/src/pages/Models.svelte +++ b/packages/frontend/src/pages/Models.svelte @@ -39,9 +39,6 @@ let filteredModels: ModelInfo[] = []; function filterModels(): void { // Let's collect the models we do not want to show (loading, error). const modelsId: string[] = tasks.reduce((previousValue, currentValue) => { - if(currentValue.state === 'success') - return previousValue; - if(currentValue.labels !== undefined) { previousValue.push(currentValue.labels["model-pulling"]); } @@ -53,7 +50,8 @@ function filterModels(): void { onMount(() => { // Pulling update const modelsPullingUnsubscribe = modelsPulling.subscribe(runningTasks => { - tasks = runningTasks; + // Only display error | loading tasks. + tasks = runningTasks.filter((task) => task.state !== 'success'); loading = false; filterModels(); }); @@ -94,7 +92,7 @@ onMount(() => { row={row}> {:else} -
There is no model yet
+
There is no model yet
{/if} {/if} diff --git a/packages/frontend/src/pages/ModelsPage.spec.ts b/packages/frontend/src/pages/ModelsPage.spec.ts new file mode 100644 index 000000000..d99fac1c5 --- /dev/null +++ b/packages/frontend/src/pages/ModelsPage.spec.ts @@ -0,0 +1,29 @@ +import '@testing-library/jest-dom/vitest'; +import { vi, test, expect } from 'vitest'; +import { screen, render } from '@testing-library/svelte'; +import Models from './Models.svelte'; + +const mocks = vi.hoisted(() => ({ + getLocalModelsMock: vi.fn().mockImplementation(() => Promise.resolve([])), + localModelsSubscribeMock: vi.fn(), + localModelsQueriesMock: { + subscribe: (f: (msg: any) => void) => { + f(mocks.localModelsSubscribeMock()); + return () => {}; + }, + }, +})); + +vi.mock('../stores/local-models', async () => { + return { + localModels: mocks.localModelsQueriesMock, + }; +}); + +test('no models provided should display no model yet', async () => { + mocks.localModelsSubscribeMock.mockReturnValue([]); + render(Models); + + const status = screen.getByRole('status', { value: { text: 'There is no model yet' } }); + expect(status).toBeDefined(); +});