Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

Commit

Permalink
refactor: plugin sandbox composition (#1507)
Browse files Browse the repository at this point in the history
* 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
luciorubeens authored Oct 30, 2019
1 parent 01ed43d commit 9f31f03
Show file tree
Hide file tree
Showing 70 changed files with 2,827 additions and 965 deletions.
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)
})
}))
194 changes: 194 additions & 0 deletions __tests__/unit/services/plugin-manager.spec.js
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))
})
})
})
Loading

0 comments on commit 9f31f03

Please sign in to comment.