UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

206 lines (184 loc) • 6.77 kB
import { LobeChatPluginManifest, LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk'; import { describe, expect, it } from 'vitest'; import { DiscoverPluginItem } from '@/types/discover'; import { initialState } from '../../initialState'; import { ToolStoreState } from '../../initialState'; import { pluginSelectors } from './selectors'; const mockState = { ...initialState, pluginInstallLoading: { 'plugin-1': false, 'plugin-2': true, }, installedPlugins: [ { identifier: 'plugin-1', type: 'plugin', manifest: { identifier: 'plugin-1', api: [{ name: 'api-1' }], type: 'default', } as LobeChatPluginManifest, settings: { setting1: 'value1' }, }, { identifier: 'plugin-2', manifest: { identifier: 'plugin-2', api: [{ name: 'api-2' }], }, type: 'plugin', }, { identifier: 'plugin-3', manifest: { identifier: 'plugin-3', api: [{ name: 'api-3' }], }, type: 'customPlugin', }, ], oldPluginItems: [ { identifier: 'plugin-1', author: 'Author 1', createdAt: '2021-01-01', avatar: 'avatar-url-1', title: 'Plugin 1', homepage: 'http://homepage-1.com', } as DiscoverPluginItem, { identifier: 'plugin-2', author: 'Author 2', createdAt: '2022-02-02', meta: { avatar: 'avatar-url-2', title: 'Plugin 2' }, homepage: 'http://homepage-2.com', }, ], } as ToolStoreState; describe('pluginSelectors', () => { describe('getToolManifestById', () => { it('getToolManifestById should return the correct manifest', () => { const result = pluginSelectors.getToolManifestById('plugin-1')(mockState); expect(result).toEqual(mockState.installedPlugins[0].manifest); }); }); describe('getPluginMetaById', () => { it('should return the plugin metadata by id', () => { const result = pluginSelectors.getPluginMetaById('plugin-1')(mockState); const item = mockState.oldPluginItems[0]; expect(result).toEqual({ title: item.title, avatar: item.avatar, }); }); }); describe('getDevPluginById', () => { it('should return undefined for non-existing custom plugin', () => { const result = pluginSelectors.getCustomPluginById('non-existing')(mockState); expect(result).toBeUndefined(); }); it('should return custom plugin by id if exists', () => { const customPlugin = { type: 'customPlugin', identifier: 'custom-plugin', manifest: { identifier: 'custom-plugin', author: 'Custom Author', createAt: '2023-03-03', meta: { avatar: 'avatar-url-custom', title: 'Custom Plugin' }, homepage: 'http://homepage-custom.com', }, }; const stateWithCustomPlugin = { ...mockState, installedPlugins: [...mockState.installedPlugins, customPlugin], } as ToolStoreState; const result = pluginSelectors.getCustomPluginById('custom-plugin')(stateWithCustomPlugin); expect(result).toEqual(customPlugin); }); }); describe('getPluginSettingsById', () => { it('should return the plugin settings by id', () => { const mockSettings = { setting1: 'value1' }; const result = pluginSelectors.getPluginSettingsById('plugin-1')(mockState); expect(result).toEqual(mockSettings); }); }); describe('hasPluginUI', () => { it('should return false when the plugin does not have a UI component', () => { const result = pluginSelectors.isPluginHasUI('non-ui-plugin')(mockState); expect(result).toBe(false); }); it('should return true when the plugin has a UI component', () => { const stateWithUIPlugin = { ...mockState, installedPlugins: [ ...mockState.installedPlugins, { ...mockState.installedPlugins[0], identifier: 'ui-plugin', manifest: { ...mockState.installedPlugins[0].manifest, identifier: 'ui-plugin', ui: true, }, }, ], } as ToolStoreState; const result = pluginSelectors.isPluginHasUI('ui-plugin')(stateWithUIPlugin); expect(result).toBe(true); }); }); describe('isPluginInstalled', () => { it('should return true if the plugin is installed', () => { const result = pluginSelectors.isPluginInstalled('plugin-1')(mockState); expect(result).toBe(true); }); it('should return false if the plugin is not installed', () => { const result = pluginSelectors.isPluginInstalled('non-installed-plugin')(mockState); expect(result).toBe(false); }); }); describe('getInstalledPluginById', () => { it('should return the installed plugin by id', () => { const result = pluginSelectors.getInstalledPluginById('plugin-1')(mockState); expect(result).toEqual(mockState.installedPlugins[0]); }); it('should return undefined if the plugin is not installed', () => { const result = pluginSelectors.getInstalledPluginById('non-installed-plugin')(mockState); expect(result).toBeUndefined(); }); }); describe('storeAndInstallPluginsIdList', () => { it('should return a list of unique plugin identifiers from both installed and store lists', () => { const result = pluginSelectors.storeAndInstallPluginsIdList(mockState); expect(result).toEqual(['plugin-1', 'plugin-2', 'plugin-3']); }); }); describe('installedPluginManifestList', () => { it('should return a list of manifests for installed plugins', () => { const result = pluginSelectors.installedPluginManifestList(mockState); const expectedManifests = mockState.installedPlugins.map((p) => p.manifest); expect(result).toEqual(expectedManifests); }); }); describe('installedPluginMetaList', () => { it('should return a list of meta information for installed plugins', () => { const result = pluginSelectors.installedPluginMetaList(mockState); const expectedMetaList = mockState.installedPlugins.map((p) => ({ identifier: p.identifier, meta: pluginSelectors.getPluginMetaById(p.identifier)(mockState), type: p.type, ...pluginSelectors.getPluginMetaById(p.identifier)(mockState), })); expect(result).toEqual(expectedMetaList); }); }); describe('installedCustomPluginMetaList', () => { it('should return a list of meta information for installed plugins', () => { const result = pluginSelectors.installedCustomPluginMetaList(mockState); expect(result).toEqual([{ identifier: 'plugin-3', type: 'customPlugin' }]); }); }); });