@kernel.chat/kbot 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,363 @@
1
+ // kbot Fetch Tool Tests — Mocked (no real network calls)
2
+ import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
3
+ import { executeTool, getTool } from './index.js';
4
+ import { registerFetchTools } from './fetch.js';
5
+ // Register once
6
+ registerFetchTools();
7
+ // ─────────────────────────────────────────────────────────────────────
8
+ // Mock global fetch
9
+ // ─────────────────────────────────────────────────────────────────────
10
+ const originalFetch = globalThis.fetch;
11
+ beforeAll(() => {
12
+ globalThis.fetch = vi.fn();
13
+ });
14
+ afterAll(() => {
15
+ globalThis.fetch = originalFetch;
16
+ });
17
+ function mockFetch(impl) {
18
+ ;
19
+ globalThis.fetch.mockImplementation(impl);
20
+ }
21
+ // ─────────────────────────────────────────────────────────────────────
22
+ // 1. Registration
23
+ // ─────────────────────────────────────────────────────────────────────
24
+ describe('Fetch Tool Registration', () => {
25
+ it('registers url_fetch', () => {
26
+ const tool = getTool('url_fetch');
27
+ expect(tool).toBeTruthy();
28
+ expect(tool.tier).toBe('free');
29
+ expect(tool.parameters.url.required).toBe(true);
30
+ });
31
+ });
32
+ // ─────────────────────────────────────────────────────────────────────
33
+ // 2. URL validation
34
+ // ─────────────────────────────────────────────────────────────────────
35
+ describe('url_fetch — URL Validation', () => {
36
+ it('rejects invalid URLs', async () => {
37
+ const result = await executeTool({
38
+ id: 'f-1',
39
+ name: 'url_fetch',
40
+ arguments: { url: 'not-a-url' },
41
+ });
42
+ expect(result.result).toContain('Error');
43
+ expect(result.result).toContain('Invalid URL');
44
+ });
45
+ it('rejects ftp protocol', async () => {
46
+ const result = await executeTool({
47
+ id: 'f-2',
48
+ name: 'url_fetch',
49
+ arguments: { url: 'ftp://example.com/file.txt' },
50
+ });
51
+ expect(result.result).toContain('Error');
52
+ expect(result.result).toContain('http/https');
53
+ });
54
+ it('rejects file:// protocol', async () => {
55
+ const result = await executeTool({
56
+ id: 'f-3',
57
+ name: 'url_fetch',
58
+ arguments: { url: 'file:///etc/passwd' },
59
+ });
60
+ expect(result.result).toContain('Error');
61
+ expect(result.result).toContain('http/https');
62
+ });
63
+ });
64
+ // ─────────────────────────────────────────────────────────────────────
65
+ // 3. SSRF protection — blocked hosts
66
+ // ─────────────────────────────────────────────────────────────────────
67
+ describe('url_fetch — SSRF Protection', () => {
68
+ it('blocks localhost', async () => {
69
+ const result = await executeTool({
70
+ id: 'ssrf-1',
71
+ name: 'url_fetch',
72
+ arguments: { url: 'http://localhost:8080/secret' },
73
+ });
74
+ expect(result.result).toContain('Blocked host');
75
+ });
76
+ it('blocks 127.0.0.1', async () => {
77
+ const result = await executeTool({
78
+ id: 'ssrf-2',
79
+ name: 'url_fetch',
80
+ arguments: { url: 'http://127.0.0.1/admin' },
81
+ });
82
+ expect(result.result).toContain('Blocked host');
83
+ });
84
+ it('blocks 10.x.x.x private range', async () => {
85
+ const result = await executeTool({
86
+ id: 'ssrf-3',
87
+ name: 'url_fetch',
88
+ arguments: { url: 'http://10.0.0.1/internal' },
89
+ });
90
+ expect(result.result).toContain('Blocked host');
91
+ });
92
+ it('blocks 172.16-31.x.x private range', async () => {
93
+ const result = await executeTool({
94
+ id: 'ssrf-4',
95
+ name: 'url_fetch',
96
+ arguments: { url: 'http://172.16.0.1/internal' },
97
+ });
98
+ expect(result.result).toContain('Blocked host');
99
+ });
100
+ it('blocks 192.168.x.x private range', async () => {
101
+ const result = await executeTool({
102
+ id: 'ssrf-5',
103
+ name: 'url_fetch',
104
+ arguments: { url: 'http://192.168.1.1/router' },
105
+ });
106
+ expect(result.result).toContain('Blocked host');
107
+ });
108
+ it('blocks 0.0.0.0', async () => {
109
+ const result = await executeTool({
110
+ id: 'ssrf-6',
111
+ name: 'url_fetch',
112
+ arguments: { url: 'http://0.0.0.0/' },
113
+ });
114
+ expect(result.result).toContain('Blocked host');
115
+ });
116
+ it('blocks ::1 (IPv6 localhost)', async () => {
117
+ // Note: URL parsing wraps IPv6 in brackets, but the hostname property strips them.
118
+ // The isBlockedHost regex matches '::1' directly.
119
+ // However, some Node.js versions may return the brackets in hostname.
120
+ // We test that the fetch is blocked or errors — either way, no content is returned.
121
+ const result = await executeTool({
122
+ id: 'ssrf-7',
123
+ name: 'url_fetch',
124
+ arguments: { url: 'http://[::1]/secret' },
125
+ });
126
+ expect(result.result).toContain('Error');
127
+ });
128
+ it('blocks .local domains', async () => {
129
+ const result = await executeTool({
130
+ id: 'ssrf-8',
131
+ name: 'url_fetch',
132
+ arguments: { url: 'http://myserver.local/api' },
133
+ });
134
+ expect(result.result).toContain('Blocked host');
135
+ });
136
+ it('blocks link-local 169.254.x.x', async () => {
137
+ const result = await executeTool({
138
+ id: 'ssrf-9',
139
+ name: 'url_fetch',
140
+ arguments: { url: 'http://169.254.169.254/latest/meta-data/' },
141
+ });
142
+ expect(result.result).toContain('Blocked host');
143
+ });
144
+ it('allows public domains', async () => {
145
+ mockFetch(async () => new Response('OK', { status: 200 }));
146
+ const result = await executeTool({
147
+ id: 'ssrf-10',
148
+ name: 'url_fetch',
149
+ arguments: { url: 'https://example.com' },
150
+ });
151
+ // Should not be blocked
152
+ expect(result.result).not.toContain('Blocked host');
153
+ });
154
+ });
155
+ // ─────────────────────────────────────────────────────────────────────
156
+ // 4. Successful fetches
157
+ // ─────────────────────────────────────────────────────────────────────
158
+ describe('url_fetch — Success Cases', () => {
159
+ it('fetches plain text content', async () => {
160
+ mockFetch(async () => new Response('Hello, World!', {
161
+ status: 200,
162
+ headers: { 'content-type': 'text/plain' },
163
+ }));
164
+ const result = await executeTool({
165
+ id: 'ok-1',
166
+ name: 'url_fetch',
167
+ arguments: { url: 'https://example.com/text' },
168
+ });
169
+ expect(result.error).toBeUndefined();
170
+ expect(result.result).toBe('Hello, World!');
171
+ });
172
+ it('fetches JSON content as-is', async () => {
173
+ const jsonContent = JSON.stringify({ key: 'value', num: 42 });
174
+ mockFetch(async () => new Response(jsonContent, {
175
+ status: 200,
176
+ headers: { 'content-type': 'application/json' },
177
+ }));
178
+ const result = await executeTool({
179
+ id: 'ok-2',
180
+ name: 'url_fetch',
181
+ arguments: { url: 'https://api.example.com/data' },
182
+ });
183
+ expect(result.error).toBeUndefined();
184
+ expect(result.result).toBe(jsonContent);
185
+ });
186
+ it('strips HTML tags from HTML content', async () => {
187
+ const html = '<html><head><title>Test</title></head><body><p>Hello <strong>World</strong></p></body></html>';
188
+ mockFetch(async () => new Response(html, {
189
+ status: 200,
190
+ headers: { 'content-type': 'text/html; charset=utf-8' },
191
+ }));
192
+ const result = await executeTool({
193
+ id: 'ok-3',
194
+ name: 'url_fetch',
195
+ arguments: { url: 'https://example.com/page' },
196
+ });
197
+ expect(result.error).toBeUndefined();
198
+ expect(result.result).toContain('Hello');
199
+ expect(result.result).toContain('World');
200
+ expect(result.result).not.toContain('<p>');
201
+ expect(result.result).not.toContain('<strong>');
202
+ });
203
+ it('removes script and style blocks from HTML', async () => {
204
+ const html = '<html><script>alert("xss")</script><style>body{color:red}</style><body>Clean text</body></html>';
205
+ mockFetch(async () => new Response(html, {
206
+ status: 200,
207
+ headers: { 'content-type': 'text/html' },
208
+ }));
209
+ const result = await executeTool({
210
+ id: 'ok-4',
211
+ name: 'url_fetch',
212
+ arguments: { url: 'https://example.com/xss' },
213
+ });
214
+ expect(result.error).toBeUndefined();
215
+ expect(result.result).toContain('Clean text');
216
+ expect(result.result).not.toContain('alert');
217
+ expect(result.result).not.toContain('color:red');
218
+ });
219
+ it('decodes HTML entities', async () => {
220
+ const html = '<p>&amp; &lt; &gt; &quot; &#39; &nbsp;</p>';
221
+ mockFetch(async () => new Response(html, {
222
+ status: 200,
223
+ headers: { 'content-type': 'text/html' },
224
+ }));
225
+ const result = await executeTool({
226
+ id: 'ok-5',
227
+ name: 'url_fetch',
228
+ arguments: { url: 'https://example.com/entities' },
229
+ });
230
+ expect(result.error).toBeUndefined();
231
+ expect(result.result).toContain('&');
232
+ expect(result.result).toContain('<');
233
+ expect(result.result).toContain('>');
234
+ expect(result.result).toContain('"');
235
+ expect(result.result).toContain("'");
236
+ });
237
+ it('returns "(empty response)" for empty body', async () => {
238
+ mockFetch(async () => new Response('', {
239
+ status: 200,
240
+ headers: { 'content-type': 'text/plain' },
241
+ }));
242
+ const result = await executeTool({
243
+ id: 'ok-6',
244
+ name: 'url_fetch',
245
+ arguments: { url: 'https://example.com/empty' },
246
+ });
247
+ expect(result.error).toBeUndefined();
248
+ expect(result.result).toBe('(empty response)');
249
+ });
250
+ });
251
+ // ─────────────────────────────────────────────────────────────────────
252
+ // 5. Truncation
253
+ // ─────────────────────────────────────────────────────────────────────
254
+ describe('url_fetch — Truncation', () => {
255
+ it('truncates long content at default 20000 chars', async () => {
256
+ const longContent = 'x'.repeat(30000);
257
+ mockFetch(async () => new Response(longContent, {
258
+ status: 200,
259
+ headers: { 'content-type': 'text/plain' },
260
+ }));
261
+ const result = await executeTool({
262
+ id: 'tr-1',
263
+ name: 'url_fetch',
264
+ arguments: { url: 'https://example.com/long' },
265
+ });
266
+ expect(result.error).toBeUndefined();
267
+ expect(result.result.length).toBeLessThan(30000);
268
+ expect(result.result).toContain('truncated');
269
+ });
270
+ it('respects custom max_length', async () => {
271
+ const content = 'abcdefghij'.repeat(100); // 1000 chars
272
+ mockFetch(async () => new Response(content, {
273
+ status: 200,
274
+ headers: { 'content-type': 'text/plain' },
275
+ }));
276
+ const result = await executeTool({
277
+ id: 'tr-2',
278
+ name: 'url_fetch',
279
+ arguments: { url: 'https://example.com/custom-len', max_length: 200 },
280
+ });
281
+ expect(result.error).toBeUndefined();
282
+ expect(result.result).toContain('truncated');
283
+ // Should be around 200 chars + truncation message
284
+ expect(result.result.length).toBeLessThan(500);
285
+ });
286
+ it('does not truncate short content', async () => {
287
+ mockFetch(async () => new Response('short', {
288
+ status: 200,
289
+ headers: { 'content-type': 'text/plain' },
290
+ }));
291
+ const result = await executeTool({
292
+ id: 'tr-3',
293
+ name: 'url_fetch',
294
+ arguments: { url: 'https://example.com/short' },
295
+ });
296
+ expect(result.error).toBeUndefined();
297
+ expect(result.result).toBe('short');
298
+ expect(result.result).not.toContain('truncated');
299
+ });
300
+ });
301
+ // ─────────────────────────────────────────────────────────────────────
302
+ // 6. Error handling
303
+ // ─────────────────────────────────────────────────────────────────────
304
+ describe('url_fetch — Error Handling', () => {
305
+ it('returns HTTP error for 404', async () => {
306
+ mockFetch(async () => new Response('Not Found', { status: 404, statusText: 'Not Found' }));
307
+ const result = await executeTool({
308
+ id: 'err-1',
309
+ name: 'url_fetch',
310
+ arguments: { url: 'https://example.com/404' },
311
+ });
312
+ expect(result.result).toContain('Error');
313
+ expect(result.result).toContain('404');
314
+ });
315
+ it('returns HTTP error for 500', async () => {
316
+ mockFetch(async () => new Response('Internal Server Error', { status: 500, statusText: 'Internal Server Error' }));
317
+ const result = await executeTool({
318
+ id: 'err-2',
319
+ name: 'url_fetch',
320
+ arguments: { url: 'https://example.com/500' },
321
+ });
322
+ expect(result.result).toContain('Error');
323
+ expect(result.result).toContain('500');
324
+ });
325
+ it('handles network errors', async () => {
326
+ mockFetch(async () => {
327
+ throw new Error('getaddrinfo ENOTFOUND example.invalid');
328
+ });
329
+ const result = await executeTool({
330
+ id: 'err-3',
331
+ name: 'url_fetch',
332
+ arguments: { url: 'https://example.invalid/page' },
333
+ });
334
+ expect(result.result).toContain('Error');
335
+ expect(result.result).toContain('ENOTFOUND');
336
+ });
337
+ it('handles timeout (AbortError)', async () => {
338
+ mockFetch(async () => {
339
+ const err = new Error('The operation was aborted');
340
+ err.name = 'AbortError';
341
+ throw err;
342
+ });
343
+ const result = await executeTool({
344
+ id: 'err-4',
345
+ name: 'url_fetch',
346
+ arguments: { url: 'https://slow.example.com/' },
347
+ });
348
+ expect(result.result).toContain('timed out');
349
+ });
350
+ it('handles non-Error thrown values', async () => {
351
+ mockFetch(async () => {
352
+ throw 'string error';
353
+ });
354
+ const result = await executeTool({
355
+ id: 'err-5',
356
+ name: 'url_fetch',
357
+ arguments: { url: 'https://example.com/weird-error' },
358
+ });
359
+ expect(result.result).toContain('Error');
360
+ expect(result.result).toContain('string error');
361
+ });
362
+ });
363
+ //# sourceMappingURL=fetch.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.test.js","sourceRoot":"","sources":["../../src/tools/fetch.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=files.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.test.d.ts","sourceRoot":"","sources":["../../src/tools/files.test.ts"],"names":[],"mappings":""}