1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-18 09:35:20 +02:00
joplin/packages/lib/services/plugins/loadPlugins.test.ts
2024-08-02 14:51:49 +01:00

161 lines
5.2 KiB
TypeScript

import Setting from '../../models/Setting';
import PluginService, { defaultPluginSetting } from '../../services/plugins/PluginService';
import { PluginManifest } from '../../services/plugins/utils/types';
import { setupDatabaseAndSynchronizer, switchClient } from '../../testing/test-utils';
import { writeFile } from 'fs-extra';
import { join } from 'path';
import loadPlugins, { Props as LoadPluginsProps } from './loadPlugins';
import MockPluginRunner from './testing/MockPluginRunner';
import reducer, { State, defaultState } from '../../reducer';
import { Action, createStore } from 'redux';
import MockPlatformImplementation from './testing/MockPlatformImplementation';
const createMockReduxStore = () => {
return createStore((state: State = defaultState, action: Action<string>) => {
return reducer(state, action);
});
};
const setPluginEnabled = (id: string, enabled: boolean) => {
const newPluginStates = {
...Setting.value('plugins.states'),
[id]: {
...defaultPluginSetting(),
enabled,
},
};
Setting.setValue('plugins.states', newPluginStates);
};
const addPluginWithManifest = async (manifest: PluginManifest, enabled: boolean) => {
const pluginSource = `
/* joplin-manifest:
${JSON.stringify(manifest)}
*/
joplin.plugins.register({
onStart: async function() { },
});
`;
const pluginPath = join(Setting.value('pluginDir'), `${manifest.id}.js`);
await writeFile(pluginPath, pluginSource, 'utf-8');
setPluginEnabled(manifest.id, enabled);
};
const defaultManifestProperties = {
manifest_version: 1,
version: '0.1.0',
app_min_version: '2.3.4',
platforms: ['desktop', 'mobile'],
};
const platformImplementation = new MockPlatformImplementation();
describe('loadPlugins', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
});
afterEach(async () => {
for (const id of PluginService.instance().pluginIds) {
await PluginService.instance().unloadPlugin(id);
}
await PluginService.instance().destroy();
});
test('should load only enabled plugins', async () => {
await addPluginWithManifest({
...defaultManifestProperties,
id: 'this.is.a.test.1',
name: 'Disabled Plugin',
}, false);
const enabledPluginId = 'this.is.a.test.2';
await addPluginWithManifest({
...defaultManifestProperties,
id: enabledPluginId,
name: 'Enabled Plugin',
}, true);
const pluginRunner = new MockPluginRunner();
const store = createMockReduxStore();
const loadPluginsOptions: LoadPluginsProps = {
pluginRunner,
pluginSettings: Setting.value('plugins.states'),
platformImplementation,
store,
reloadAll: false,
cancelEvent: { cancelled: false },
};
expect(Object.keys(PluginService.instance().plugins)).toHaveLength(0);
await loadPlugins(loadPluginsOptions);
await pluginRunner.waitForAllToBeRunning([enabledPluginId]);
expect(pluginRunner.runningPluginIds).toMatchObject([enabledPluginId]);
// No plugins were running before, so none should be stopped.
expect(pluginRunner.stopCalledTimes).toBe(0);
// Loading again should not re-run plugins
await loadPlugins(loadPluginsOptions);
// Should have tried to stop at most the disabled plugin (which is a no-op).
expect(pluginRunner.stopCalledTimes).toBe(1);
expect(pluginRunner.runningPluginIds).toMatchObject([enabledPluginId]);
});
test('should reload all plugins when reloadAll is true', async () => {
const enabledCount = 3;
for (let i = 0; i < enabledCount; i++) {
await addPluginWithManifest({
...defaultManifestProperties,
id: `joplin.test.plugin.${i}`,
name: `Enabled Plugin ${i}`,
}, true);
}
const disabledCount = 6;
for (let i = 0; i < disabledCount; i++) {
await addPluginWithManifest({
...defaultManifestProperties,
id: `joplin.test.plugin.disabled.${i}`,
name: `Disabled Plugin ${i}`,
}, false);
}
const pluginRunner = new MockPluginRunner();
const store = createMockReduxStore();
const loadPluginsOptions: LoadPluginsProps = {
pluginRunner,
pluginSettings: Setting.value('plugins.states'),
platformImplementation,
store,
reloadAll: true,
cancelEvent: { cancelled: false },
};
await loadPlugins(loadPluginsOptions);
let expectedRunningIds = ['joplin.test.plugin.0', 'joplin.test.plugin.1', 'joplin.test.plugin.2'];
await pluginRunner.waitForAllToBeRunning(expectedRunningIds);
// No additional plugins should be running.
expect([...pluginRunner.runningPluginIds].sort()).toMatchObject(expectedRunningIds);
// No plugins were running before -- there were no plugins to stop
expect(pluginRunner.stopCalledTimes).toBe(0);
// Enabling a plugin and reloading it should cause all plugins to load.
setPluginEnabled('joplin.test.plugin.disabled.2', true);
await loadPlugins({ ...loadPluginsOptions, pluginSettings: Setting.value('plugins.states') });
expectedRunningIds = ['joplin.test.plugin.0', 'joplin.test.plugin.1', 'joplin.test.plugin.2', 'joplin.test.plugin.disabled.2'];
await pluginRunner.waitForAllToBeRunning(expectedRunningIds);
// Reloading all should stop all plugins and rerun enabled plugins, even
// if not enabled previously.
expect(pluginRunner.stopCalledTimes).toBe(disabledCount + enabledCount);
expect([...pluginRunner.runningPluginIds].sort()).toMatchObject(expectedRunningIds);
});
});