Files
gods-eye-view/src/ui/imageryBoxTool.test.mjs
T
Bilawal Sidhuandmanjunath22466 082074a006 feat(layers): Recent Imagery — open satellite imagery for a selected box (#716)
Select a box on the world and browse the last 30 days of open satellite imagery over it, keyless: NASA GIBS Harmonized Landsat Sentinel-2 (30 m) and the VIIRS daily overview (250 m), with a day strip, IMAGE / VS BASEMAP / A / B modes with a swipe divider, PNG export and share links. The before/after swipe from the Nepal scene moves into shared modules so both use it.

Co-authored-by: manjunath22466 <[email protected]>
2026-09-22 20:34:11 -05:00

155 lines
5.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
claimPointer,
pointerOwner,
releasePointer,
resetPointerOwnership,
} from '../data/inputOwnership.js';
import {
IMAGERY_BOX_POINTER_OWNER,
initImageryBoxTool,
} from './imageryBoxTool.js';
import { boxToolFakes } from '../layers/recentImagery/testDoubles.mjs';
function fixture(options = {}) {
resetPointerOwnership();
const fakes = boxToolFakes();
const boxes = [];
const cancels = [];
const actives = [];
const tool = initImageryBoxTool({
viewer: fakes.viewer,
cesium: fakes.cesium,
pickWorld: fakes.pickWorld,
documentRef: fakes.documentRef,
onBox: (box) => boxes.push(box),
onCancel: (reason, message) => cancels.push([reason, message]),
onActive: (active) => actives.push(active),
...options,
});
const camera = fakes.viewer.scene.screenSpaceCameraController;
const stockAction = (type) =>
fakes.viewer.screenSpaceEventHandler.getInputAction(fakes.types[type]);
const preview = () =>
fakes.viewer.dataSources.sources[0]?.entities.values.every((e) => e.show);
return {
...fakes,
tool,
boxes,
cancels,
actives,
camera,
stockAction,
preview,
};
}
test('a session claims the pointer, borrows the stock clicks, freezes the camera only mid-drag and returns everything with the box', async () => {
const f = fixture();
assert.equal(f.tool.start(), true);
assert.equal(pointerOwner(), IMAGERY_BOX_POINTER_OWNER);
assert.equal(f.stockAction('LEFT_CLICK'), undefined);
assert.equal(f.stockAction('LEFT_DOUBLE_CLICK'), undefined);
assert.ok(f.documentRef.classes.has('gev-imagery-box'));
assert.equal(f.camera.enableInputs, true, 'not frozen before the press');
f.fire('LEFT_DOWN', { position: { x: 250, y: 125 } });
assert.equal(f.camera.enableInputs, false);
assert.equal(f.preview(), true);
f.fire('MOUSE_MOVE', { endPosition: { x: 500, y: 250 } });
f.fire('MOUSE_MOVE', { endPosition: { x: 500, y: 10 } }); // sky: ignored
f.fire('LEFT_UP', { position: { x: 500, y: 250 } });
assert.equal(f.boxes.length, 1);
const { west, south, east, north } = f.boxes[0];
assert.deepEqual(
[west, south, east, north].map((v) => Math.round(v * 1e6) / 1e6),
[-97.85, 30.3, -97.8, 30.35],
);
assert.deepEqual(f.cancels, []);
assert.equal(f.tool.isActive(), false);
assert.equal(pointerOwner(), null);
assert.equal(f.stockAction('LEFT_CLICK'), f.originalClick);
assert.equal(f.stockAction('LEFT_DOUBLE_CLICK'), f.originalDouble);
assert.equal(f.camera.enableInputs, true);
assert.equal(f.preview(), false);
assert.equal(f.documentRef.classes.has('gev-imagery-box'), false);
assert.equal(f.documentRef.listeners.length, 0);
assert.equal(f.handler(), null);
assert.deepEqual(f.actives, [true, false]);
await f.tool.destroy();
});
test('a sky press, a click without a drag and Escape each say why', async () => {
const f = fixture();
f.tool.start();
f.fire('LEFT_DOWN', { position: { x: 250, y: 10 } });
assert.deepEqual(f.cancels.at(-1), [
'sky',
'Press on the ground, not the sky',
]);
assert.equal(f.tool.isActive(), true, 'a sky press keeps the session');
f.fire('LEFT_DOWN', { position: { x: 250, y: 125 } });
f.fire('LEFT_UP', { position: { x: 250, y: 125 } });
assert.deepEqual(f.cancels.at(-1), ['degenerate', 'Drag to size the box']);
f.tool.start();
assert.equal(f.key('Escape').prevented, true);
assert.deepEqual(f.cancels.at(-1), ['escape', undefined]);
assert.equal(pointerOwner(), null);
await f.tool.destroy();
});
test('an Escape interceptor that claims the key leaves the tool armed; the next Escape cancels', async () => {
let claim = true;
let asked = 0;
const f = fixture({
onEscape: () => {
asked += 1;
return claim;
},
});
f.tool.start();
const first = f.key('Escape');
assert.equal(asked, 1);
assert.equal(
first.prevented && first.stopped,
true,
'the key goes no further',
);
assert.equal(f.tool.isActive(), true);
claim = false;
f.key('Escape');
assert.deepEqual(f.cancels, [['escape', undefined]]);
f.tool.start();
f.key('Enter');
assert.equal(asked, 2, 'other keys never reach the interceptor');
await f.tool.destroy();
});
test('a held pointer refuses the session and nothing is borrowed', async () => {
const f = fixture();
const lease = claimPointer('draw');
assert.equal(f.tool.start(), false);
assert.deepEqual(f.cancels, [
['pointer-busy', 'draw is using the pointer — close it first'],
]);
assert.equal(f.stockAction('LEFT_CLICK'), f.originalClick);
assert.equal(f.handler(), null);
releasePointer(lease);
assert.equal(f.tool.start(), true);
await f.tool.destroy();
});
test('destroy mid-drag restores the camera, releases the claim and detaches the preview', async () => {
const f = fixture();
f.tool.start();
f.fire('LEFT_DOWN', { position: { x: 250, y: 125 } });
assert.equal(f.viewer.dataSources.sources.length, 1);
await f.tool.destroy();
assert.equal(f.camera.enableInputs, true);
assert.equal(pointerOwner(), null);
assert.equal(f.viewer.dataSources.sources.length, 0);
assert.equal(f.stockAction('LEFT_CLICK'), f.originalClick);
assert.equal(f.tool.start(), false);
assert.equal(initImageryBoxTool({ viewer: null, onBox() {} }), null);
});