mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Picks up the terrain partial-heights work (#1456). No conflicts; it changes no voice prompt or tool description.
150 lines
6.8 KiB
JavaScript
150 lines
6.8 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createApplicationRequestServices } from './requests.js';
|
|
|
|
test('independent compatible endpoints receive normalized requests without changing global fetch', async () => {
|
|
const requests = [];
|
|
const original = globalThis.fetch;
|
|
const services = createApplicationRequestServices({
|
|
endpoints: { regional: '/custom/region', terrain: '/custom/floors', summary: '/custom/summary' },
|
|
fetchImpl: async (url, init) => {
|
|
requests.push({ url, init });
|
|
return Response.json({ results: [{ ellipsoid: 10 }], summary: 'fixture' });
|
|
},
|
|
});
|
|
await services.regional.getBrief(30, -97);
|
|
assert.match(requests[0].url, /^\/custom\/region\?latitude=30.00000&longitude=-97.00000$/);
|
|
assert.deepEqual(await services.terrain.getHeights([{ lat: 30, lon: -97 }]), [{ ellipsoid: 10 }]);
|
|
const result = await services.summary.summarize({ place: 'fixture' });
|
|
assert.equal(result.data.summary, 'fixture');
|
|
assert.equal(requests[2].init.body, '{"place":"fixture"}');
|
|
assert.equal(requests[2].init.redirect, 'error');
|
|
assert.equal(globalThis.fetch, original);
|
|
});
|
|
|
|
test('lifetime cancellation discards a late response body even from an uncooperative transport', async () => {
|
|
const lifetime = new AbortController();
|
|
let finish;
|
|
const services = createApplicationRequestServices({ signal: lifetime.signal,
|
|
fetchImpl: async () => ({ ok: true, status: 200, json: () => new Promise(resolve => { finish = resolve; }) }),
|
|
});
|
|
const pending = services.weather.getConditions(30, -97);
|
|
while (!finish) await Promise.resolve();
|
|
lifetime.abort();
|
|
finish({ weather: { temperatureC: 10 } });
|
|
await assert.rejects(pending, { name: 'AbortError' });
|
|
await assert.rejects(services.regional.getBrief(30, -97), { name: 'AbortError' });
|
|
});
|
|
|
|
test('boundary throttle status survives empty or invalid error bodies', async () => {
|
|
for (const status of [429, 503]) {
|
|
const services = createApplicationRequestServices({ fetchImpl: async () => new Response('unavailable', { status, headers: { 'Retry-After': '5' } }) });
|
|
assert.deepEqual(await services.boundaries.query('fixture'), { rateLimited: true, retryAfterMs: 5000 });
|
|
}
|
|
});
|
|
|
|
/** A transport whose status probe behaves as told; queries answer with no elements. */
|
|
function probeTransport(status) {
|
|
const seen = [];
|
|
const fetchImpl = (url, init = {}) => {
|
|
seen.push(`${init.method || 'GET'} ${url}`);
|
|
if (!String(url).endsWith('/status')) return Promise.resolve(Response.json({ elements: [] }));
|
|
return status(init);
|
|
};
|
|
return { seen, fetchImpl };
|
|
}
|
|
const stalled = (init) => new Promise((_, reject) => init.signal.addEventListener('abort', () => reject(init.signal.reason)));
|
|
const stalledWithReferencedWait = (init) =>
|
|
new Promise((_, reject) => {
|
|
// AbortSignal.timeout() is intentionally unref'd in Node. Keep this one
|
|
// timeout test alive until the signal fires so an isolated test process
|
|
// cannot exit with a still-pending assertion.
|
|
const keepAlive = setTimeout(() => {}, 1000);
|
|
init.signal.addEventListener(
|
|
'abort',
|
|
() => {
|
|
clearTimeout(keepAlive);
|
|
reject(init.signal.reason);
|
|
},
|
|
{ once: true },
|
|
);
|
|
});
|
|
|
|
test('a stalled capability probe times out and queries proceed; no re-probe during backoff', async () => {
|
|
const { seen, fetchImpl } = probeTransport(stalledWithReferencedWait);
|
|
const services = createApplicationRequestServices({ fetchImpl, boundaryProbe: { timeoutMs: 20, retryMs: 60_000 } });
|
|
const started = Date.now();
|
|
assert.deepEqual(await services.boundaries.query('fixture'), []);
|
|
assert.ok(Date.now() - started < 1000);
|
|
assert.deepEqual(await services.boundaries.query('fixture'), []);
|
|
assert.deepEqual(seen, ['GET /api/overpass/status', 'POST /api/overpass', 'POST /api/overpass']);
|
|
});
|
|
|
|
test('a caller cancelled while the probe is pending stops waiting at once', async () => {
|
|
const { seen, fetchImpl } = probeTransport(stalled);
|
|
const services = createApplicationRequestServices({ fetchImpl, boundaryProbe: { timeoutMs: 60_000, retryMs: 60_000 } });
|
|
const caller = new AbortController();
|
|
const pending = services.boundaries.query('fixture', { signal: caller.signal });
|
|
setTimeout(() => caller.abort(), 10);
|
|
await assert.rejects(pending, { name: 'AbortError' });
|
|
assert.deepEqual(seen, ['GET /api/overpass/status']);
|
|
});
|
|
|
|
test('a failed probe is retried after its backoff, not on every query', async () => {
|
|
let failures = 1;
|
|
const { seen, fetchImpl } = probeTransport(async () => {
|
|
if (failures-- > 0) throw new TypeError('network');
|
|
return Response.json({ configured: false });
|
|
});
|
|
const services = createApplicationRequestServices({ fetchImpl, boundaryProbe: { timeoutMs: 1000, retryMs: 30 } });
|
|
assert.deepEqual(await services.boundaries.query('fixture'), []);
|
|
assert.deepEqual(await services.boundaries.query('fixture'), []);
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
assert.equal((await services.boundaries.query('fixture')).code, 'OVERPASS_NOT_CONFIGURED');
|
|
assert.equal((await services.boundaries.query('fixture')).code, 'OVERPASS_NOT_CONFIGURED');
|
|
assert.deepEqual(seen, [
|
|
'GET /api/overpass/status',
|
|
'POST /api/overpass',
|
|
'POST /api/overpass',
|
|
'GET /api/overpass/status',
|
|
]);
|
|
});
|
|
|
|
test('a failed terrain request carries the real heights the server had', async () => {
|
|
const partial = [{ ellipsoid: 412.5 }, null];
|
|
const services = createApplicationRequestServices({
|
|
fetchImpl: async () => Response.json({ error: 'x', partial }, { status: 502 }),
|
|
});
|
|
const points = [{ lat: 30, lon: -97 }, { lat: 31, lon: -97 }];
|
|
await assert.rejects(services.terrain.getHeights(points), (error) => {
|
|
assert.match(error.message, /Terrain heights unavailable \(502\)/);
|
|
assert.deepEqual(error.partial, partial);
|
|
return true;
|
|
});
|
|
await assert.rejects(services.terrain.getHeights(points.slice(0, 1)), (error) => {
|
|
assert.equal(error.partial, undefined, 'a list of the wrong length is not attached');
|
|
return true;
|
|
});
|
|
});
|
|
|
|
test('the summary capability probe is asked once and unknown when unanswered', async () => {
|
|
for (const [answer, expected] of [
|
|
[() => Response.json({ configured: false }), false],
|
|
[() => Response.json({ configured: true }), true],
|
|
[() => new Response('missing', { status: 404 }), null],
|
|
[() => Response.json({ configured: 'yes' }), null],
|
|
[() => { throw new TypeError('offline'); }, null],
|
|
]) {
|
|
const seen = [];
|
|
const services = createApplicationRequestServices({
|
|
fetchImpl: async (url, init) => {
|
|
seen.push(`${init.method || 'GET'} ${url}`);
|
|
return answer();
|
|
},
|
|
});
|
|
assert.equal(await services.summary.configured(), expected);
|
|
assert.equal(await services.summary.configured(), expected);
|
|
assert.deepEqual(seen, ['GET /api/openai/hud-summary/status']);
|
|
}
|
|
});
|