mirror of
https://github.com/langgenius/dify.git
synced 2026-11-13 14:51:39 +08:00
218 lines
6.9 KiB
TypeScript
218 lines
6.9 KiB
TypeScript
import type { PluginDeclaration, PluginManifestInMarket } from '../../types'
|
|
import { describe, expect, it } from 'vite-plus/test'
|
|
import { PluginCategoryEnum } from '../../types'
|
|
import {
|
|
convertRepoToUrl,
|
|
parseGitHubUrl,
|
|
pluginDeclarationToCardPluginProps,
|
|
pluginManifestInMarketToPluginProps,
|
|
pluginManifestToCardPluginProps,
|
|
toPluginText,
|
|
} from '../utils'
|
|
|
|
describe('pluginManifestToCardPluginProps', () => {
|
|
const createMockPluginDeclaration = (
|
|
overrides?: Partial<PluginDeclaration>,
|
|
): PluginDeclaration => ({
|
|
plugin_unique_identifier: 'test-plugin-123',
|
|
version: '1.0.0',
|
|
author: 'test-author',
|
|
icon: '/test-icon.png',
|
|
name: 'test-plugin',
|
|
category: PluginCategoryEnum.tool,
|
|
label: { 'en-US': 'Test Plugin' } as Record<string, string>,
|
|
description: { 'en-US': 'Test description' } as Record<string, string>,
|
|
created_at: '2024-01-01',
|
|
resource: {},
|
|
plugins: {},
|
|
verified: true,
|
|
endpoint: { settings: [], endpoints: [] },
|
|
model: {},
|
|
tags: ['search', 'api'],
|
|
agent_strategy: null,
|
|
meta: { version: '1.0.0' },
|
|
trigger: {} as PluginDeclaration['trigger'],
|
|
...overrides,
|
|
})
|
|
|
|
it('converts a package manifest into its card identity and metadata', () => {
|
|
const manifest = createMockPluginDeclaration({
|
|
category: PluginCategoryEnum.model,
|
|
label: {
|
|
...createMockPluginDeclaration().label,
|
|
'en-US': 'My Plugin',
|
|
'zh-Hans': '我的插件',
|
|
},
|
|
icon_dark: '/dark-icon.png',
|
|
})
|
|
expect(pluginManifestToCardPluginProps(manifest)).toEqual({
|
|
plugin_id: 'test-plugin-123',
|
|
type: PluginCategoryEnum.model,
|
|
category: PluginCategoryEnum.model,
|
|
name: 'test-plugin',
|
|
version: '1.0.0',
|
|
org: 'test-author',
|
|
author: 'test-author',
|
|
label: { 'en-US': 'My Plugin', 'zh-Hans': '我的插件' },
|
|
brief: { 'en-US': 'Test description' },
|
|
description: { 'en-US': 'Test description' },
|
|
icon: '/test-icon.png',
|
|
icon_dark: '/dark-icon.png',
|
|
verified: true,
|
|
latest_version: '',
|
|
latest_package_identifier: '',
|
|
introduction: '',
|
|
repository: '',
|
|
install_count: 0,
|
|
endpoint: { settings: [] },
|
|
tags: [{ name: 'search' }, { name: 'api' }],
|
|
badges: [],
|
|
verification: { authorized_category: 'langgenius' },
|
|
from: 'package',
|
|
})
|
|
})
|
|
|
|
it('keeps untagged package manifests untagged', () => {
|
|
expect(pluginManifestToCardPluginProps(createMockPluginDeclaration({ tags: [] })).tags).toEqual(
|
|
[],
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('pluginDeclarationToCardPluginProps', () => {
|
|
const manifest = {
|
|
author: null,
|
|
category: 'agent-strategy',
|
|
created_at: '2026-01-01T00:00:00Z',
|
|
description: { en_US: 'Description', zh_Hans: null },
|
|
icon: 'icon.svg',
|
|
label: { en_US: 'Agent', zh_Hans: '代理' },
|
|
meta: { minimum_dify_version: null, version: '0.0.1' },
|
|
name: 'agent',
|
|
plugins: {},
|
|
resource: { memory: 0 },
|
|
version: '1.0.0',
|
|
} satisfies Parameters<typeof pluginDeclarationToCardPluginProps>[0]
|
|
|
|
it('reads the uploaded package as a card', () => {
|
|
expect(
|
|
pluginDeclarationToCardPluginProps(manifest, 'langgenius/agent:1.0.0@hash'),
|
|
).toMatchObject({
|
|
plugin_id: 'langgenius/agent:1.0.0@hash',
|
|
type: 'agent_strategy',
|
|
category: 'agent-strategy',
|
|
org: '',
|
|
author: undefined,
|
|
label: { en_US: 'Agent', zh_Hans: '代理' },
|
|
description: { en_US: 'Description' },
|
|
verified: false,
|
|
tags: [],
|
|
})
|
|
})
|
|
|
|
it('leaves untranslated locales out of card text', () => {
|
|
expect(toPluginText({ en_US: 'Name', ja_JP: null, pt_BR: 'Nome' })).toEqual({
|
|
en_US: 'Name',
|
|
pt_BR: 'Nome',
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('pluginManifestInMarketToPluginProps', () => {
|
|
const createMockPluginManifestInMarket = (
|
|
overrides?: Partial<PluginManifestInMarket>,
|
|
): PluginManifestInMarket => ({
|
|
plugin_unique_identifier: 'market-plugin-123',
|
|
name: 'market-plugin',
|
|
org: 'market-org',
|
|
icon: '/market-icon.png',
|
|
label: { 'en-US': 'Market Plugin' } as Record<string, string>,
|
|
category: PluginCategoryEnum.tool,
|
|
version: '1.0.0',
|
|
latest_version: '1.2.0',
|
|
brief: { 'en-US': 'Market plugin description' } as Record<string, string>,
|
|
introduction: 'Full introduction text',
|
|
verified: true,
|
|
install_count: 5000,
|
|
badges: ['partner', 'verified'],
|
|
verification: { authorized_category: 'langgenius' },
|
|
from: 'marketplace',
|
|
...overrides,
|
|
})
|
|
|
|
it('uses the latest marketplace version and marketplace metadata for the card', () => {
|
|
const manifest = createMockPluginManifestInMarket({ category: PluginCategoryEnum.model })
|
|
expect(pluginManifestInMarketToPluginProps(manifest)).toEqual({
|
|
plugin_id: 'market-plugin-123',
|
|
type: PluginCategoryEnum.model,
|
|
category: PluginCategoryEnum.model,
|
|
name: 'market-plugin',
|
|
version: '1.2.0',
|
|
latest_version: '1.2.0',
|
|
org: 'market-org',
|
|
label: { 'en-US': 'Market Plugin' },
|
|
brief: { 'en-US': 'Market plugin description' },
|
|
description: { 'en-US': 'Market plugin description' },
|
|
icon: '/market-icon.png',
|
|
verified: true,
|
|
introduction: 'Full introduction text',
|
|
latest_package_identifier: '',
|
|
repository: '',
|
|
install_count: 0,
|
|
tags: [],
|
|
endpoint: { settings: [] },
|
|
badges: ['partner', 'verified'],
|
|
verification: { authorized_category: 'langgenius' },
|
|
from: 'marketplace',
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
[{ authorized_category: 'partner' }, { authorized_category: 'partner' }],
|
|
[{}, { authorized_category: 'langgenius' }],
|
|
])('normalizes marketplace verification %j', (verification, expected) => {
|
|
expect(
|
|
pluginManifestInMarketToPluginProps(
|
|
createMockPluginManifestInMarket({
|
|
verification: verification as PluginManifestInMarket['verification'],
|
|
from: 'github',
|
|
}),
|
|
),
|
|
).toMatchObject({ verification: expected, from: 'github' })
|
|
})
|
|
})
|
|
|
|
describe('parseGitHubUrl', () => {
|
|
it.each([
|
|
['https://github.com/owner/repo', 'owner', 'repo'],
|
|
['https://github.com/owner/repo/', 'owner', 'repo'],
|
|
['https://github.com/my-org/my_repo123', 'my-org', 'my_repo123'],
|
|
])('parses %s', (url, owner, repo) => {
|
|
expect(parseGitHubUrl(url)).toEqual({ isValid: true, owner, repo })
|
|
})
|
|
|
|
it.each([
|
|
'https://gitlab.com/owner/repo',
|
|
'https://github.com/owner/repo/tree/main',
|
|
'https://github.com/owner',
|
|
'',
|
|
'not-a-url',
|
|
'http://github.com/owner/repo',
|
|
'https://www.github.com/owner/repo',
|
|
])('rejects %s', (url) => {
|
|
expect(parseGitHubUrl(url)).toEqual({ isValid: false })
|
|
})
|
|
})
|
|
|
|
describe('convertRepoToUrl', () => {
|
|
it.each([
|
|
[
|
|
'organization_name/repository-name.js',
|
|
'https://github.com/organization_name/repository-name.js',
|
|
],
|
|
['', ''],
|
|
])('converts %s to its repository URL', (repo, expected) => {
|
|
expect(convertRepoToUrl(repo)).toBe(expected)
|
|
})
|
|
})
|