mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
test(street-level): harden KartaView tests (mutation score 51% → 95%)
A mutation review (91, then 130 mutants) found tests that could not fail
(quick presses with synchronous fakes, a no-flight check with a provider
that never posed), and untested paths. New and rewritten tests kill 123 of
130 mutants; the 7 survivors are equivalent or harmless redraws.
- viewer: held-back loads for quick presses, stale sharp/flat loads,
close mid-load, ends checks for an older photo, WebGL retried per mount,
focus handed back, look direction kept on ›.
- provider: id-ordered pages with out-of-order indexes, page and probe
failures retried, overtaken lookups, cones re-centred on ‹ ›, leftover
imagery filters hide no line or cone, coverage hints, tile cache.
- source: 429 backoff and Retry-After under mock timers, hang timeouts,
the nearest query's parameters. policy: storage-host injection, FOV 360,
longitudes past ±180. panorama: a stub WebGL context (angles, lost
context, re-measuring). lineCoverage.test.mjs: tooHigh hint, passes().
- core: openImage({frame:false}) and openNearest leave the camera
(with a posing provider and a default-open control), KartaView's legend
and wording end to end; viewerHost supportsRenderModes.
- Fixed tick-count waits replaced by an until() poll.
- Browser gate fixture: odd photos archived (409 at storage2, served by
the proxy), the first lookup rate-limited (429, Retry-After: 0); the
line-click step asserts the camera stays and › skips the archived photo.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
bd0bbf5134
commit
3d4c6de21a
14 files changed
+1374
-81
No files matched your search
@@ -26,9 +26,13 @@ import {
|
||||
KV_LINE,
|
||||
KV_SEQUENCE_ID,
|
||||
kartaViewPhotos,
|
||||
resetKartaViewFixture,
|
||||
} from '../../scripts/fixtures/street-level/kartaView.mjs';
|
||||
import { lonToTileX, latToTileY } from '../layers/streetLevel/tileMath.js';
|
||||
import { normalizePhoto } from '../layers/streetLevel/providers/kartaview/policy.js';
|
||||
import {
|
||||
normalizePhoto,
|
||||
resizedImageUrl,
|
||||
} from '../layers/streetLevel/providers/kartaview/policy.js';
|
||||
|
||||
// The press helpers wait for paint; Node has no frames, so a tick stands in.
|
||||
globalThis.requestAnimationFrame ??= (callback) =>
|
||||
@@ -665,10 +669,16 @@ test('KartaView fixtures draw the drive, answer nearest first, and refuse the st
|
||||
url: `https://api.kartaview.org/2.0/sequence/tiles/${x + 3}/${y}/14.json`,
|
||||
});
|
||||
assert.deepEqual(body(empty).lines, []);
|
||||
const near = answerKartaViewRequest({
|
||||
method: 'GET',
|
||||
url: `https://api.kartaview.org/2.0/photo/?lat=${lat}&lng=${KV_LINE.lon + 0.0001}&zoomLevel=18&itemsPerPage=10`,
|
||||
});
|
||||
const nearUrl = `https://api.kartaview.org/2.0/photo/?lat=${lat}&lng=${KV_LINE.lon + 0.0001}&zoomLevel=18&itemsPerPage=10`;
|
||||
resetKartaViewFixture();
|
||||
// The first lookup is rate-limited, readable cross-origin; the retry answers.
|
||||
const limited = answerKartaViewRequest({ method: 'GET', url: nearUrl });
|
||||
assert.equal(limited.status, 429);
|
||||
assert.equal(limited.known, true);
|
||||
assert.equal(limited.headers['Retry-After'], '0');
|
||||
assert.match(limited.headers['Access-Control-Expose-Headers'], /Retry-After/);
|
||||
const near = answerKartaViewRequest({ method: 'GET', url: nearUrl });
|
||||
assert.equal(near.status, 200);
|
||||
const records = body(near).result.data;
|
||||
assert.ok(records.length > 1);
|
||||
assert.ok(Number(records[0].distance) <= Number(records[1].distance));
|
||||
@@ -678,6 +688,42 @@ test('KartaView fixtures draw the drive, answer nearest first, and refuse the st
|
||||
answerKartaViewRequest({ method: 'GET', url: photo.urls.view }).known,
|
||||
true,
|
||||
);
|
||||
// Every odd photo is archived: its file answers 409, an even one the image.
|
||||
const photos = kartaViewPhotos();
|
||||
const storageAnswer = (index) =>
|
||||
answerKartaViewRequest({
|
||||
method: 'GET',
|
||||
url: normalizePhoto(
|
||||
body(
|
||||
answerKartaViewRequest({
|
||||
method: 'GET',
|
||||
url: `https://api.kartaview.org/2.0/photo/${photos[index].id}`,
|
||||
}),
|
||||
).result.data,
|
||||
).urls.view,
|
||||
});
|
||||
assert.equal(photos[3].archived, true);
|
||||
assert.equal(storageAnswer(3).status, 409);
|
||||
assert.equal(storageAnswer(3).known, true);
|
||||
assert.equal(photos[4].archived, false);
|
||||
assert.equal(storageAnswer(4).status, 200);
|
||||
assert.equal(storageAnswer(4).contentType, 'image/jpeg');
|
||||
// The image proxy still serves an archived photo: the 360° step opens one.
|
||||
const pano = photos.find((p) => p.isPano);
|
||||
assert.equal(pano.archived, true);
|
||||
const panoRecord = body(
|
||||
answerKartaViewRequest({
|
||||
method: 'GET',
|
||||
url: `https://api.kartaview.org/2.0/photo/${pano.id}`,
|
||||
}),
|
||||
).result.data;
|
||||
assert.equal(
|
||||
answerKartaViewRequest({
|
||||
method: 'GET',
|
||||
url: resizedImageUrl(normalizePhoto(panoRecord).urls.pano, [1024, 512]),
|
||||
}).status,
|
||||
200,
|
||||
);
|
||||
assert.equal(
|
||||
answerKartaViewRequest({ method: 'GET', url: records[0].fileurlLTh }).known,
|
||||
false,
|
||||
|
||||
Reference in new issue
Block a user