All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { ReloadService } from './reload.service.js';
|
|
|
|
function createMockCommandRegistry() {
|
|
return {
|
|
getManifest: vi.fn().mockReturnValue({
|
|
version: 1,
|
|
commands: [],
|
|
skills: [],
|
|
}),
|
|
};
|
|
}
|
|
|
|
function createService() {
|
|
const registry = createMockCommandRegistry();
|
|
const service = new ReloadService(registry as never);
|
|
return { service, registry };
|
|
}
|
|
|
|
describe('ReloadService', () => {
|
|
it('reload() calls onUnload then onLoad for registered MosaicPlugin', async () => {
|
|
const { service } = createService();
|
|
|
|
const callOrder: string[] = [];
|
|
const mockPlugin = {
|
|
pluginName: 'test-plugin',
|
|
onLoad: vi.fn().mockImplementation(() => {
|
|
callOrder.push('onLoad');
|
|
return Promise.resolve();
|
|
}),
|
|
onUnload: vi.fn().mockImplementation(() => {
|
|
callOrder.push('onUnload');
|
|
return Promise.resolve();
|
|
}),
|
|
};
|
|
|
|
service.registerPlugin('test-plugin', mockPlugin);
|
|
const result = await service.reload('command');
|
|
|
|
expect(mockPlugin.onUnload).toHaveBeenCalledOnce();
|
|
expect(mockPlugin.onLoad).toHaveBeenCalledOnce();
|
|
expect(callOrder).toEqual(['onUnload', 'onLoad']);
|
|
expect(result.message).toContain('test-plugin');
|
|
});
|
|
|
|
it('reload() continues if one plugin throws during onUnload', async () => {
|
|
const { service } = createService();
|
|
|
|
const badPlugin = {
|
|
pluginName: 'bad-plugin',
|
|
onLoad: vi.fn().mockResolvedValue(undefined),
|
|
onUnload: vi.fn().mockRejectedValue(new Error('unload failed')),
|
|
};
|
|
|
|
service.registerPlugin('bad-plugin', badPlugin);
|
|
const result = await service.reload('command');
|
|
|
|
expect(result.message).toContain('bad-plugin');
|
|
expect(result.message).toContain('unload failed');
|
|
});
|
|
|
|
it('reload() skips non-MosaicPlugin objects', async () => {
|
|
const { service } = createService();
|
|
|
|
const notAPlugin = { foo: 'bar' };
|
|
service.registerPlugin('not-a-plugin', notAPlugin);
|
|
|
|
// Should not throw
|
|
const result = await service.reload('command');
|
|
expect(result).toBeDefined();
|
|
expect(result.message).not.toContain('not-a-plugin');
|
|
});
|
|
|
|
it('reload() returns SystemReloadPayload with commands, skills, providers, message', async () => {
|
|
const { service, registry } = createService();
|
|
registry.getManifest.mockReturnValue({
|
|
version: 1,
|
|
commands: [
|
|
{
|
|
name: 'test',
|
|
description: 'test cmd',
|
|
aliases: [],
|
|
scope: 'core',
|
|
execution: 'socket',
|
|
available: true,
|
|
},
|
|
],
|
|
skills: [],
|
|
});
|
|
|
|
const result = await service.reload('rest');
|
|
|
|
expect(result).toHaveProperty('commands');
|
|
expect(result).toHaveProperty('skills');
|
|
expect(result).toHaveProperty('providers');
|
|
expect(result).toHaveProperty('message');
|
|
expect(result.commands).toHaveLength(1);
|
|
});
|
|
|
|
it('registerPlugin() logs plugin registration', () => {
|
|
const { service } = createService();
|
|
|
|
// Should not throw and should register
|
|
expect(() => service.registerPlugin('my-plugin', {})).not.toThrow();
|
|
});
|
|
});
|