Files
gods-eye-view/src/layers/cctv/testing.js
T
Sameh Khamis 479286a6a6 CCTV opens on the camera nearest the viewer, not the first in the catalog
Turning CCTV on picked the first catalog record, so at King's Cross it
showed a Sydney camera. enable() now picks the camera nearest the viewer.
Until someone chooses a camera, each settled move re-picks the nearest,
so a share link whose flight lands after CCTV turned on still opens
nearby.
2026-11-07 03:52:38 -08:00

130 lines
4.3 KiB
JavaScript

import * as Cesium from 'cesium';
export function createTesting({ state: layerState, services, parts, source }) {
/** Test seam: republishes host entries through the real push path, so tests
* can observe the pristine module default without touching the setter. */
function _pushAmbientCardEntriesForTest() {
parts.cards.pushAmbientCardEntries();
}
/** Test seam for exercising real layer lifecycle paths without a DOM host. */
function _setCctvOverlayHostForTest(host = null) {
layerState._cctvOverlayHost = host
? { ...layerState.DEFAULT_CCTV_OVERLAY_HOST, ...host }
: layerState.DEFAULT_CCTV_OVERLAY_HOST;
layerState._projectionOverlayOwnerId = null;
}
/**
* Create the production monitor-plane/host-label pair without media setup.
* @param {Object} viewer Cesium viewer seam.
* @param {Object} record CCTV runtime record.
* @returns {Object} Projection runtime.
*/
function _createCctvProjectionPlaneForTest(viewer, record) {
layerState._viewer = viewer;
const geometry =
record.frustumGeometry ||
parts.geometry.computeFrustumGeometry(
record.camera,
parts.ground.groundAltFor(record),
record.probeClampRangeM,
);
const positions =
record.frustumPositions || parts.geometry.frustumCartesians(geometry);
record.frustumGeometry = geometry;
record.frustumPositions = positions;
const runtime = {
cameraId: String(record.camera.id),
planeEntity: null,
labelPosition: new Cesium.Cartesian3(),
overlayEntry: null,
planeMaterial: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE),
};
parts.projection.createProjectionPlane(
record,
runtime,
geometry,
positions,
);
record.projection = runtime;
return runtime;
}
/**
* Exercise the production geometry-to-plane-and-label cache update.
* @param {Object} record CCTV runtime record.
*/
function _updateCctvProjectionPlaneForTest(record) {
parts.projection.updatePlanePlacement(record);
}
/** Test-only seam for the CCTV ownership proof used by the world-click route. */
function _extractPickedCameraIdForTest(picked) {
return parts.selection.extractPickedCameraId(picked);
}
/**
* Primes the minimum module state needed to exercise the production coverage
* refresh path in unit tests.
* @param {Object} [options={}] Test state values.
* @param {Object|null} [options.viewer] Viewer-like entity owner.
* @param {Object[]} [options.records] Seeded CCTV records.
* @param {string|null} [options.activeCameraId] Active record id.
* @param {boolean} [options.enabled=true] Layer enabled state.
* @param {'off'|'on'|'viewshed'} [options.coverageMode='on'] Coverage mode.
* @param {boolean} [options.showProjection=false] Projection visibility.
* @param {Map<string, Object>} [options.healthById] Health rows by camera id.
* @returns {void}
*/
function _setCctvCoverageStateForTest({
viewer = null,
records = [],
activeCameraId = null,
enabled = true,
coverageMode = 'on',
showProjection = false,
healthById = new Map(),
openingCameraProvisional = false,
} = {}) {
layerState._viewer = viewer;
layerState._records = Array.isArray(records) ? records : [];
layerState._recordById = new Map(
layerState._records
.filter((record) => record?.camera?.id)
.map((record) => [record.camera.id, record]),
);
layerState._coverageEntities = [];
layerState._projectionEntities = [];
layerState._billboards = null;
layerState._activeCameraId = activeCameraId;
layerState._autoHopSuspended = false;
layerState._openingCameraProvisional = !!openingCameraProvisional;
layerState._enabled = !!enabled;
layerState._coverageMode = parts.model.normalizeCoverageMode(
coverageMode,
'on',
);
layerState._showProjection = !!showProjection;
layerState._healthById = healthById;
layerState._viewRecords = [];
layerState._cameraIndexCache = null;
layerState._coverageVisibleIds = new Set();
layerState._neighborCountCache = null;
}
return {
_pushAmbientCardEntriesForTest,
_setCctvOverlayHostForTest,
_createCctvProjectionPlaneForTest,
_updateCctvProjectionPlaneForTest,
_extractPickedCameraIdForTest,
_setCctvCoverageStateForTest,
};
}