Files
gods-eye-view/src/layers/flights/ownership.test.mjs
T
Aditya ac0e124a67 fix(flights): read a 359.6° track as 0° in the voice context, not 360°
The voice context records for a selected flight or military contact
rounded the track without wrapping, so a contact on 359.5° or more was
described to the assistant as heading "360°". Both now wrap after
rounding: 359.6° reads "0°", 359.4° still reads "359°".
2026-10-28 18:11:42 +05:30

149 lines
4.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { createCivilFlightLayer } from './index.js';
import { createFlightState } from './state.js';
import { createEnrichment } from './enrichment.js';
import { createTracking } from './tracking.js';
function services() {
const names = [
'picking',
'sprites',
'trails',
'aircraftPresentation',
'camera',
'militaryRegistry',
'labels',
'groundFloor',
'meshFloor',
'geoid',
'focus',
'readout',
'context',
'render',
'recession',
];
return {
...Object.fromEntries(names.map((name) => [name, {}])),
groundSnap: { createGroundSnap: () => ({ clear() {} }) },
};
}
test('constructing independent flight layers performs no source request and isolates selection', () => {
let requests = 0;
const source = {
label: 'Fixture aircraft',
getSnapshot() {
requests++;
},
};
const first = createCivilFlightLayer({ source, services: services() });
const second = createCivilFlightLayer({ source, services: services() });
first.testing._armFlightTrackingRestoreForTest('abc123');
assert.equal(first.testing._pendingFlightTrackingRestoreForTest(), 'abc123');
assert.equal(second.testing._pendingFlightTrackingRestoreForTest(), null);
first.testing._setFlightTrackingRefreshOutcomeForTest({ ids: ['abc123'] });
assert.notEqual(first.testing, second.testing);
assert.equal(first.getStats().source, 'Fixture aircraft');
assert.equal(requests, 0);
});
test('a layer without a source fails before touching the viewer', () => {
const layer = createCivilFlightLayer({ services: services() });
assert.throws(() => layer.init({}), /snapshot source/);
});
test('flight state owns distinct mutable records, scratch objects and floor samplers', () => {
const first = createFlightState({ services: services() });
const second = createFlightState({ services: services() });
for (const key of [
'records',
'feed',
'_billboards',
'_positionHistory',
'_displayFloorState',
'_groundSnap',
'_scratchCarto',
'_models',
'lifetime',
]) {
assert.notEqual(first[key], second[key], key);
}
assert.notEqual(first.records.data, second.records.data);
assert.notEqual(first.records.missingPolls, second.records.missingPolls);
assert.notEqual(first.records.geoidNCache, second.records.geoidNCache);
assert.notEqual(
first.feed._activeUpdateControllers,
second.feed._activeUpdateControllers,
);
});
test('aborted enrichment cannot write into a later lifecycle or decrement its active count', async () => {
let resolve;
let signal;
const source = {
getEnrichment(query, options) {
signal = options.signal;
return new Promise((done) => {
resolve = done;
});
},
};
const flightState = createFlightState({ source, services: services() });
const enrichment = createEnrichment({ flightState, services: {}, parts: {} });
let writes = 0;
enrichment._enqueueEnrich(
'test',
{ kind: 'type', id: 'abc123' },
() => writes++,
);
await Promise.resolve();
assert.equal(flightState._enrichActive, 1);
flightState.lifetime.abort();
flightState.lifetime = new AbortController();
flightState._enrichActive = 0;
resolve({ found: true });
await new Promise((done) => setImmediate(done));
assert.equal(signal.aborted, true);
assert.equal(writes, 0);
assert.equal(flightState._enrichActive, 0);
});
test('a synchronous enrichment failure stays bounded and releases its slot', async () => {
const flightState = createFlightState({
services: services(),
source: {
getEnrichment() {
throw new Error('fixture failure');
},
},
});
const enrichment = createEnrichment({ flightState, services: {}, parts: {} });
assert.doesNotThrow(() =>
enrichment._enqueueEnrich('test', {}, () => assert.fail()),
);
await new Promise((done) => setImmediate(done));
assert.equal(flightState._enrichActive, 0);
});
test('voice context reads a track that rounds to north as 0°, not 360°', () => {
const tracking = createTracking({
flightState: {
feed: { _lastSource: 'Fixture aircraft' },
records: { data: new Map() },
},
services: services(),
parts: {
queries: {
_describeFlight: () => ({ track: 359.6, altitudeM: 9000 }),
_contactLabel: () => 'AAL1',
},
},
layer: {},
});
assert.equal(
tracking._contextSubjectMetadata('abc123').properties.heading,
'0°',
);
});