-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBatchGetDocumentsTool.test.ts
More file actions
147 lines (122 loc) · 4.71 KB
/
BatchGetDocumentsTool.test.ts
File metadata and controls
147 lines (122 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { BatchGetDocumentsTool } from '../../../src/tools/batch-get-documents-tool/BatchGetDocumentsTool.js';
import { docCache } from '../../../src/utils/docCache.js';
beforeEach(() => {
docCache.clear();
});
function makeResponse(body: string, status = 200): Response {
return new Response(body, {
status,
headers: {
'content-type': 'text/plain',
'content-length': String(Buffer.byteLength(body, 'utf8'))
}
});
}
describe('BatchGetDocumentsTool', () => {
describe('intra-batch URL deduplication', () => {
it('issues only one HTTP request for multiple URLs with the same normalized key', async () => {
const httpRequest = vi
.fn()
.mockResolvedValue(makeResponse('page content'));
const tool = new BatchGetDocumentsTool({ httpRequest });
const urls = [
'https://docs.mapbox.com/page?bust=1',
'https://docs.mapbox.com/page?bust=2',
'https://docs.mapbox.com/page?bust=3'
];
const result = await tool.run({ urls });
expect(httpRequest).toHaveBeenCalledTimes(1);
expect(result.isError).toBe(false);
const output = JSON.parse((result.content[0] as { text: string }).text);
expect(output).toHaveLength(3);
expect(
output.every((r: { content: string }) => r.content === 'page content')
).toBe(true);
});
it('issues one request per distinct normalized URL', async () => {
const httpRequest = vi
.fn()
.mockResolvedValueOnce(makeResponse('page A'))
.mockResolvedValueOnce(makeResponse('page B'));
const tool = new BatchGetDocumentsTool({ httpRequest });
const urls = [
'https://docs.mapbox.com/a?x=1',
'https://docs.mapbox.com/a?x=2',
'https://docs.mapbox.com/b?x=1'
];
const result = await tool.run({ urls });
expect(httpRequest).toHaveBeenCalledTimes(2);
expect(result.isError).toBe(false);
const output = JSON.parse((result.content[0] as { text: string }).text);
expect(output[0].content).toBe('page A');
expect(output[1].content).toBe('page A');
expect(output[2].content).toBe('page B');
});
it('uses cached content and skips fetch for already-cached normalized URL', async () => {
docCache.set('https://docs.mapbox.com/page', 'cached content');
const httpRequest = vi.fn();
const tool = new BatchGetDocumentsTool({ httpRequest });
const result = await tool.run({
urls: [
'https://docs.mapbox.com/page?bust=1',
'https://docs.mapbox.com/page?bust=2'
]
});
expect(httpRequest).not.toHaveBeenCalled();
const output = JSON.parse((result.content[0] as { text: string }).text);
expect(
output.every((r: { content: string }) => r.content === 'cached content')
).toBe(true);
});
});
describe('response body size limit', () => {
it('returns an error for a URL whose Content-Length exceeds the limit', async () => {
const oversizeHeaders = new Headers({
'content-type': 'text/plain',
'content-length': String(3 * 1024 * 1024) // 3 MB > 2 MB limit
});
const httpRequest = vi
.fn()
.mockResolvedValue(
new Response('x', { status: 200, headers: oversizeHeaders })
);
const tool = new BatchGetDocumentsTool({ httpRequest });
const result = await tool.run({
urls: ['https://docs.mapbox.com/page']
});
expect(result.isError).toBe(false); // batch doesn't fail entirely
const output = JSON.parse((result.content[0] as { text: string }).text);
expect(output[0].error).toMatch(/too large/i);
});
});
describe('invalid URLs', () => {
it('rejects non-mapbox URLs', async () => {
const httpRequest = vi.fn();
const tool = new BatchGetDocumentsTool({ httpRequest });
const result = await tool.run({
urls: ['https://evil.com/page']
});
expect(result.isError).toBe(true);
expect(httpRequest).not.toHaveBeenCalled();
});
});
describe('HTTP errors', () => {
it('returns per-URL error on non-ok response', async () => {
const httpRequest = vi
.fn()
.mockResolvedValue(
new Response('Not Found', { status: 404, statusText: 'Not Found' })
);
const tool = new BatchGetDocumentsTool({ httpRequest });
const result = await tool.run({
urls: ['https://docs.mapbox.com/missing']
});
expect(result.isError).toBe(false);
const output = JSON.parse((result.content[0] as { text: string }).text);
expect(output[0].error).toBe('404 Not Found');
});
});
});