Skip to content

Commit

Permalink
tests: more applicationManager.pullApplication tests
Browse files Browse the repository at this point in the history
  • Loading branch information
feloy committed Jan 23, 2024
1 parent be07dd4 commit eec5015
Showing 1 changed file with 126 additions and 67 deletions.
193 changes: 126 additions & 67 deletions packages/backend/src/managers/applicationManager.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect, test, vi } from 'vitest';
import { type MockInstance, describe, expect, test, vi, beforeEach } from 'vitest';
import { ApplicationManager } from './applicationManager';
import type { RecipeStatusRegistry } from '../registries/RecipeStatusRegistry';
import type { ExtensionContext } from '@podman-desktop/api';
Expand All @@ -8,6 +8,8 @@ import fs, { Stats, type Dirent } from 'fs';
import path from 'path';
import type { Recipe } from '@shared/src/models/IRecipe';
import type { ModelInfo } from '@shared/src/models/IModelInfo';
import type { LocalModelInfo } from '@shared/src/models/ILocalModelInfo';
import type { RecipeStatusUtils } from '../utils/recipeStatusUtils';

const mocks = vi.hoisted(() => {
return {
Expand Down Expand Up @@ -71,76 +73,133 @@ test('getLocalModels should return models in local directory', () => {
]);
});

test('pullApplication should clone repository and call downloadModelMain', async () => {
describe('pullApplication', () => {
interface mockForPullApplicationOptions {
recipeFolderExists: boolean;
}

const setStatusMock = vi.fn();
const cloneRepositoryMock = vi.fn();
vi.spyOn(os, 'homedir').mockReturnValue('/home/user');
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
vi.spyOn(fs, 'existsSync').mockImplementation((path: string) => {
if (path.endsWith('recipe1')) {
let manager: ApplicationManager;
let getLocalModelsSpy: MockInstance<[], LocalModelInfo[]>;
let downloadModelMainSpy: MockInstance<
[modelId: string, url: string, taskUtil: RecipeStatusUtils, destFileName?: string],
Promise<string>
>;

beforeEach(() => {
vi.resetAllMocks();
})

Check failure on line 92 in packages/backend/src/managers/applicationManager.spec.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / windows-2022

Missing semicolon

Check failure on line 92 in packages/backend/src/managers/applicationManager.spec.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / ubuntu-22.04

Missing semicolon

Check failure on line 92 in packages/backend/src/managers/applicationManager.spec.ts

View workflow job for this annotation

GitHub Actions / linter, formatters and unit tests / macos-12

Missing semicolon

function mockForPullApplication(options: mockForPullApplicationOptions) {
vi.spyOn(os, 'homedir').mockReturnValue('/home/user');
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
vi.spyOn(fs, 'existsSync').mockImplementation((path: string) => {
if (path.endsWith('recipe1')) {
return options.recipeFolderExists;
} else if (path.endsWith('ai-studio.yaml')) {
return true;
}
return false;
} else if (path.endsWith('ai-studio.yaml')) {
return true;
}
return false;
});
vi.spyOn(fs, 'statSync').mockImplementation((path: string) => {
if (path.endsWith('recipe1')) {
const stat = new Stats();
stat.isDirectory = () => true;
return stat;
} else if (path.endsWith('ai-studio.yaml')) {
const stat = new Stats();
stat.isDirectory = () => false;
return stat;
});
vi.spyOn(fs, 'statSync').mockImplementation((path: string) => {
if (path.endsWith('recipe1')) {
const stat = new Stats();
stat.isDirectory = () => true;
return stat;
} else if (path.endsWith('ai-studio.yaml')) {
const stat = new Stats();
stat.isDirectory = () => false;
return stat;
}
});
vi.spyOn(fs, 'readFileSync').mockImplementation((_path: string) => {
return '';
});
mocks.parseYamlMock.mockReturnValue({
application: {
containers: [],
},
});

manager = new ApplicationManager(
{
cloneRepository: cloneRepositoryMock,
} as unknown as GitManager,
{
setStatus: setStatusMock,
} as unknown as RecipeStatusRegistry,
{} as ExtensionContext,
);

getLocalModelsSpy = vi.spyOn(manager, 'getLocalModels');
getLocalModelsSpy.mockReturnValue([]);
downloadModelMainSpy = vi.spyOn(manager, 'downloadModelMain');
downloadModelMainSpy.mockResolvedValue('');
}

test('pullApplication should clone repository and call downloadModelMain', async () => {
mockForPullApplication({
recipeFolderExists: false,
});

const recipe: Recipe = {
id: 'recipe1',
name: 'Recipe 1',
categories: [],
description: '',
readme: '',
repository: 'repo',
};
const model: ModelInfo = {
id: 'model1',
description: '',
hw: '',
license: '',
name: 'Model 1',
popularity: 1,
registry: '',
url: '',
};

await manager.pullApplication(recipe, model);
if (process.platform === 'win32') {
expect(cloneRepositoryMock).toHaveBeenNthCalledWith(
1,
'repo',
'\\home\\user\\podman-desktop\\ai-studio\\recipe1',
);
} else {
expect(cloneRepositoryMock).toHaveBeenNthCalledWith(1, 'repo', '/home/user/podman-desktop/ai-studio/recipe1');
}
expect(downloadModelMainSpy).toHaveBeenCalledOnce();
});
vi.spyOn(fs, 'readFileSync').mockImplementation((_path: string) => {
return '';
});
mocks.parseYamlMock.mockReturnValue({
application: {
containers: [],
},

test('pullApplication should not clone repository if folder already exists locally', async () => {
mockForPullApplication({
recipeFolderExists: true,
});

const recipe: Recipe = {
id: 'recipe1',
name: 'Recipe 1',
categories: [],
description: '',
readme: '',
repository: 'repo',
};
const model: ModelInfo = {
id: 'model1',
description: '',
hw: '',
license: '',
name: 'Model 1',
popularity: 1,
registry: '',
url: '',
};

await manager.pullApplication(recipe, model);
expect(cloneRepositoryMock).not.toHaveBeenCalled();
});
const manager = new ApplicationManager(
{
cloneRepository: cloneRepositoryMock,
} as unknown as GitManager,
{
setStatus: setStatusMock,
} as unknown as RecipeStatusRegistry,
{} as ExtensionContext,
);

const getLocalModelsSpy = vi.spyOn(manager, 'getLocalModels');
getLocalModelsSpy.mockReturnValue([]);
const downloadModelMainSpy = vi.spyOn(manager, 'downloadModelMain');
downloadModelMainSpy.mockResolvedValue('');

const recipe: Recipe = {
id: 'recipe1',
name: 'Recipe 1',
categories: [],
description: '',
readme: '',
repository: 'repo',
};
const model: ModelInfo = {
id: 'model1',
description: '',
hw: '',
license: '',
name: 'Model 1',
popularity: 1,
registry: '',
url: '',
};
await manager.pullApplication(recipe, model);
if (process.platform === 'win32') {
expect(cloneRepositoryMock).toHaveBeenNthCalledWith(1, 'repo', '\\home\\user\\podman-desktop\\ai-studio\\recipe1');
} else {
expect(cloneRepositoryMock).toHaveBeenNthCalledWith(1, 'repo', '/home/user/podman-desktop/ai-studio/recipe1');
}
expect(downloadModelMainSpy).toHaveBeenCalledOnce();
});

0 comments on commit eec5015

Please sign in to comment.