2022-09-01 12:44:33 +02:00
|
|
|
import { installDefaultPlugins, getDefaultPluginsInstallState, setSettingsForDefaultPlugins, checkPreInstalledDefaultPlugins } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
|
|
|
|
import PluginRunner from '../../../app/services/plugins/PluginRunner';
|
|
|
|
import { pathExists } from 'fs-extra';
|
2022-09-12 17:08:06 +02:00
|
|
|
import { checkThrow, setupDatabaseAndSynchronizer, supportDir, switchClient } from '@joplin/lib/testing/test-utils';
|
2022-09-01 12:44:33 +02:00
|
|
|
import PluginService, { defaultPluginSetting, DefaultPluginsInfo, PluginSettings } from '@joplin/lib/services/plugins/PluginService';
|
|
|
|
import Setting from '@joplin/lib/models/Setting';
|
|
|
|
|
|
|
|
const testPluginDir = `${supportDir}/plugins`;
|
|
|
|
|
2023-06-30 10:11:26 +02:00
|
|
|
function newPluginService(appVersion = '1.4') {
|
2022-09-01 12:44:33 +02:00
|
|
|
const runner = new PluginRunner();
|
|
|
|
const service = new PluginService();
|
|
|
|
service.initialize(
|
|
|
|
appVersion,
|
|
|
|
{
|
|
|
|
joplin: {},
|
|
|
|
},
|
|
|
|
runner,
|
|
|
|
{
|
|
|
|
dispatch: () => {},
|
|
|
|
getState: () => {},
|
2023-08-22 12:58:53 +02:00
|
|
|
},
|
2022-09-01 12:44:33 +02:00
|
|
|
);
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
2023-02-20 17:02:29 +02:00
|
|
|
describe('defaultPluginsUtils', () => {
|
2022-09-01 12:44:33 +02:00
|
|
|
|
|
|
|
const pluginsId = ['joplin.plugin.ambrt.backlinksToNote', 'org.joplinapp.plugins.ToggleSidebars'];
|
|
|
|
|
2022-11-15 12:23:50 +02:00
|
|
|
beforeEach(async () => {
|
2022-09-01 12:44:33 +02:00
|
|
|
await setupDatabaseAndSynchronizer(1);
|
|
|
|
await switchClient(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should install default plugins with no previous default plugins installed', (async () => {
|
|
|
|
const testPluginDir = `${supportDir}/pluginRepo/plugins`;
|
|
|
|
Setting.setValue('installedDefaultPlugins', []);
|
|
|
|
|
|
|
|
const service = newPluginService('2.1');
|
|
|
|
|
|
|
|
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
|
|
|
|
|
|
|
|
const newPluginsSettings = await installDefaultPlugins(service, testPluginDir, pluginsId, pluginSettings);
|
|
|
|
|
|
|
|
const installedPluginPath1 = `${Setting.value('pluginDir')}/${pluginsId[0]}.jpl`;
|
|
|
|
const installedPluginPath2 = `${Setting.value('pluginDir')}/${pluginsId[1]}.jpl`;
|
|
|
|
|
|
|
|
expect(await pathExists(installedPluginPath1)).toBe(true);
|
|
|
|
expect(await pathExists(installedPluginPath2)).toBe(true);
|
|
|
|
|
|
|
|
expect(newPluginsSettings[pluginsId[0]]).toMatchObject(defaultPluginSetting());
|
|
|
|
expect(newPluginsSettings[pluginsId[1]]).toMatchObject(defaultPluginSetting());
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
it('should install default plugins with previous default plugins installed', (async () => {
|
|
|
|
|
|
|
|
const testPluginDir = `${supportDir}/pluginRepo/plugins`;
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['org.joplinapp.plugins.ToggleSidebars']);
|
|
|
|
|
|
|
|
const service = newPluginService('2.1');
|
|
|
|
|
|
|
|
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
|
|
|
|
|
|
|
|
const newPluginsSettings = await installDefaultPlugins(service, testPluginDir, pluginsId, pluginSettings);
|
|
|
|
|
|
|
|
const installedPluginPath1 = `${Setting.value('pluginDir')}/${pluginsId[0]}.jpl`;
|
|
|
|
const installedPluginPath2 = `${Setting.value('pluginDir')}/${pluginsId[1]}.jpl`;
|
|
|
|
|
|
|
|
expect(await pathExists(installedPluginPath1)).toBe(true);
|
|
|
|
expect(await pathExists(installedPluginPath2)).toBe(false);
|
|
|
|
|
|
|
|
expect(newPluginsSettings[pluginsId[0]]).toMatchObject(defaultPluginSetting());
|
|
|
|
expect(newPluginsSettings[pluginsId[1]]).toBeUndefined();
|
|
|
|
}));
|
|
|
|
|
|
|
|
it('should get default plugins install state', (async () => {
|
|
|
|
const testCases = [
|
|
|
|
{
|
|
|
|
'installedDefaultPlugins': [''],
|
|
|
|
'loadingPlugins': [`${testPluginDir}/simple`, `${testPluginDir}/jpl_test/org.joplinapp.FirstJplPlugin.jpl`],
|
|
|
|
'plugin1DefaultState': defaultPluginSetting(),
|
|
|
|
'plugin2DefaultState': defaultPluginSetting(),
|
|
|
|
'installedDefaultPlugins1': true,
|
|
|
|
'installedDefaultPlugins2': true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'installedDefaultPlugins': [''],
|
|
|
|
'loadingPlugins': [`${testPluginDir}/simple`],
|
|
|
|
'plugin1DefaultState': defaultPluginSetting(),
|
|
|
|
'plugin2DefaultState': undefined,
|
|
|
|
'installedDefaultPlugins1': true,
|
|
|
|
'installedDefaultPlugins2': false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'installedDefaultPlugins': ['org.joplinapp.plugins.Simple'],
|
|
|
|
'loadingPlugins': [`${testPluginDir}/simple`, `${testPluginDir}/jpl_test/org.joplinapp.FirstJplPlugin.jpl`],
|
|
|
|
'plugin1DefaultState': undefined,
|
|
|
|
'plugin2DefaultState': defaultPluginSetting(),
|
|
|
|
'installedDefaultPlugins1': true,
|
|
|
|
'installedDefaultPlugins2': true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'installedDefaultPlugins': ['org.joplinapp.plugins.Simple'],
|
|
|
|
'loadingPlugins': [`${testPluginDir}/simple`],
|
|
|
|
'plugin1DefaultState': undefined,
|
|
|
|
'plugin2DefaultState': undefined,
|
|
|
|
'installedDefaultPlugins1': true,
|
|
|
|
'installedDefaultPlugins2': false,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
for (const testCase of testCases) {
|
|
|
|
const service = newPluginService();
|
|
|
|
const pluginsId = ['org.joplinapp.plugins.Simple', 'org.joplinapp.FirstJplPlugin'];
|
|
|
|
|
|
|
|
Setting.setValue('installedDefaultPlugins', testCase.installedDefaultPlugins);
|
|
|
|
await service.loadAndRunPlugins(testCase.loadingPlugins, {});
|
|
|
|
|
|
|
|
// setting installedDefaultPlugins state
|
|
|
|
const defaultInstallStates: PluginSettings = getDefaultPluginsInstallState(service, pluginsId);
|
|
|
|
|
|
|
|
expect(defaultInstallStates[pluginsId[0]]).toStrictEqual(testCase.plugin1DefaultState);
|
|
|
|
expect(defaultInstallStates[pluginsId[1]]).toStrictEqual(testCase.plugin2DefaultState);
|
|
|
|
|
|
|
|
|
|
|
|
const installedDefaultPlugins = Setting.value('installedDefaultPlugins');
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(testCase.installedDefaultPlugins1);
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(testCase.installedDefaultPlugins2);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
it('should check pre-installed default plugins', (async () => {
|
|
|
|
// with previous pre-installed default plugins
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['']);
|
|
|
|
let pluginSettings, installedDefaultPlugins;
|
|
|
|
|
|
|
|
pluginSettings = { [pluginsId[0]]: defaultPluginSetting() };
|
|
|
|
checkPreInstalledDefaultPlugins(pluginsId, pluginSettings);
|
|
|
|
|
|
|
|
installedDefaultPlugins = Setting.value('installedDefaultPlugins');
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(true);
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(false);
|
|
|
|
|
|
|
|
|
|
|
|
// with no previous pre-installed default plugins
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['not-a-default-plugin']);
|
|
|
|
pluginSettings = {};
|
|
|
|
checkPreInstalledDefaultPlugins(pluginsId, pluginSettings);
|
|
|
|
|
|
|
|
installedDefaultPlugins = Setting.value('installedDefaultPlugins');
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(false);
|
|
|
|
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(false);
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
it('should set initial settings for default plugins', async () => {
|
|
|
|
const service = newPluginService();
|
|
|
|
|
|
|
|
const pluginScript = `
|
|
|
|
/* joplin-manifest:
|
|
|
|
{
|
|
|
|
"id": "io.github.jackgruber.backup",
|
|
|
|
"manifest_version": 1,
|
|
|
|
"app_min_version": "1.4",
|
|
|
|
"name": "JS Bundle test",
|
|
|
|
"version": "1.0.0"
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
|
|
onStart: async function() {
|
|
|
|
await joplin.settings.registerSettings({
|
|
|
|
path: {
|
|
|
|
value: "initial-path",
|
|
|
|
type: 2,
|
|
|
|
section: "backupSection",
|
|
|
|
public: true,
|
|
|
|
label: "Backup path",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
},
|
|
|
|
});`;
|
|
|
|
|
|
|
|
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
|
|
|
|
await service.runPlugin(plugin);
|
|
|
|
|
|
|
|
const defaultPluginsInfo: DefaultPluginsInfo = {
|
|
|
|
'io.github.jackgruber.backup': {
|
|
|
|
settings: {
|
|
|
|
'path': `${Setting.value('profileDir')}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'plugin.calebjohn.rich-markdown': {
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// with pre-installed default plugin
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['io.github.jackgruber.backup']);
|
|
|
|
setSettingsForDefaultPlugins(defaultPluginsInfo);
|
|
|
|
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe('initial-path');
|
|
|
|
await service.destroy();
|
|
|
|
|
|
|
|
// with no pre-installed default plugin
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['']);
|
|
|
|
setSettingsForDefaultPlugins(defaultPluginsInfo);
|
|
|
|
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe(`${Setting.value('profileDir')}`);
|
|
|
|
await service.destroy();
|
|
|
|
});
|
|
|
|
|
2022-09-12 17:08:06 +02:00
|
|
|
it('should not throw error on missing setting key', async () => {
|
|
|
|
|
|
|
|
const service = newPluginService();
|
|
|
|
|
|
|
|
const pluginScript = `
|
|
|
|
/* joplin-manifest:
|
|
|
|
{
|
|
|
|
"id": "io.github.jackgruber.backup",
|
|
|
|
"manifest_version": 1,
|
|
|
|
"app_min_version": "1.4",
|
|
|
|
"name": "JS Bundle test",
|
|
|
|
"version": "1.0.0"
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
|
|
onStart: async function() {
|
|
|
|
await joplin.settings.registerSettings({
|
|
|
|
path: {
|
|
|
|
value: "initial-path",
|
|
|
|
type: 2,
|
|
|
|
section: "backupSection",
|
|
|
|
public: true,
|
|
|
|
label: "Backup path",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
},
|
|
|
|
});`;
|
|
|
|
|
|
|
|
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
|
|
|
|
await service.runPlugin(plugin);
|
|
|
|
|
|
|
|
const defaultPluginsInfo: DefaultPluginsInfo = {
|
|
|
|
'io.github.jackgruber.backup': {
|
|
|
|
settings: {
|
|
|
|
'path': `${Setting.value('profileDir')}`,
|
|
|
|
'missing-key1': 'someValue',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'plugin.calebjohn.rich-markdown': {
|
|
|
|
settings: {
|
|
|
|
'missing-key2': 'someValue',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
Setting.setValue('installedDefaultPlugins', ['']);
|
|
|
|
expect(checkThrow(() => setSettingsForDefaultPlugins(defaultPluginsInfo))).toBe(false);
|
|
|
|
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe(`${Setting.value('profileDir')}`);
|
|
|
|
await service.destroy();
|
|
|
|
});
|
|
|
|
|
2022-09-01 12:44:33 +02:00
|
|
|
});
|