This repository has been archived by the owner on Mar 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: plugin sandbox composition (#1507)
* wip * refactor: move component sandbox methods to specific folder * feat: add PROFILE_ALL permission * feat: add PROFILE_CURRENT permission * feat: add PEER_CURRENT permission * feat: add STORAGE permission * feat: add AUDIO permission * feat: add EVENTS permission * feat: add ALERTS permission * fix: component validation * refactor: move THEMES permission to setup * test: add component validation specs * refactor: timers and websocket sandbox specs * test: add audio sandbox specs * test: add http sandbox specs * test: add profile-all sandbox specs * test: add alerts and events sandbox specs * test: add font awesome and messaging sandbox specs * test: fix profile all sandbox * test: add profile current and webframe sandbox specs * 'test: add ui components and storage sandbox specs * test: peer current and route sandbox specs * test: add avatars setup specs * test: add wallet tabs setup specs * test: register setup specs * fix: ui components sandbox * test: add menu items setup specs * test: add routes setup specs * test: add themes setup specs * test: add prepare context specs * test: add define context specs * fix: relative imports * refactor: create safe component * test: add components setup specs * feat: global components * fix: compile template * fix: don't load a disabled plugin * test: add plugin-manager specs * fix: lint * fix: remove document object from component sandbox * fix: props * fix: sync changes on props * refactor: block ref methods * test: blocked ref methods * fix: component name output in log * style: validate component method * fix: global components * fix: computed data * test: add methods * fix: add root path to sandbox external modules * fix: pass arguments to plugin methods * fix: resolve method * fix: regex check for html events
- Loading branch information
1 parent
01ed43d
commit 9f31f03
Showing
70 changed files
with
2,827 additions
and
965 deletions.
There are no files selected for viewing
6 changes: 6 additions & 0 deletions
6
__tests__/unit/__mocks__/@/services/plugin-manager/component/compile-template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default jest.fn().mockImplementation(() => ({ | ||
compileTemplate: jest.fn((vm, template) => { | ||
const { compileToFunctions } = require('vue-template-compiler') | ||
return compileToFunctions(template) | ||
}) | ||
})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import * as fs from 'fs' | ||
import * as fsExtra from 'fs-extra' | ||
import { createLocalVue } from '@vue/test-utils' | ||
import { PluginManager } from '@/services/plugin-manager' | ||
import { PluginSandbox } from '@/services/plugin-manager/plugin-sandbox' | ||
import { PluginSetup } from '@/services/plugin-manager/plugin-setup' | ||
|
||
jest.mock('@/services/plugin-manager/plugin-sandbox.js') | ||
jest.mock('@/services/plugin-manager/plugin-setup.js') | ||
|
||
jest.mock('fs-extra', () => ({ | ||
ensureDirSync: jest.fn(), | ||
readdirSync: jest.fn(() => []), | ||
lstatSync: jest.fn(() => ({ | ||
isDirectory: jest.fn(() => true) | ||
})) | ||
})) | ||
|
||
jest.mock('@/services/plugin-manager/utils/validate-plugin-path.js', () => ({ | ||
validatePluginPath: jest.fn() | ||
})) | ||
|
||
const mockDispatch = jest.fn() | ||
const mockSandboxInstall = jest.fn() | ||
const mockSandboxSetup = jest.fn() | ||
|
||
PluginSandbox.mockImplementation(() => ({ | ||
install: mockSandboxInstall | ||
})) | ||
|
||
PluginSetup.mockImplementation(() => ({ | ||
install: mockSandboxSetup | ||
})) | ||
|
||
const localVue = createLocalVue() | ||
|
||
const pkg = { | ||
name: 'plugin-test', | ||
description: 'Test', | ||
title: 'Plugin Test', | ||
version: '0.0.1' | ||
} | ||
|
||
const app = { | ||
$store: { | ||
dispatch: mockDispatch, | ||
getters: { | ||
'plugin/isEnabled': jest.fn((pluginId) => pluginId === 'plugin-test'), | ||
'profile/byId': jest.fn(() => {}) | ||
} | ||
} | ||
} | ||
|
||
let pluginManager | ||
|
||
beforeEach(() => { | ||
mockDispatch.mockReset() | ||
pluginManager = new PluginManager() | ||
pluginManager.setVue(localVue) | ||
}) | ||
|
||
describe('Plugin Manager', () => { | ||
it('should load plugins on init', async () => { | ||
await pluginManager.init(app) | ||
expect(app.$store.dispatch).toHaveBeenNthCalledWith(1, 'plugin/init') | ||
expect(app.$store.dispatch).toHaveBeenNthCalledWith(2, 'plugin/loadPluginsForProfiles') | ||
}) | ||
|
||
describe('Fetch plugins', () => { | ||
it('should read plugins from path', async () => { | ||
jest.spyOn(fsExtra, 'readdirSync').mockReturnValue(['plugin-1']) | ||
jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify(pkg)) | ||
|
||
await pluginManager.init(app) | ||
|
||
expect(app.$store.dispatch).toHaveBeenCalledWith('plugin/setAvailable', | ||
expect.objectContaining({ | ||
config: expect.any(Object), | ||
fullPath: expect.any(String) | ||
}) | ||
) | ||
}) | ||
}) | ||
|
||
describe('Enable plugin', () => { | ||
it('should throw not initiated error', async () => { | ||
expect.assertions(1) | ||
try { | ||
await pluginManager.enablePlugin('plugin-1', 'p-1') | ||
} catch (e) { | ||
expect(e.message).toBe('Plugin Manager not initiated') | ||
} | ||
}) | ||
|
||
it('should throw not found error', async () => { | ||
expect.assertions(1) | ||
await pluginManager.init(app) | ||
try { | ||
await pluginManager.enablePlugin('plugin-not-loaded', 'p-1') | ||
} catch (e) { | ||
expect(e.message).toBe('Plugin not found') | ||
} | ||
}) | ||
|
||
it('should throw not enabled error', async () => { | ||
expect.assertions(2) | ||
await pluginManager.init(app) | ||
pluginManager.plugins = { | ||
'plugin-not-enabled': { | ||
config: { | ||
id: '1' | ||
} | ||
} | ||
} | ||
try { | ||
await pluginManager.enablePlugin('plugin-not-enabled', 'p-1') | ||
} catch (e) { | ||
expect(e.message).toBe('Plugin is not enabled') | ||
expect(app.$store.getters['plugin/isEnabled']).toHaveBeenCalled() | ||
} | ||
}) | ||
|
||
it('should enable', async () => { | ||
await pluginManager.init(app) | ||
|
||
pluginManager.plugins = { | ||
[pkg.name]: { | ||
config: { | ||
id: pkg.name | ||
}, | ||
fullPath: './test' | ||
} | ||
} | ||
|
||
await pluginManager.enablePlugin(pkg.name, 'p-1') | ||
expect(mockDispatch).toHaveBeenCalledWith('plugin/setLoaded', expect.any(Object)) | ||
expect(mockSandboxInstall).toHaveBeenCalled() | ||
expect(mockSandboxSetup).toHaveBeenCalled() | ||
}) | ||
}) | ||
|
||
describe('Disable plugin', () => { | ||
it('should throw not initiated error', async () => { | ||
expect.assertions(1) | ||
try { | ||
await pluginManager.disablePlugin('plugin-1', 'p-1') | ||
} catch (e) { | ||
expect(e.message).toBe('Plugin Manager not initiated') | ||
} | ||
}) | ||
|
||
it('should throw not found error', async () => { | ||
expect.assertions(1) | ||
await pluginManager.init(app) | ||
try { | ||
await pluginManager.disablePlugin('plugin-not-loaded', 'p-1') | ||
} catch (e) { | ||
expect(e.message).toBe('Plugin `plugin-not-loaded` not found') | ||
} | ||
}) | ||
|
||
it('should disable', async () => { | ||
await pluginManager.init(app) | ||
pluginManager.plugins = { | ||
[pkg.name]: { | ||
config: { | ||
id: pkg.name, | ||
permissions: [] | ||
} | ||
} | ||
} | ||
|
||
await pluginManager.disablePlugin(pkg.name, 'p-1') | ||
expect(mockDispatch).toHaveBeenCalledWith('plugin/deleteLoaded', pkg.name) | ||
}) | ||
|
||
it('should unload theme', async () => { | ||
await pluginManager.init(app) | ||
pluginManager.plugins = { | ||
[pkg.name]: { | ||
config: { | ||
id: pkg.name, | ||
permissions: ['THEMES'] | ||
} | ||
} | ||
} | ||
|
||
await pluginManager.disablePlugin(pkg.name, 'p-1') | ||
expect(mockDispatch).toHaveBeenCalledWith('plugin/deleteLoaded', pkg.name) | ||
expect(mockDispatch).toHaveBeenCalledWith('session/setTheme', expect.any(String)) | ||
expect(mockDispatch).toHaveBeenCalledWith('profile/update', expect.any(Object)) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.