Files
gods-eye-view/src/layers/streetLevel/params.test.mjs
T
Said TurkseverandClaude Opus 5.5 3af0f80cdb test(street-level): close the mutation survivors; Esc in rich text
A mutation review left 18 earlier survivors; each now has a test that
fails with the mutant applied:

- the expanded viewer returns into the panel on shrink, close and destroy
  (the fake DOM had no parentNode, so reinsertion was never exercised); the
  fake DOM gains offsetParent and a MutationObserver that honours its
  options, and a <body> child added while expanded goes inert;
- each pose moves the marker, drives FOLLOW and selects a new sequence;
  close() retires an open still mounting or opening; a provider toggled
  while the layer is off activates nothing; the adapter drops late and
  superseded poses;
- share-link defaults: "any date" (0 days), the codec max pinned to the
  filter's MAX_SINCE_DAYS (layerState cannot import it across package
  boundaries, so a test ties the two), Mapillary on when a link omits it;
- Esc that something else handled, or typed in a field, keeps the
  selection; a key problem outranks LOADING on the pill;
- the marker's terrain height (mesh, DEM, clamp then re-place);
- proxy: LRU memory cache and its half-budget rule, Retry-After capped,
  a request after a cancelled fetch starts a fresh one;
- date-line tile ranking with and without focus; the horizon cull idles
  while the camera stands still; the old zoom goes as soon as the new one
  lands; a rate limit holds every refresh inside its wait.

One real bug found and fixed: Esc inside a contenteditable cleared the
selected sequence (selection.js now ignores isContentEditable targets).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 16:54:06 +01:00

59 lines
1.9 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { decodeParams, encodeParams } from './params.js';
test('encodeParams writes one boolean per provider plus the filter', () => {
assert.deepEqual(
encodeParams({
providers: [
['mapillary', true],
['panoramax', false],
],
filter: { pano: 'flat', sinceDays: 365 },
}),
{ mapillary: true, panoramax: false, pano: 'flat', sinceDays: 365 },
);
});
test('decodeParams round-trips and ignores unknown or malformed keys', () => {
const current = { pano: 'all', sinceDays: 0 };
const decoded = decodeParams(
{ mapillary: false, kartaview: true, pano: 'pano', sinceDays: 730, x: 1 },
{ providerIds: ['mapillary'], filter: current },
);
assert.deepEqual([...decoded.providers], [['mapillary', false]]);
assert.deepEqual(decoded.filter, { pano: 'pano', sinceDays: 730 });
const partial = decodeParams(
{ mapillary: '1', pano: 'weird' },
{ providerIds: ['mapillary'], filter: { pano: 'flat', sinceDays: 5 } },
);
assert.equal(partial.providers.size, 0, 'a string is not a switch');
assert.deepEqual(partial.filter, { pano: 'flat', sinceDays: 5 });
const empty = decodeParams(null, {
providerIds: ['mapillary'],
filter: current,
});
assert.equal(empty.providers.size, 0);
assert.deepEqual(empty.filter, current);
});
test('decodeParams applies "any date" (0 days) over a current window (share-link defaults)', () => {
const decoded = decodeParams(
{ sinceDays: 0 },
{ providerIds: ['mapillary'], filter: { pano: 'flat', sinceDays: 365 } },
);
assert.deepEqual(decoded.filter, { pano: 'flat', sinceDays: 0 });
// The provider switch off is a value too, not an absence.
assert.deepEqual(
[
...decodeParams(
{ mapillary: false },
{ providerIds: ['mapillary'], filter: { pano: 'all', sinceDays: 0 } },
).providers,
],
[['mapillary', false]],
);
});