Add unit tests for toolList API functions and update the export statements in toolList.ts. (#4623)

Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com>
This commit is contained in:
gru-agent[bot]
2025-04-22 15:26:05 +08:00
committed by GitHub
parent 2dd5cf6d1f
commit 27614e9e8b
2 changed files with 210 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
import { describe, it, expect, vi } from 'vitest';
import {
pluginNodes2InputSchema,
workflow2InputSchema,
handler
} from '@/pages/api/support/mcp/server/toolList';
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 { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller';
import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth';
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
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/core/app/version/controller', () => ({
getAppLatestVersion: vi.fn()
}));
vi.mock('@fastgpt/service/support/permission/app/auth', () => ({
authAppByTmbId: vi.fn()
}));
describe('toolList', () => {
describe('pluginNodes2InputSchema', () => {
it('should generate input schema for plugin nodes', () => {
const nodes = [
{
flowNodeType: FlowNodeTypeEnum.pluginInput,
inputs: [
{
key: 'test',
valueType: 'string',
description: 'test desc',
required: true
}
]
}
];
const schema = pluginNodes2InputSchema(nodes);
expect(schema).toEqual({
type: 'object',
properties: {
test: {
type: 'string',
description: 'test desc'
}
},
required: ['test']
});
});
});
describe('workflow2InputSchema', () => {
it('should generate input schema with file config', () => {
const chatConfig = {
fileSelectConfig: {
canSelectFile: true
},
variables: []
};
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'
}
},
required: ['question']
});
});
it('should generate input schema with variables', () => {
const chatConfig = {
variables: [
{
key: 'var1',
valueType: 'string',
description: 'test var',
required: true
}
]
};
const schema = workflow2InputSchema(chatConfig);
expect(schema).toEqual({
type: 'object',
properties: {
question: {
type: 'string',
description: 'Question from user'
},
var1: {
type: 'string',
description: 'test var'
}
},
required: ['question', 'var1']
});
});
});
describe('handler', () => {
it('should return tools list', async () => {
const mockMcp = {
tmbId: 'test-tmb',
apps: [
{
appId: 'app1',
toolName: 'tool1',
toolAlias: 'alias1',
description: 'desc1'
}
]
};
const mockApp = {
_id: 'app1',
name: 'app1'
};
const mockVersion = {
nodes: [],
chatConfig: {}
};
vi.mocked(MongoMcpKey.findOne).mockReturnValue({
lean: () => Promise.resolve(mockMcp)
});
vi.mocked(MongoApp.find).mockReturnValue({
lean: () => Promise.resolve([mockApp])
});
vi.mocked(authAppByTmbId).mockResolvedValue(undefined);
vi.mocked(getAppLatestVersion).mockResolvedValue(mockVersion);
const result = await handler(
{
query: { key: 'test-key' },
body: {}
},
{} as any
);
expect(result).toEqual([
{
name: 'alias1',
description: 'desc1',
inputSchema: {
type: 'object',
properties: {
question: {
type: 'string',
description: 'Question from user'
}
},
required: ['question']
}
}
]);
});
it('should throw error if mcp key not found', async () => {
vi.mocked(MongoMcpKey.findOne).mockReturnValue({
lean: () => Promise.resolve(null)
});
await expect(
handler(
{
query: { key: 'invalid-key' },
body: {}
},
{} as any
)
).rejects.toBe(CommonErrEnum.invalidResource);
});
});
});