fix(street-level): harden the Mapillary tile proxy

From gekh's review of #768, each with a test that fails before:

- The routes refuse cross-site requests (sameSiteGated, as the paid
  proxies do) and the tile route has a generous per-IP limit (600/min), so
  another page cannot burn the token's quota or trip the shared 429 hold.
- At most six upstream fetches run at once; a queued request that is
  abandoned never fetches, nor does one abandoned during the disk read.
- A body past the 48 MB cap aborts the upstream request as it streams.
- Empty tiles are charged against the memory and disk budgets.
- Each disk write uses its own temp file and a retrim is skipped while a
  write of that tile is pending, so concurrent hits cannot extend a tile's
  life or fail a rename.
- Upstream refusals other than 401/403/429 answer 502.
- The tile route's success path is tested end to end (200 with the image
  layer stripped and the right headers, 204 when empty, an abandoned
  response aborts upstream); the teardown race that made this file flaky
  is gone (240 parallel runs, no failure); the QA-constant tautologies are
  replaced by a check against the real provider registry; the boundary
  group lists the modules the provider actually imports.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-10-05 18:35:44 +01:00
1 parent 5f98b871e8
commit d70f468781
8 files changed
+709 -94

No files matched your search

+10 -20
View File
@@ -1,34 +1,24 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import test from 'node:test';
import { createApplicationStreetLevel } from '../app/layers/streetLevel.js';
import {
fixtureTile,
EXPECTED_PROVIDERS,
isCollapsed,
RAIL_ORDER,
VIEWPORTS,
} from '../../scripts/qa-street-level.mjs';
test('the QA harness exercises both review viewports', () => {
assert.deepEqual(
VIEWPORTS.map((v) => `${v.width}x${v.height}`),
['1440x900', '1280x800'],
);
test('the harness expects exactly the providers the app registers, in chip order', () => {
// Any method a provider asks its source for is a no-op: only ids matter.
const source = new Proxy({}, { get: () => () => {} });
const layer = createApplicationStreetLevel({
surface: null,
sources: { mapillary: source },
});
assert.deepEqual([...EXPECTED_PROVIDERS], [...layer.providerIds]);
});
test('the harness expects exactly the registered providers', () => {
assert.deepEqual(EXPECTED_PROVIDERS, ['mapillary']);
});
test('rail order puts Street Level between CCTV and Context', () => {
assert.deepEqual(RAIL_ORDER, [
'pp-toggles',
'cctv-panel',
'weather-panel',
'recent-imagery-panel',
'street-level-panel',
'global-context-panel',
]);
test('a panel reads as collapsed only with the collapsed class', () => {
assert.equal(isCollapsed(['panel-collapsible', 'collapsed']), true);
assert.equal(isCollapsed(['panel-collapsible']), false);
});