mirror of
https://github.com/langgenius/dify.git
synced 2026-03-19 21:57:33 +08:00
Signed-off-by: yyh <yuanyouhuilyz@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: statxc <tyleradams93226@gmail.com>
196 lines
6.7 KiB
TypeScript
196 lines
6.7 KiB
TypeScript
import type { TriggerWithProvider } from '../block-selector/types'
|
|
import type { CommonNodeType, ToolWithProvider } from '../types'
|
|
import { CollectionType } from '@/app/components/tools/types'
|
|
import { BlockEnum } from '../types'
|
|
import {
|
|
isNodePluginMissing,
|
|
isPluginDependentNode,
|
|
matchDataSource,
|
|
matchToolInCollection,
|
|
matchTriggerProvider,
|
|
} from './plugin-install-check'
|
|
|
|
const createTool = (overrides: Partial<ToolWithProvider> = {}): ToolWithProvider => ({
|
|
id: 'langgenius/search/search',
|
|
name: 'search',
|
|
plugin_id: 'plugin-search',
|
|
provider: 'search-provider',
|
|
plugin_unique_identifier: 'plugin-search@1.0.0',
|
|
...overrides,
|
|
} as ToolWithProvider)
|
|
|
|
const createTriggerProvider = (overrides: Partial<TriggerWithProvider> = {}): TriggerWithProvider => ({
|
|
id: 'trigger-provider-id',
|
|
name: 'trigger-provider',
|
|
plugin_id: 'trigger-plugin',
|
|
...overrides,
|
|
} as TriggerWithProvider)
|
|
|
|
describe('plugin install check', () => {
|
|
describe('isPluginDependentNode', () => {
|
|
it('should return true for plugin dependent node types', () => {
|
|
expect(isPluginDependentNode(BlockEnum.Tool)).toBe(true)
|
|
expect(isPluginDependentNode(BlockEnum.DataSource)).toBe(true)
|
|
expect(isPluginDependentNode(BlockEnum.TriggerPlugin)).toBe(true)
|
|
})
|
|
|
|
it('should return false for non-plugin node types', () => {
|
|
expect(isPluginDependentNode(BlockEnum.LLM)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('matchToolInCollection', () => {
|
|
const collection = [createTool()]
|
|
|
|
it('should match a tool by plugin id', () => {
|
|
expect(matchToolInCollection(collection, { plugin_id: 'plugin-search' })).toEqual(collection[0])
|
|
})
|
|
|
|
it('should match a tool by legacy provider id', () => {
|
|
expect(matchToolInCollection(collection, { provider_id: 'search' })).toEqual(collection[0])
|
|
})
|
|
|
|
it('should match a tool by provider name', () => {
|
|
expect(matchToolInCollection(collection, { provider_name: 'search' })).toEqual(collection[0])
|
|
})
|
|
|
|
it('should return undefined when no tool matches', () => {
|
|
expect(matchToolInCollection(collection, { plugin_id: 'missing-plugin' })).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('matchTriggerProvider', () => {
|
|
const providers = [createTriggerProvider()]
|
|
|
|
it('should match a trigger provider by name', () => {
|
|
expect(matchTriggerProvider(providers, { provider_name: 'trigger-provider' })).toEqual(providers[0])
|
|
})
|
|
|
|
it('should match a trigger provider by id', () => {
|
|
expect(matchTriggerProvider(providers, { provider_id: 'trigger-provider-id' })).toEqual(providers[0])
|
|
})
|
|
|
|
it('should match a trigger provider by plugin id', () => {
|
|
expect(matchTriggerProvider(providers, { plugin_id: 'trigger-plugin' })).toEqual(providers[0])
|
|
})
|
|
})
|
|
|
|
describe('matchDataSource', () => {
|
|
const dataSources = [createTool({
|
|
provider: 'knowledge-provider',
|
|
plugin_id: 'knowledge-plugin',
|
|
plugin_unique_identifier: 'knowledge-plugin@1.0.0',
|
|
})]
|
|
|
|
it('should match a data source by unique identifier', () => {
|
|
expect(matchDataSource(dataSources, { plugin_unique_identifier: 'knowledge-plugin@1.0.0' })).toEqual(dataSources[0])
|
|
})
|
|
|
|
it('should match a data source by plugin id', () => {
|
|
expect(matchDataSource(dataSources, { plugin_id: 'knowledge-plugin' })).toEqual(dataSources[0])
|
|
})
|
|
|
|
it('should match a data source by provider name', () => {
|
|
expect(matchDataSource(dataSources, { provider_name: 'knowledge-provider' })).toEqual(dataSources[0])
|
|
})
|
|
})
|
|
|
|
describe('isNodePluginMissing', () => {
|
|
it('should report missing tool plugins when the collection is loaded but unmatched', () => {
|
|
const node = {
|
|
type: BlockEnum.Tool,
|
|
title: 'Tool',
|
|
desc: '',
|
|
provider_type: CollectionType.builtIn,
|
|
provider_id: 'missing-provider',
|
|
plugin_unique_identifier: 'missing-plugin@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { builtInTools: [createTool()] })).toBe(true)
|
|
})
|
|
|
|
it('should keep tool nodes installable when the collection has not loaded yet', () => {
|
|
const node = {
|
|
type: BlockEnum.Tool,
|
|
title: 'Tool',
|
|
desc: '',
|
|
provider_type: CollectionType.builtIn,
|
|
provider_id: 'missing-provider',
|
|
plugin_unique_identifier: 'missing-plugin@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { builtInTools: undefined })).toBe(false)
|
|
})
|
|
|
|
it('should ignore unmatched tool nodes without plugin identifiers', () => {
|
|
const node = {
|
|
type: BlockEnum.Tool,
|
|
title: 'Tool',
|
|
desc: '',
|
|
provider_type: CollectionType.builtIn,
|
|
provider_id: 'missing-provider',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { builtInTools: [createTool()] })).toBe(false)
|
|
})
|
|
|
|
it('should report missing trigger plugins when no provider matches', () => {
|
|
const node = {
|
|
type: BlockEnum.TriggerPlugin,
|
|
title: 'Trigger',
|
|
desc: '',
|
|
provider_id: 'missing-trigger',
|
|
plugin_unique_identifier: 'trigger-plugin@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { triggerPlugins: [createTriggerProvider()] })).toBe(true)
|
|
})
|
|
|
|
it('should keep trigger plugin nodes installable when the provider list has not loaded yet', () => {
|
|
const node = {
|
|
type: BlockEnum.TriggerPlugin,
|
|
title: 'Trigger',
|
|
desc: '',
|
|
provider_id: 'missing-trigger',
|
|
plugin_unique_identifier: 'trigger-plugin@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { triggerPlugins: undefined })).toBe(false)
|
|
})
|
|
|
|
it('should report missing data source plugins when the list is loaded but unmatched', () => {
|
|
const node = {
|
|
type: BlockEnum.DataSource,
|
|
title: 'Data Source',
|
|
desc: '',
|
|
provider_name: 'missing-provider',
|
|
plugin_unique_identifier: 'missing-data-source@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { dataSourceList: [createTool()] })).toBe(true)
|
|
})
|
|
|
|
it('should keep data source nodes installable when the list has not loaded yet', () => {
|
|
const node = {
|
|
type: BlockEnum.DataSource,
|
|
title: 'Data Source',
|
|
desc: '',
|
|
provider_name: 'missing-provider',
|
|
plugin_unique_identifier: 'missing-data-source@1.0.0',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, { dataSourceList: undefined })).toBe(false)
|
|
})
|
|
|
|
it('should return false for unsupported node types', () => {
|
|
const node = {
|
|
type: BlockEnum.LLM,
|
|
title: 'LLM',
|
|
desc: '',
|
|
} as CommonNodeType
|
|
|
|
expect(isNodePluginMissing(node, {})).toBe(false)
|
|
})
|
|
})
|
|
})
|