mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-28 15:42:55 +00:00
* fix: push again, user select option button and form input radio content overflow (#5601) * fix: push again, user select option button and form input radio content overflow * fix: use useCallback instead of useMemo, fix unnecessary delete * fix: Move the variable inside the component * fix: do not pass valueLabel to MySelect * ui * del collection api adapt * refactor: inherit permission (#5529) * refactor: permission update conflict check function * refactor(permission): app collaborator update api * refactor(permission): support app update collaborator * feat: support fe permission conflict check * refactor(permission): app permission * refactor(permission): dataset permission * refactor(permission): team permission * chore: fe adjust * fix: type error * fix: audit pagiation * fix: tc * chore: initv4130 * fix: app/dataset auth logic * chore: move code * refactor(permission): remove selfPermission * fix: mock * fix: test * fix: app & dataset auth * fix: inherit * test(inheritPermission): test syncChildrenPermission * prompt editor add list plugin (#5620) * perf: search result (#5608) * fix: table size (#5598) * temp: list value * backspace * optimize code --------- Co-authored-by: Archer <545436317@qq.com> Co-authored-by: 伍闲犬 <whoeverimf5@gmail.com> * fix: fe & member list (#5619) * chore: initv4130 * fix: MemberItemCard * fix: MemberItemCard * chore: fe adjust & init script * perf: test code * doc * fix debug variables (#5617) * perf: search result (#5608) * fix: table size (#5598) * fix debug variables * fix --------- Co-authored-by: Archer <545436317@qq.com> Co-authored-by: 伍闲犬 <whoeverimf5@gmail.com> * perf: member ui * fix: inherit bug (#5624) * refactor(permission): remove getClbsWithInfo, which is useless * fix: app list privateApp * fix: get infos * perf(fe): remove delete icon when it is disable in MemberItemCard * fix: dataset private dataset * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Archer <545436317@qq.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * perf: auto coupon * chore: upgrade script & get infos avatar (#5625) * fix: get infos * chore: initv4130 * feat: support WecomRobot publish, and fix AesKey can not save bug (#5526) * feat: resolve conflicts * fix: add param 'show_publish_wecom' * feat: abstract out WecomCrypto type * doc: wecom robot document * fix: solve instability in AI output * doc: update some pictures * feat: remove functions from request.ts to chat.ts and toolCall.ts * doc: wecom robot doc update * fix * delete unused code * doc: update version and prompt * feat: remove wecom crypto, delete wecom code in workflow * feat: delete unused codes --------- Co-authored-by: heheer <zhiyu44@qq.com> * remove test * rename init shell * feat: collection page store * reload sandbox * pysandbox * remove log * chore: remove useless code (#5629) * chore: remove useless code * fix: checkConflict * perf: support hidden type for RoleList * fix: copy node * update doc * fix(permission): some bug (#5632) * fix: app/dataset list * fix: inherit bug * perf: del app;i18n;save chat * fix: test * i18n * fix: sumper overflow return OwnerRoleVal (#5633) * remove invalid code * fix: scroll * fix: objectId * update next * update package * object id * mock redis * feat: add redis append to resolve wecom stream response (#5643) * feat: resolve conflicts * fix: add param 'show_publish_wecom' * feat: abstract out WecomCrypto type * doc: wecom robot document * fix: solve instability in AI output * doc: update some pictures * feat: remove functions from request.ts to chat.ts and toolCall.ts * doc: wecom robot doc update * fix * delete unused code * doc: update version and prompt * feat: remove wecom crypto, delete wecom code in workflow * feat: delete unused codes * feat: add redis append method --------- Co-authored-by: heheer <zhiyu44@qq.com> * cache per * fix(test): init team sub when creating mocked user (#5646) * fix: button is not vertically centered (#5647) * doc * fix: gridFs objectId (#5649) --------- Co-authored-by: Zeng Qingwen <143274079+fishwww-ww@users.noreply.github.com> Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com> Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: 伍闲犬 <whoeverimf5@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: heheer <zhiyu44@qq.com>
205 lines
4.8 KiB
TypeScript
205 lines
4.8 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import {
|
|
pluginNodes2InputSchema,
|
|
workflow2InputSchema,
|
|
getMcpServerTools
|
|
} from '@/service/support/mcp/utils';
|
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
|
import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema';
|
|
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
|
import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth';
|
|
import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller';
|
|
|
|
vi.mock('@fastgpt/service/support/mcp/schema', () => ({
|
|
MongoMcpKey: {
|
|
findOne: vi.fn().mockReturnValue({
|
|
lean: vi.fn()
|
|
})
|
|
}
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/core/app/schema', () => ({
|
|
MongoApp: {
|
|
find: vi.fn().mockReturnValue({
|
|
lean: vi.fn()
|
|
})
|
|
}
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/support/permission/app/auth', () => ({
|
|
authAppByTmbId: vi.fn()
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/core/app/version/controller', () => ({
|
|
getAppLatestVersion: vi.fn()
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/support/permission/auth/team', () => ({
|
|
getUserChatInfoAndAuthTeamPoints: vi.fn(),
|
|
getRunningUserInfoByTmbId: vi.fn()
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/core/workflow/dispatch', () => ({
|
|
dispatchWorkFlow: vi.fn()
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/core/chat/saveChat', () => ({
|
|
saveChat: vi.fn()
|
|
}));
|
|
|
|
vi.mock('@fastgpt/service/support/wallet/usage/controller', () => ({
|
|
createChatUsage: vi.fn()
|
|
}));
|
|
|
|
describe('pluginNodes2InputSchema', () => {
|
|
it('should generate input schema from plugin nodes', () => {
|
|
const nodes = [
|
|
{
|
|
flowNodeType: FlowNodeTypeEnum.pluginInput,
|
|
inputs: [
|
|
{
|
|
key: 'testKey',
|
|
valueType: 'string',
|
|
description: 'test description',
|
|
required: true,
|
|
enum: 'a\nb\nc'
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
const schema = pluginNodes2InputSchema(nodes);
|
|
|
|
expect(schema).toEqual({
|
|
type: 'object',
|
|
properties: {
|
|
testKey: {
|
|
type: 'string',
|
|
description: 'test description',
|
|
enum: ['a', 'b', 'c']
|
|
}
|
|
},
|
|
required: ['testKey']
|
|
});
|
|
});
|
|
|
|
it('should handle empty plugin input nodes', () => {
|
|
const nodes = [
|
|
{
|
|
flowNodeType: FlowNodeTypeEnum.pluginInput,
|
|
inputs: []
|
|
}
|
|
];
|
|
|
|
const schema = pluginNodes2InputSchema(nodes);
|
|
|
|
expect(schema).toEqual({
|
|
type: 'object',
|
|
properties: {},
|
|
required: []
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('workflow2InputSchema', () => {
|
|
it('should generate input schema with file config', () => {
|
|
const chatConfig = {
|
|
fileSelectConfig: {
|
|
canSelectFile: true,
|
|
canSelectImg: true
|
|
},
|
|
variables: [
|
|
{
|
|
key: 'var1',
|
|
valueType: 'string',
|
|
description: 'test var',
|
|
required: true,
|
|
enums: [{ value: 'a' }, { value: 'b' }]
|
|
}
|
|
]
|
|
};
|
|
|
|
const schema = workflow2InputSchema(chatConfig);
|
|
|
|
expect(schema).toEqual({
|
|
type: 'object',
|
|
properties: {
|
|
question: {
|
|
type: 'string',
|
|
description: 'Question from user'
|
|
},
|
|
fileUrlList: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string'
|
|
},
|
|
description: 'File linkage'
|
|
},
|
|
var1: {
|
|
type: 'string',
|
|
description: 'test var',
|
|
enum: ['a', 'b']
|
|
}
|
|
},
|
|
required: ['question', 'var1']
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getMcpServerTools', () => {
|
|
it('should return tools list', async () => {
|
|
const mockMcp = {
|
|
tmbId: 'test-tmb',
|
|
apps: [
|
|
{
|
|
appId: 'test-app',
|
|
toolName: 'test-tool',
|
|
description: 'test description'
|
|
}
|
|
]
|
|
};
|
|
|
|
vi.mocked(MongoMcpKey.findOne).mockReturnValue({
|
|
lean: () => mockMcp
|
|
});
|
|
|
|
vi.mocked(MongoApp.find).mockReturnValue({
|
|
lean: () => [
|
|
{
|
|
_id: 'test-app',
|
|
name: 'Test App',
|
|
type: AppTypeEnum.plugin
|
|
}
|
|
]
|
|
});
|
|
|
|
vi.mocked(authAppByTmbId).mockResolvedValue(undefined);
|
|
|
|
vi.mocked(getAppLatestVersion).mockResolvedValue({
|
|
nodes: [
|
|
{
|
|
flowNodeType: FlowNodeTypeEnum.pluginInput,
|
|
inputs: []
|
|
}
|
|
],
|
|
edges: [],
|
|
chatConfig: {}
|
|
});
|
|
|
|
const tools = await getMcpServerTools('test-key');
|
|
|
|
expect(tools).toHaveLength(1);
|
|
expect(tools[0].name).toBe('test-tool');
|
|
});
|
|
|
|
it('should reject if key not found', async () => {
|
|
vi.mocked(MongoMcpKey.findOne).mockReturnValue({
|
|
lean: () => null
|
|
});
|
|
|
|
await expect(getMcpServerTools('invalid-key')).rejects.toBe(CommonErrEnum.invalidResource);
|
|
});
|
|
});
|