Files
gods-eye-view/server/providers/inaturalist/speed.test.mjs
T
Yehe LiuandClaude Opus 5.5 14f88b3e08 feat: Wildlife Sightings layer from iNaturalist and Acartia
Recent community wildlife observations, as a new Wildlife group in the
layer panel.

- Server: keyless iNaturalist proxy (v2 observations with only the
  projected fields; undocumented v1 UTFGrid density tiles, decoded on the
  server) sharing one paced queue (burst 4, ~1/s, 60/min, 8,000/day budget,
  up to four in flight), in-memory caches and upstream-only cooldowns;
  Acartia Salish Sea marine-mammal feed rounded to 0.01 degrees with
  comments dropped.
- Layer: grid counts drawn as a soft view-ranked density glow; real sampled
  sightings as taxon badges at their true positions with ambient photo
  thumbnails and labels; obscured records stay privacy cells; a clicked
  sighting stays pinned through camera moves and refreshes.
- Anchored photo card per selection with the single iNaturalist link;
  attribution in the layer row and the Data attribution popover.
- Filters (CONFIRMED, taxa presets) round-trip in share links with token 9.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-05 16:17:12 -05:00

219 lines
6.5 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { createInatClient } from './client.js';
import { installInatProxy, NOW } from './proxy.fixture.mjs';
import { syntheticGrid } from './grid.fixture.mjs';
import { INAT_GRID_DECODE_MEASURE } from './grid.js';
const gridUrl = '/grid?z=2&x=1&y=1&taxa=Aves';
const params = {
scope: 'global',
taxa: 'all',
observedD1: '2026-11-02',
};
const tick = () => new Promise(setImmediate);
const install = (options, hook) => installInatProxy(gridUrl, options, hook);
test('tile cache lasts fifteen minutes, then returns stale before revalidation finishes', async () => {
let at = NOW;
let calls = 0;
let release;
const request = install({
now: () => at,
fetchImpl: () => {
calls += 1;
return calls === 1
? Response.json(syntheticGrid())
: new Promise((resolve) => {
release = resolve;
});
},
});
const first = await request();
at += 899_999;
const freshPromise = request();
await tick();
assert.equal(calls, 1, 'a fresh tile never spends another upstream attempt');
assert.deepEqual((await freshPromise).body, first.body);
at += 1;
const stalePromise = request();
let resolved = false;
void stalePromise.then(() => {
resolved = true;
});
await tick();
try {
assert.equal(
resolved,
true,
'stale cells publish while refresh is pending',
);
const stale = await stalePromise;
assert.equal(stale.body.stale, true);
assert.equal(stale.body.fetchedAt, NOW);
assert.deepEqual(stale.body.cells, first.body.cells);
await request();
assert.equal(calls, 2, 'all stale consumers share one background refresh');
const refreshPromise = request(`${gridUrl}&refresh=wait`);
let refreshed = false;
void refreshPromise.then(() => {
refreshed = true;
});
await tick();
assert.equal(
refreshed,
false,
'a background consumer can await the same refresh',
);
release(Response.json(syntheticGrid()));
const fresh = await refreshPromise;
assert.equal(fresh.body.stale, undefined);
assert.equal(fresh.body.fetchedAt, at);
assert.equal(
calls,
2,
'waiting for fresh cells never duplicates upstream work',
);
release = null;
} finally {
release?.(Response.json(syntheticGrid()));
}
});
test('more than sixteen queued views and thirty local requests never report local rate limiting', async () => {
let release;
let calls = 0;
const request = install({
fetchImpl: async () => {
calls += 1;
if (calls === 1)
await new Promise((resolve) => {
release = resolve;
});
return Response.json(syntheticGrid());
},
});
const pending = Array.from({ length: 40 }, (_, x) =>
request(`/grid?z=6&x=${x}&y=1`),
);
await tick();
release();
const results = await Promise.all(pending);
assert.ok(results.every((result) => result.status === 200));
assert.equal(calls, 40);
});
test('only real upstream 429 or 5xx failures start cooldown', async () => {
for (const bad of [
() => Promise.reject(new Error('network')),
() => Response.json({ malformed: true }),
() => new Response('', { status: 404 }),
]) {
let calls = 0;
const client = createInatClient({
now: () => NOW,
cacheDir: null,
queueOptions: { intervalMs: 0, windowMs: 0 },
warn() {},
fetchImpl: () => {
calls += 1;
return calls === 1
? bad()
: Response.json({ results: [], total_results: 0 });
},
});
await assert.rejects(client.getObservations(params), { status: 502 });
await client.getObservations(params);
assert.equal(
calls,
2,
'a non-cooldown failure must not hold the next attempt',
);
}
});
test('actual upstream cooldown is marked separately from a local budget stop', async () => {
for (const upstream of [429, 503]) {
let calls = 0;
const request = install({
fetchImpl: () => {
calls += 1;
return new Response('', {
status: upstream,
headers: { 'Retry-After': '120' },
});
},
});
const first = await request();
assert.equal(first.headers['X-Upstream-Status'], String(upstream));
assert.equal(first.headers['Retry-After'], '120');
await request();
assert.equal(calls, 1);
}
});
test('upstream Retry-After zero survives the HTTP response and permits an immediate next request', async () => {
for (const upstream of [429, 503]) {
let calls = 0;
const request = install({
fetchImpl: () => {
calls += 1;
return calls === 1
? new Response('', {
status: upstream,
headers: { 'Retry-After': '0' },
})
: Response.json(syntheticGrid());
},
});
const first = await request();
assert.equal(first.headers['X-Upstream-Status'], String(upstream));
assert.equal(first.headers['Retry-After'], '0');
assert.equal((await request()).status, 200);
assert.equal(calls, 2);
}
});
test('a local daily budget stop has a distinct code and no upstream cooldown marker', async (t) => {
const before = process.env.INATURALIST_DAILY_BUDGET;
process.env.INATURALIST_DAILY_BUDGET = '1';
t.after(() => {
if (before === undefined) delete process.env.INATURALIST_DAILY_BUDGET;
else process.env.INATURALIST_DAILY_BUDGET = before;
});
let calls = 0;
const request = install({
fetchImpl: () => {
calls += 1;
return Response.json(syntheticGrid());
},
});
assert.equal((await request()).status, 200);
const stopped = await request('/grid?z=2&x=0&y=1');
assert.equal(stopped.status, 503);
assert.equal(stopped.body.error, 'inaturalist_budget_exhausted');
assert.equal(stopped.headers['X-Upstream-Status'], undefined);
assert.equal((await request()).status, 200, 'cached data remains available');
assert.equal(calls, 1);
});
test('cached tiles avoid UTFGrid decode and decode timing entries stay bounded', async () => {
const request = install({
fetchImpl: () => Response.json(syntheticGrid()),
});
await request();
const sample = performance.getEntriesByName(INAT_GRID_DECODE_MEASURE)[0];
assert.ok(sample.duration >= 0);
for (let i = 0; i < 10; i += 1) await request();
assert.equal(
performance.getEntriesByName(INAT_GRID_DECODE_MEASURE)[0],
sample,
);
for (let x = 0; x < 4; x += 1) await request(`/grid?z=3&x=${x}&y=1`);
assert.equal(
performance.getEntriesByName(INAT_GRID_DECODE_MEASURE).length,
1,
);
});