jan/electron/core/plugin-manager/execution/activation-manager.test.js
Louis afbb94f083
efactor app directories and enforce ts strict mode (#201)
* refactor: move Electron app to main directory and enforce ts strict mode

* chore: add pre-install plugins

* remove duplicated initModel function

Signed-off-by: James <james@jan.ai>

* chore: correct module path

* fix: dynamic import does not work with ts

* chore: web should be able to run on target host browser

* fix: history panel, should display conversations rather just blank state

* chore: init default model

* chore: pluggin in ts

* fix: pre-pack model management

* fix: compiled core should not include plugins

* chore: refactor - invoke plugin function

* refactor download/delete file

Signed-off-by: James <james@jan.ai>

* update prebuild lib

Signed-off-by: James <james@jan.ai>

* chore: yarn workspace

* chore: update yarn workspace

* chore: yarn workspace with nohoist

* fix: llama-cpp-import

* chore: fix data-plugin wrong module path

* chore: correct build step

* chore: 	- separate inference service (#212)

- remove base-plugin

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>

* chore: update core plugins

* chore: hide installation prompt and fix model load - management plugin

* chore: remove legacy files; update readme

* fix: refresh page lost the download state

Signed-off-by: James <james@jan.ai>

* fix: ai prompt not passed to plugin

Signed-off-by: James <james@jan.ai>

* chore: module import fix for production

* chore: auto updater

* chore: package is public

* chore: fix yarn workspace config

* update: model management uses Q4_K_M

* chore: fix yarn scripts for publishing

* chore: app updater - progress update message

* chore: user confirms update action

* adding some state for changing page
store downloaded model to database

Signed-off-by: James <james@jan.ai>

* chore: refactor plugins into yarn workspace - a single command to publish all base plugins

* chore update readme (#218)

Co-authored-by: Hien To <tominhhien97@gmail.com>

* change app name and app icon

Signed-off-by: James <james@jan.ai>

* remove: go-to-nowhere actions

* chore: bundle core plugins from root and scan default plugins

* fix: app crashes on different field name lookup

* chore: css fix

* chore: bind download progress to app ui

* chore: bind active model

* chore: simplify app splash-screen only centered jan icon

* feature: system monitoring plugin (#196)

* feat: Add function for system monitoring

* chore: register plugin functions

* chore: move to corresponding directory

* chore: bind system monitoring data to UI

---------

Co-authored-by: Louis <louis@jan.ai>

* chore: add build:plugins step to README

* chore: model searching and fix model name

* fix: plugin file selected appearance

* fix: create new conversation does not work

* fix: delete conversation not update state - messages still exist

* chore: fix asset path prefix

* Add CICD for macos (#221)

Co-authored-by: Hien To <tominhhien97@gmail.com>

* chore: fix production plugin path

* chore: add shell open url in external browser

---------

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
Co-authored-by: NamH <NamNh0122@gmail.com>
Co-authored-by: 0xSage <n@pragmatic.vc>
Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com>
Co-authored-by: Hien To <tominhhien97@gmail.com>
Co-authored-by: namvuong <22463238+vuonghoainam@users.noreply.github.com>
2023-09-28 18:15:18 +07:00

308 lines
6.9 KiB
JavaScript

import { setup } from './index'
import { register, trigger, remove, clear, get } from "./activation-manager";
import { add } from './extension-manager'
let mockPlugins = {}
setup({
importer(plugin) { return mockPlugins[plugin] }
})
afterEach(() => {
clear()
mockPlugins = {}
})
describe('register', () => {
it('should add a new activation point to the register when a new, valid plugin is registered',
() => {
register({
name: 'test',
url: 'testPkg',
activationPoints: ['ap1', 'ap2'],
active: true
})
expect(get()).toEqual([
{
plugin: 'test',
url: 'testPkg',
activationPoint: 'ap1',
activated: false
},
{
plugin: 'test',
url: 'testPkg',
activationPoint: 'ap2',
activated: false
}
])
}
)
it('should not add an activation point to the register when an existing, valid plugin is registered',
() => {
register({
name: 'test',
url: 'testPkg',
activationPoints: ['ap1', 'ap2'],
active: true
})
register({
name: 'test',
url: 'testPkg',
activationPoints: ['ap2', 'ap3'],
active: true
})
expect(get()).toEqual([
{
plugin: 'test',
url: 'testPkg',
activationPoint: 'ap1',
activated: false
},
{
plugin: 'test',
url: 'testPkg',
activationPoint: 'ap2',
activated: false
},
{
plugin: 'test',
url: 'testPkg',
activationPoint: 'ap3',
activated: false
},
])
}
)
it('should throw an error when an invalid plugin is registered',
() => {
const noActivationPoints = () => register({
name: 'test',
url: 'testPkg',
active: true
})
expect(noActivationPoints).toThrow(/does not have any activation points set up in its manifest/)
}
)
})
describe('trigger', () => {
it('should trigger all and only the activations with for the given execution point on triggering an execution, using the defined importer',
async () => {
const triggered = []
mockPlugins.plugin1 = {
ap1() { triggered.push('plugin1-ap1') }
}
mockPlugins.plugin2 = {
ap2() { triggered.push('plugin2-ap2') }
}
mockPlugins.plugin3 = {
ap1() { triggered.push('plugin3-ap1') },
ap2() { triggered.push('plugin3-ap2') }
}
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1'],
active: true
})
register({
name: 'plugin2',
url: 'plugin2',
activationPoints: ['ap2'],
active: true
})
register({
name: 'plugin3',
url: 'plugin3',
activationPoints: ['ap1', 'ap2'],
active: true
})
await trigger('ap1')
expect(triggered).toEqual(['plugin1-ap1', 'plugin3-ap1'])
}
)
it('should return an error if an activation point is triggered on a plugin that does not include it',
async () => {
mockPlugins.plugin1 = {
wrongAp() { }
}
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1']
})
await expect(() => trigger('ap1')).rejects.toThrow(/was triggered but does not exist on plugin/)
}
)
it('should provide the registered extension points to the triggered activation point if presetEPs is set to true in the setup',
async () => {
setup({
importer(plugin) { return mockPlugins[plugin] },
presetEPs: true,
})
let ap1Res
mockPlugins.plugin1 = {
ap1: eps => ap1Res = eps
}
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1']
})
add('ep1')
add('ep2')
await trigger('ap1')
expect(ap1Res.ep1.constructor.name).toEqual('ExtensionPoint')
expect(ap1Res.ep2.constructor.name).toEqual('ExtensionPoint')
}
)
it('should allow registration, execution and serial execution of execution points when an activation point is triggered if presetEPs is set to false in the setup',
async () => {
setup({
importer(plugin) { return mockPlugins[plugin] },
})
let ap1Res
mockPlugins.plugin1 = {
ap1: eps => ap1Res = eps
}
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1']
})
await trigger('ap1')
expect(typeof ap1Res.register).toBe('function')
expect(typeof ap1Res.execute).toBe('function')
expect(typeof ap1Res.executeSerial).toBe('function')
}
)
it('should not provide any reference to extension points during activation point triggering if presetEPs is set to null in the setup',
async () => {
setup({
importer(plugin) { return mockPlugins[plugin] },
presetEPs: null,
})
let ap1Res = true
mockPlugins.plugin1 = {
ap1: eps => ap1Res = eps
}
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1']
})
await trigger('ap1')
expect(ap1Res).not.toBeDefined()
}
)
})
describe('remove and clear', () => {
beforeEach(() => {
register({
name: 'plugin1',
url: 'plugin1',
activationPoints: ['ap1', 'ap2'],
active: true
})
register({
name: 'plugin2',
url: 'plugin2',
activationPoints: ['ap2', 'ap3'],
active: true
})
})
it('should remove all and only the activations for the given plugin from the register when removing activations',
() => {
remove('plugin1')
expect(get()).toEqual([
{
plugin: 'plugin2',
url: 'plugin2',
activationPoint: 'ap2',
activated: false
},
{
plugin: 'plugin2',
url: 'plugin2',
activationPoint: 'ap3',
activated: false
},
])
}
)
it('should not remove any activations from the register if no plugin name is provided',
() => {
remove()
expect(get()).toEqual([
{
plugin: 'plugin1',
url: 'plugin1',
activationPoint: 'ap1',
activated: false
},
{
plugin: 'plugin1',
url: 'plugin1',
activationPoint: 'ap2',
activated: false
},
{
plugin: 'plugin2',
url: 'plugin2',
activationPoint: 'ap2',
activated: false
},
{
plugin: 'plugin2',
url: 'plugin2',
activationPoint: 'ap3',
activated: false
},
])
}
)
it('should remove all activations from the register when clearing the register',
() => {
clear()
expect(get()).toEqual([])
}
)
})