import test from 'node:test'; import assert from 'node:assert/strict'; import { fetchWithTimeout, fetchJsonWithTimeout, fetchTextWithTimeout } from '../src/util/fetch.mjs'; import { createOverpassClient } from '../src/sources/overpass.mjs'; function waitingFetch(url, { signal }) { return new Promise((resolve, reject) => { signal.addEventListener('abort', () => reject(signal.reason), { once: true }); }); } test('fetchWithTimeout aborta requisicao que excede o prazo', async () => { await assert.rejects( fetchWithTimeout('https://example.test', { fetch: waitingFetch }, 5), /timeout.*5ms/i ); }); test('fetchWithTimeout combina cancelamento externo sem esperar o timeout', async () => { const controller = new AbortController(); const promise = fetchWithTimeout('https://example.test', { fetch: waitingFetch, signal: controller.signal }, 10_000); controller.abort(new Error('cancelado pelo usuario')); await assert.rejects(promise, /cancelado pelo usuario/i); }); test('fetchJsonWithTimeout mantem timer ate body JSON terminar', async () => { let aborted = false; const fetch = async (url, { signal }) => { signal.addEventListener('abort', () => { aborted = true; }, { once: true }); return new Response(new ReadableStream({ start(controller) { controller.enqueue(Buffer.from('{"ok":')); } })); }; await assert.rejects(fetchJsonWithTimeout('https://example.test', { fetch }, 10), /timeout.*10ms/i); assert.equal(aborted, true); }); test('fetchTextWithTimeout limita bytes do corpo', async () => { await assert.rejects( fetchTextWithTimeout('https://example.test', { fetch: async () => new Response('123456') }, 1000, { maxBytes: 5 }), /limite.*5 bytes/i ); }); test('Overpass mantem timeout proprio durante leitura do corpo', async () => { const originalFetch = globalThis.fetch; globalThis.fetch = async () => new Response(new ReadableStream({ start(controller) { controller.enqueue(Buffer.from('{"elements":')); } })); try { const request = createOverpassClient({ urls: ['https://overpass.test'], timeoutMs: 10 }); await assert.rejects(request('[out:json];'), /timeout/i); } finally { globalThis.fetch = originalFetch; } });