mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
- No pointer cursor over coverage lines (no other layer has one); a click test replaces the hover tests. - No legend: one source, one colour. - The on-globe credit lives in index.js; credits.js is gone. - Billboard glyphs are SVG data URLs with the same geometry, so tests need no canvas stub. - The tile cache keeps the 120 most recently used tiles, same 24 h TTL, instead of a byte budget; listTileLayers was test-only. - providers/mapillary/ is flattened into the layer and its policy merged into one policy.js; the source's method list is a literal in the catalog. - One fakeCesiumViewer for the layer tests. - The fixture gate keeps the steps the unit tests do not cover: coverage and credit, a rejected key, line -> cone -> photo, close, a keyless page. Co-Authored-By: Claude Fable 5.1 <[email protected]>
115 lines
3.9 KiB
JavaScript
115 lines
3.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
answerMapillaryRequest,
|
|
describeCall,
|
|
PHOTO_SEQUENCE_ID,
|
|
photoImages,
|
|
THUMB_HOST,
|
|
} from '../../scripts/fixtures/street-level/mapillaryGraph.mjs';
|
|
import { redact } from '../../scripts/qa-browserEvidence.mjs';
|
|
|
|
const graph = (path, params) =>
|
|
`https://graph.mapillary.com/${path}?${new URLSearchParams({ access_token: 'MLY|0|qa-fixture', ...params })}`;
|
|
const answer = (url, method = 'GET') => {
|
|
const out = answerMapillaryRequest({ method, url });
|
|
return {
|
|
...out,
|
|
json: out.contentType === 'application/json' ? JSON.parse(out.body) : null,
|
|
};
|
|
};
|
|
|
|
test('the Graph fixtures answer every call MapillaryJS makes to open a photo', () => {
|
|
const [first, second] = photoImages();
|
|
const spatial = answer(
|
|
graph('images', {
|
|
image_ids: `${first.id},${second.id}`,
|
|
fields:
|
|
'id,computed_geometry,geometry,sequence,camera_type,computed_rotation,thumb_1024_url,thumb_2048_url,width,height,merge_cc,sfm_cluster,mesh,creator,captured_at',
|
|
}),
|
|
);
|
|
assert.equal(spatial.status, 200);
|
|
assert.equal(spatial.headers['Access-Control-Allow-Origin'], '*');
|
|
const [pano, flat] = spatial.json.data;
|
|
assert.equal(pano.camera_type, 'spherical');
|
|
assert.equal(flat.camera_type, 'perspective');
|
|
assert.equal(pano.merge_cc, null, 'unmerged: no mesh request');
|
|
assert.equal(pano.sfm_cluster, null, 'no cluster request');
|
|
assert.equal(pano.computed_rotation.length, 3);
|
|
assert.equal(new URL(pano.thumb_2048_url).hostname, THUMB_HOST);
|
|
assert.equal(
|
|
answer(graph('images', { s2: '9749618446378729472', fields: 'id' })).json
|
|
.data.length,
|
|
0,
|
|
);
|
|
assert.deepEqual(
|
|
answer(graph('image_ids', { sequence_id: PHOTO_SEQUENCE_ID })).json.data[0],
|
|
{ id: first.id },
|
|
);
|
|
assert.deepEqual(
|
|
answer(graph(`${first.id}/tiles`, { z: '11', fields: 'url,z,x,y' })).json,
|
|
{ data: [] },
|
|
);
|
|
const photo = answer(pano.thumb_2048_url);
|
|
assert.equal(photo.status, 200);
|
|
assert.equal(photo.contentType, 'image/jpeg');
|
|
assert.deepEqual([...photo.body.subarray(0, 3)], [0xff, 0xd8, 0xff]);
|
|
const preflight = answer(graph('images', { image_ids: first.id }), 'OPTIONS');
|
|
assert.equal(preflight.status, 204);
|
|
assert.match(
|
|
preflight.headers['Access-Control-Allow-Headers'],
|
|
/Authorization/,
|
|
);
|
|
});
|
|
|
|
test('a Mapillary call no fixture covers is answered but flagged unknown', () => {
|
|
for (const url of [
|
|
graph('images', { bbox: '0,0,1,1' }),
|
|
graph('map_features', { fields: 'id' }),
|
|
'https://tiles.mapillary.com/maps/vtp/mly1_public/2/14/1/1',
|
|
]) {
|
|
const out = answer(url);
|
|
assert.equal(out.known, false, url);
|
|
assert.ok(out.status >= 400);
|
|
}
|
|
});
|
|
|
|
test('answered calls are named without the token', () => {
|
|
const call = describeCall(
|
|
'GET',
|
|
new URL(graph('9100000000000/tiles', { z: '11', fields: 'url' })),
|
|
);
|
|
assert.equal(call, 'GET graph.mapillary.com/{imageId}/tiles?fields&z');
|
|
assert.doesNotMatch(call, /MLY|access_token/);
|
|
assert.equal(
|
|
describeCall(
|
|
'GET',
|
|
new URL('https://qa-fixture.mapillary.com/thumb/9100000000016.jpg'),
|
|
),
|
|
'GET qa-fixture.mapillary.com/thumb/{imageId}.jpg',
|
|
);
|
|
});
|
|
|
|
test('evidence never carries a Mapillary token', () => {
|
|
assert.equal(
|
|
redact(
|
|
'GET https://graph.mapillary.com/images?access_token=MLY|123|abc&fields=id',
|
|
),
|
|
'GET https://graph.mapillary.com/images?access_token=REDACTED&fields=id',
|
|
);
|
|
assert.equal(
|
|
redact('token MLY|123|abc in a log'),
|
|
'token MLY|REDACTED in a log',
|
|
);
|
|
assert.equal(
|
|
redact(
|
|
'https://tile.googleapis.com/v1/3dtiles/x.glb?session=s1&key=AIzaSyBexampleexampleexampleexample00',
|
|
),
|
|
'https://tile.googleapis.com/v1/3dtiles/x.glb?session=s1&key=REDACTED',
|
|
);
|
|
assert.equal(
|
|
redact('loaded with AIzaSyBexampleexampleexampleexample00 inline'),
|
|
'loaded with AIza…REDACTED inline',
|
|
);
|
|
});
|