Skip to content

Commit 3a8778b

Browse files
Add unit tests for the HTTP tool handler and ensure proper functionality and error handling.
1 parent 89e718f commit 3a8778b

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

projects/app/src/pages/api/core/app/httpTools/runTool.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ async function handler(
5151
}
5252

5353
export default NextAPI(handler);
54+
55+
export { handler };
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { describe, it, expect, beforeEach, vi } from 'vitest';
2+
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
3+
import type {
4+
RunHTTPToolBody,
5+
RunHTTPToolQuery,
6+
RunHTTPToolResponse
7+
} from '@/pages/api/core/app/httpTools/runTool';
8+
import { handler } from '@/pages/api/core/app/httpTools/runTool';
9+
10+
// Mock runHTTPTool
11+
vi.mock('@fastgpt/service/core/app/http', async (importOriginal) => {
12+
const actual = await importOriginal<typeof import('@fastgpt/service/core/app/http')>();
13+
return {
14+
...actual,
15+
runHTTPTool: vi.fn()
16+
};
17+
});
18+
19+
import { runHTTPTool } from '@fastgpt/service/core/app/http';
20+
21+
describe('handler', () => {
22+
const baseUrl = 'https://api.example.com';
23+
const toolPath = '/v1/resource';
24+
const method = 'POST';
25+
const params = { foo: 'bar', baz: 123 };
26+
const customHeaders = { Authorization: 'Bearer token', 'X-Test': 'true' };
27+
const headerSecret = { key: 'secret-key', value: 'secret-value' };
28+
const staticParams = { static1: 'value1', static2: 2 };
29+
const staticHeaders = { 'X-Static': 'static-header' };
30+
const staticBody = { bodyField: 'bodyValue' };
31+
32+
let req: ApiRequestProps<RunHTTPToolBody, RunHTTPToolQuery>;
33+
let res: ApiResponseType<RunHTTPToolResponse>;
34+
35+
beforeEach(() => {
36+
vi.clearAllMocks();
37+
req = {
38+
body: {
39+
params,
40+
baseUrl,
41+
toolPath,
42+
method,
43+
customHeaders,
44+
headerSecret,
45+
staticParams,
46+
staticHeaders,
47+
staticBody
48+
},
49+
query: {}
50+
};
51+
52+
// res is not used in handler, but must be present
53+
res = {} as ApiResponseType<RunHTTPToolResponse>;
54+
});
55+
56+
it('should call runHTTPTool with all provided fields and return its result', async () => {
57+
const expectedResult: RunHTTPToolResponse = {
58+
success: true,
59+
data: { result: 'ok' }
60+
} as RunHTTPToolResponse;
61+
vi.mocked(runHTTPTool).mockResolvedValue(expectedResult);
62+
63+
const result = await handler(req, res);
64+
65+
expect(runHTTPTool).toHaveBeenCalledWith({
66+
baseUrl,
67+
toolPath,
68+
method,
69+
params,
70+
headerSecret,
71+
customHeaders,
72+
staticParams,
73+
staticHeaders,
74+
staticBody
75+
});
76+
expect(result).toBe(expectedResult);
77+
});
78+
79+
it('should default method to POST if not provided', async () => {
80+
req.body.method = undefined as any;
81+
const expectedResult: RunHTTPToolResponse = { success: true, data: {} } as RunHTTPToolResponse;
82+
vi.mocked(runHTTPTool).mockResolvedValue(expectedResult);
83+
84+
await handler(req, res);
85+
86+
expect(runHTTPTool).toHaveBeenCalledWith(
87+
expect.objectContaining({
88+
method: 'POST'
89+
})
90+
);
91+
});
92+
93+
it('should handle missing optional fields', async () => {
94+
req.body.customHeaders = undefined;
95+
req.body.headerSecret = undefined;
96+
req.body.staticParams = undefined;
97+
req.body.staticHeaders = undefined;
98+
req.body.staticBody = undefined;
99+
100+
const expectedResult: RunHTTPToolResponse = { success: true, data: {} } as RunHTTPToolResponse;
101+
vi.mocked(runHTTPTool).mockResolvedValue(expectedResult);
102+
103+
await handler(req, res);
104+
105+
expect(runHTTPTool).toHaveBeenCalledWith({
106+
baseUrl,
107+
toolPath,
108+
method,
109+
params,
110+
headerSecret: undefined,
111+
customHeaders: undefined,
112+
staticParams: undefined,
113+
staticHeaders: undefined,
114+
staticBody: undefined
115+
});
116+
});
117+
118+
it('should pass through all values correctly', async () => {
119+
const expectedResult: RunHTTPToolResponse = {
120+
success: true,
121+
data: { echo: true }
122+
} as RunHTTPToolResponse;
123+
vi.mocked(runHTTPTool).mockResolvedValue(expectedResult);
124+
125+
const result = await handler(req, res);
126+
127+
expect(result).toEqual(expectedResult);
128+
});
129+
130+
it('should propagate errors from runHTTPTool', async () => {
131+
const error = new Error('runHTTPTool failed');
132+
vi.mocked(runHTTPTool).mockRejectedValue(error);
133+
134+
await expect(handler(req, res)).rejects.toThrow('runHTTPTool failed');
135+
});
136+
});

0 commit comments

Comments
 (0)