refactor: Remove hardcoded values
All checks were successful
Queue Release Build / prepare (push) Successful in 2m28s
Deploy Web Apps / deploy (push) Successful in 7m58s
Queue Release Build / build-linux (push) Successful in 46m59s
Queue Release Build / build-windows (push) Successful in 26m2s
Queue Release Build / finalize (push) Successful in 23s
All checks were successful
Queue Release Build / prepare (push) Successful in 2m28s
Deploy Web Apps / deploy (push) Successful in 7m58s
Queue Release Build / build-linux (push) Successful in 46m59s
Queue Release Build / build-windows (push) Successful in 26m2s
Queue Release Build / finalize (push) Successful in 23s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Injector } from '@angular/core';
|
||||
import { environment } from '../../../../../environments/environment';
|
||||
import type { TojuPluginManifest } from '../../../../shared-kernel';
|
||||
import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
|
||||
import { PluginStoreService } from './plugin-store.service';
|
||||
@@ -6,8 +7,11 @@ import { PluginHostService } from './plugin-host.service';
|
||||
import { PluginDesktopStateService } from './plugin-desktop-state.service';
|
||||
import { PluginRequirementService } from './plugin-requirement.service';
|
||||
import { PluginRegistryService } from './plugin-registry.service';
|
||||
import { PluginCapabilityService } from './plugin-capability.service';
|
||||
import type { PluginStoreEntry } from '../../domain/models/plugin-store.models';
|
||||
|
||||
const OFFICIAL_PLUGIN_SOURCE_URL = environment.pluginStore.defaultSourceUrls[0];
|
||||
|
||||
describe('PluginStoreService', () => {
|
||||
let fetchMock: ReturnType<typeof vi.fn>;
|
||||
let registerLocalManifest: ReturnType<typeof vi.fn>;
|
||||
@@ -36,42 +40,79 @@ describe('PluginStoreService', () => {
|
||||
});
|
||||
|
||||
it('loads plugin entries from source manifests and resolves relative links', async () => {
|
||||
fetchMock.mockResolvedValueOnce(jsonResponse({
|
||||
plugins: [
|
||||
{
|
||||
author: 'Ada Example',
|
||||
description: 'Adds better channel tools.',
|
||||
github: 'https://github.com/example/better-channels',
|
||||
id: 'example.better-channels',
|
||||
image: './images/better.png',
|
||||
install: './better/toju-plugin.json',
|
||||
readme: './better/README.md',
|
||||
title: 'Better Channels',
|
||||
version: '1.2.0'
|
||||
}
|
||||
],
|
||||
title: 'Example Plugins'
|
||||
}));
|
||||
mockFetchResponses(fetchMock, {
|
||||
'https://plugins.example.test/index.json': jsonResponse({
|
||||
plugins: [
|
||||
{
|
||||
author: 'Ada Example',
|
||||
description: 'Adds better channel tools.',
|
||||
github: 'https://github.com/example/better-channels',
|
||||
id: 'example.better-channels',
|
||||
image: './images/better.png',
|
||||
install: './better/toju-plugin.json',
|
||||
readme: './better/README.md',
|
||||
title: 'Better Channels',
|
||||
version: '1.2.0'
|
||||
}
|
||||
],
|
||||
title: 'Example Plugins'
|
||||
})
|
||||
});
|
||||
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
|
||||
await service.addSourceUrl('https://plugins.example.test/index.json#latest');
|
||||
|
||||
expect(service.sourceUrls()).toEqual(['https://plugins.example.test/index.json']);
|
||||
expect(service.sources()[0]?.title).toBe('Example Plugins');
|
||||
expect(service.availablePlugins()).toEqual([
|
||||
expect(service.sourceUrls()).toEqual([OFFICIAL_PLUGIN_SOURCE_URL, 'https://plugins.example.test/index.json']);
|
||||
|
||||
expect(service.sources().some((source) => source.title === 'Example Plugins')).toBe(true);
|
||||
expect(service.availablePlugins()).toContainEqual(expect.objectContaining({
|
||||
author: 'Ada Example',
|
||||
githubUrl: 'https://github.com/example/better-channels',
|
||||
id: 'example.better-channels',
|
||||
imageUrl: 'https://plugins.example.test/images/better.png',
|
||||
installUrl: 'https://plugins.example.test/better/toju-plugin.json',
|
||||
readmeUrl: 'https://plugins.example.test/better/README.md',
|
||||
sourceTitle: 'Example Plugins',
|
||||
title: 'Better Channels',
|
||||
version: '1.2.0'
|
||||
}));
|
||||
});
|
||||
|
||||
it('seeds the official plugin repository for new users', () => {
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
|
||||
expect(service.sourceUrls()).toEqual([OFFICIAL_PLUGIN_SOURCE_URL]);
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
OFFICIAL_PLUGIN_SOURCE_URL,
|
||||
expect.objectContaining({
|
||||
author: 'Ada Example',
|
||||
githubUrl: 'https://github.com/example/better-channels',
|
||||
id: 'example.better-channels',
|
||||
imageUrl: 'https://plugins.example.test/images/better.png',
|
||||
installUrl: 'https://plugins.example.test/better/toju-plugin.json',
|
||||
readmeUrl: 'https://plugins.example.test/better/README.md',
|
||||
sourceTitle: 'Example Plugins',
|
||||
title: 'Better Channels',
|
||||
version: '1.2.0'
|
||||
headers: { Accept: 'application/json' }
|
||||
})
|
||||
]);
|
||||
);
|
||||
});
|
||||
|
||||
it('adds the official plugin repository when loading legacy source lists', () => {
|
||||
storage.setItem('metoyou_plugin_store', JSON.stringify({
|
||||
installedPlugins: [],
|
||||
schemaVersion: 1,
|
||||
sourceUrls: ['https://plugins.example.test/index.json']
|
||||
}));
|
||||
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
|
||||
expect(service.sourceUrls()).toEqual([OFFICIAL_PLUGIN_SOURCE_URL, 'https://plugins.example.test/index.json']);
|
||||
});
|
||||
|
||||
it('keeps user-removed default sources removed after schema migration', () => {
|
||||
storage.setItem('metoyou_plugin_store', JSON.stringify({
|
||||
installedPlugins: [],
|
||||
schemaVersion: 2,
|
||||
sourceUrls: ['https://plugins.example.test/index.json']
|
||||
}));
|
||||
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
|
||||
expect(service.sourceUrls()).toEqual(['https://plugins.example.test/index.json']);
|
||||
});
|
||||
|
||||
it('accepts local source manifest paths and resolves relative file links', async () => {
|
||||
@@ -94,9 +135,10 @@ describe('PluginStoreService', () => {
|
||||
|
||||
await service.addSourceUrl('/home/ludde/Desktop/TestPlugin/plugin-source.json');
|
||||
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
expect(fetchMock).not.toHaveBeenCalledWith('/home/ludde/Desktop/TestPlugin/plugin-source.json', expect.anything());
|
||||
expect(readFile).toHaveBeenCalledWith('/home/ludde/Desktop/TestPlugin/plugin-source.json');
|
||||
expect(service.sourceUrls()).toEqual(['file:///home/ludde/Desktop/TestPlugin/plugin-source.json']);
|
||||
expect(service.sourceUrls()).toEqual([OFFICIAL_PLUGIN_SOURCE_URL, 'file:///home/ludde/Desktop/TestPlugin/plugin-source.json']);
|
||||
|
||||
expect(service.availablePlugins()).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'example.local-plugin',
|
||||
@@ -112,7 +154,9 @@ describe('PluginStoreService', () => {
|
||||
const manifest = createManifest({ version: '1.0.0' });
|
||||
const plugin = createStoreEntry({ version: '1.0.0' });
|
||||
|
||||
fetchMock.mockResolvedValueOnce(jsonResponse(manifest));
|
||||
mockFetchResponses(fetchMock, {
|
||||
[plugin.installUrl ?? '']: jsonResponse(manifest)
|
||||
});
|
||||
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
|
||||
@@ -141,9 +185,10 @@ describe('PluginStoreService', () => {
|
||||
writeFile: vi.fn(async () => true)
|
||||
};
|
||||
|
||||
fetchMock
|
||||
.mockResolvedValueOnce(jsonResponse(manifest))
|
||||
.mockResolvedValueOnce(textResponse('export function activate() {}'));
|
||||
mockFetchResponses(fetchMock, {
|
||||
[plugin.bundleUrl ?? '']: textResponse('export function activate() {}'),
|
||||
[plugin.installUrl ?? '']: jsonResponse(manifest)
|
||||
});
|
||||
|
||||
const service = createService(registerLocalManifest, unregister, electronApi);
|
||||
|
||||
@@ -171,7 +216,9 @@ describe('PluginStoreService', () => {
|
||||
it('loads plugin readmes as markdown text', async () => {
|
||||
const plugin = createStoreEntry({ readmeUrl: 'https://plugins.example.test/better/README.md' });
|
||||
|
||||
fetchMock.mockResolvedValueOnce(textResponse('# Better Channels'));
|
||||
mockFetchResponses(fetchMock, {
|
||||
[plugin.readmeUrl ?? '']: textResponse('# Better Channels')
|
||||
});
|
||||
|
||||
const service = createService(registerLocalManifest, unregister);
|
||||
const readme = await service.loadReadme(plugin);
|
||||
@@ -185,6 +232,21 @@ describe('PluginStoreService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function mockFetchResponses(fetchMock: ReturnType<typeof vi.fn>, responses: Record<string, Response>): void {
|
||||
fetchMock.mockImplementation(async (url: RequestInfo | URL) => {
|
||||
const requestUrl = typeof url === 'string'
|
||||
? url
|
||||
: url instanceof URL
|
||||
? url.toString()
|
||||
: url.url;
|
||||
|
||||
return responses[requestUrl]
|
||||
?? (requestUrl === OFFICIAL_PLUGIN_SOURCE_URL
|
||||
? jsonResponse({ plugins: [], title: 'Official Toju Plugins' })
|
||||
: textResponse(''));
|
||||
});
|
||||
}
|
||||
|
||||
function createService(
|
||||
registerLocalManifest: ReturnType<typeof vi.fn>,
|
||||
unregister: ReturnType<typeof vi.fn>,
|
||||
@@ -220,6 +282,12 @@ function createService(
|
||||
writeJson: vi.fn(async () => undefined)
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: PluginCapabilityService,
|
||||
useValue: {
|
||||
grantAll: vi.fn()
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: PluginRegistryService,
|
||||
useValue: { unregister }
|
||||
|
||||
Reference in New Issue
Block a user