mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-12 08:54:00 +02:00
3d8577a689
- For now, supports Markdown-it plugins - Also fixed slow rendering of notes in some cases - Simplified how Markdown-It plugins are created and cleaned MdToHtml code commit89576de289
Merge:c75aa21f
5292fc14
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:23:00 2020 +0100 Merge branch 'release-1.3' into plugin_content_scripts commitc75aa21ffd
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:19:52 2020 +0100 Fixed tests commit075187729d
Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:11:53 2020 +0100 Fixed tests commit14696b8c65
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 23:27:58 2020 +0100 Fixed slow rendering of note commit61c09f5bf8
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 22:35:21 2020 +0100 Clean up commit9f7ea7d865
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 20:05:31 2020 +0100 Updated doc commit98bf3bde8d
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 19:56:34 2020 +0100 Finished converting plugins commitfe90d92e01
Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 17:52:02 2020 +0100 Simplified how Markdown-It plugins are created commit47c7b864cb
Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 16:40:11 2020 +0100 Clean up rules commitd927a238bb
Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:29:40 2020 +0100 Fixed tests commit388a56c5dd
Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:00:47 2020 +0100 Add support for content scripts
205 lines
5.8 KiB
TypeScript
205 lines
5.8 KiB
TypeScript
import PluginRunner from '../app/services/plugins/PluginRunner';
|
|
import PluginService from 'lib/services/plugins/PluginService';
|
|
import { ContentScriptType } from 'lib/services/plugins/api/types';
|
|
import MdToHtml from 'lib/joplin-renderer/MdToHtml';
|
|
import Setting from 'lib/models/Setting';
|
|
import shim from 'lib/shim';
|
|
import uuid from 'lib/uuid';
|
|
|
|
require('app-module-path').addPath(__dirname);
|
|
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow } = require('test-utils.js');
|
|
const Note = require('lib/models/Note');
|
|
const Folder = require('lib/models/Folder');
|
|
|
|
process.on('unhandledRejection', (reason, p) => {
|
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
|
});
|
|
|
|
const testPluginDir = `${__dirname}/../tests/support/plugins`;
|
|
|
|
function newPluginService() {
|
|
const runner = new PluginRunner();
|
|
const service = new PluginService();
|
|
service.initialize(
|
|
{
|
|
joplin: {
|
|
workspace: {},
|
|
},
|
|
},
|
|
runner,
|
|
{
|
|
dispatch: () => {},
|
|
getState: () => {},
|
|
}
|
|
);
|
|
return service;
|
|
}
|
|
|
|
describe('services_PluginService', function() {
|
|
|
|
beforeEach(async (done) => {
|
|
await setupDatabaseAndSynchronizer(1);
|
|
await switchClient(1);
|
|
done();
|
|
});
|
|
|
|
it('should load and run a simple plugin', asyncTest(async () => {
|
|
const service = newPluginService();
|
|
await service.loadAndRunPlugins([`${testPluginDir}/simple`]);
|
|
|
|
const allFolders = await Folder.all();
|
|
expect(allFolders.length).toBe(1);
|
|
expect(allFolders[0].title).toBe('my plugin folder');
|
|
|
|
const allNotes = await Note.all();
|
|
expect(allNotes.length).toBe(1);
|
|
expect(allNotes[0].title).toBe('testing plugin!');
|
|
expect(allNotes[0].parent_id).toBe(allFolders[0].id);
|
|
}));
|
|
|
|
it('should load and run a plugin that uses external packages', asyncTest(async () => {
|
|
const service = newPluginService();
|
|
await service.loadAndRunPlugins([`${testPluginDir}/withExternalModules`]);
|
|
const plugin = service.pluginById('withexternalmodules');
|
|
expect(plugin.id).toBe('withexternalmodules');
|
|
|
|
const allFolders = await Folder.all();
|
|
expect(allFolders.length).toBe(1);
|
|
expect(allFolders[0].title).toBe(' foo');
|
|
}));
|
|
|
|
it('should load multiple plugins from a directory', asyncTest(async () => {
|
|
const service = newPluginService();
|
|
await service.loadAndRunPlugins(`${testPluginDir}/multi_plugins`);
|
|
|
|
const plugin1 = service.pluginById('simple1');
|
|
const plugin2 = service.pluginById('simple2');
|
|
expect(!!plugin1).toBe(true);
|
|
expect(!!plugin2).toBe(true);
|
|
|
|
const allFolders = await Folder.all();
|
|
expect(allFolders.length).toBe(2);
|
|
expect(allFolders.map((f:any) => f.title).sort().join(', ')).toBe('multi - simple1, multi - simple2');
|
|
}));
|
|
|
|
it('should load plugins from JS bundles', asyncTest(async () => {
|
|
const service = newPluginService();
|
|
|
|
const plugin = await service.loadPluginFromString('example', '/tmp', `
|
|
/* joplin-manifest:
|
|
{
|
|
"manifest_version": 1,
|
|
"name": "JS Bundle test",
|
|
"description": "JS Bundle Test plugin",
|
|
"version": "1.0.0",
|
|
"author": "Laurent Cozic",
|
|
"homepage_url": "https://joplinapp.org"
|
|
}
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
onStart: async function() {
|
|
await joplin.data.post(['folders'], null, { title: "my plugin folder" });
|
|
},
|
|
});
|
|
`);
|
|
|
|
await service.runPlugin(plugin);
|
|
|
|
expect(plugin.manifest.manifest_version).toBe(1);
|
|
expect(plugin.manifest.name).toBe('JS Bundle test');
|
|
|
|
const allFolders = await Folder.all();
|
|
expect(allFolders.length).toBe(1);
|
|
}));
|
|
|
|
it('should load plugins from JS bundle files', asyncTest(async () => {
|
|
const service = newPluginService();
|
|
await service.loadAndRunPlugins(`${testPluginDir}/jsbundles`);
|
|
expect(!!service.pluginById('example')).toBe(true);
|
|
expect((await Folder.all()).length).toBe(1);
|
|
}));
|
|
|
|
it('should validate JS bundles', asyncTest(async () => {
|
|
const invalidJsBundles = [
|
|
`
|
|
/* joplin-manifest:
|
|
{
|
|
"not_a_valid_manifest_at_all": 1
|
|
}
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
onStart: async function() {},
|
|
});
|
|
`, `
|
|
/* joplin-manifest:
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
onStart: async function() {},
|
|
});
|
|
`, `
|
|
joplin.plugins.register({
|
|
onStart: async function() {},
|
|
});
|
|
`, '',
|
|
];
|
|
|
|
const service = newPluginService();
|
|
|
|
for (const jsBundle of invalidJsBundles) {
|
|
await expectThrow(async () => await service.loadPluginFromString('example', '/tmp', jsBundle));
|
|
}
|
|
}));
|
|
|
|
it('should register a Markdown-it plugin', asyncTest(async () => {
|
|
const contentScriptPath = `${Setting.value('tempDir')}/markdownItTestPlugin${uuid.createNano()}.js`;
|
|
await shim.fsDriver().copy(`${testPluginDir}/content_script/src/markdownItTestPlugin.js`, contentScriptPath);
|
|
|
|
const service = newPluginService();
|
|
|
|
const plugin = await service.loadPluginFromString('example', Setting.value('tempDir'), `
|
|
/* joplin-manifest:
|
|
{
|
|
"manifest_version": 1,
|
|
"name": "JS Bundle test",
|
|
"description": "JS Bundle Test plugin",
|
|
"version": "1.0.0",
|
|
"author": "Laurent Cozic",
|
|
"homepage_url": "https://joplinapp.org"
|
|
}
|
|
*/
|
|
|
|
joplin.plugins.register({
|
|
onStart: async function() {
|
|
await joplin.plugins.registerContentScript('markdownItPlugin', 'justtesting', '${contentScriptPath}');
|
|
},
|
|
});
|
|
`);
|
|
|
|
await service.runPlugin(plugin);
|
|
|
|
const contentScripts = plugin.contentScriptsByType(ContentScriptType.MarkdownItPlugin);
|
|
expect(contentScripts.length).toBe(1);
|
|
expect(!!contentScripts[0].path).toBe(true);
|
|
|
|
const contentScript = contentScripts[0];
|
|
|
|
const mdToHtml = new MdToHtml();
|
|
const module = require(contentScript.path).default;
|
|
mdToHtml.loadExtraRendererRule(contentScript.id, module({}));
|
|
|
|
const result = await mdToHtml.render([
|
|
'```justtesting',
|
|
'something',
|
|
'```',
|
|
].join('\n'));
|
|
|
|
expect(result.html.includes('JUST TESTING: something')).toBe(true);
|
|
|
|
await shim.fsDriver().remove(contentScriptPath);
|
|
}));
|
|
|
|
});
|