diff --git a/scripts/format-scope.json b/scripts/format-scope.json index a28a8c53c..40bca019a 100644 --- a/scripts/format-scope.json +++ b/scripts/format-scope.json @@ -1128,6 +1128,7 @@ "src/dockerTrustedPeers.test.mjs", "src/cameraGlobeRotation.test.mjs", "src/cameraTilt.test.mjs", + "src/ui/shellFacade.test.mjs", "src/voice/globeResetConfirmation.test.mjs", "src/hudDms.test.mjs", "src/hudSummaryGate.test.mjs", diff --git a/src/ui/shellFacade.js b/src/ui/shellFacade.js index 95bf791d4..678b69c79 100644 --- a/src/ui/shellFacade.js +++ b/src/ui/shellFacade.js @@ -6,7 +6,7 @@ export class ShellFacade { /** Observe camera ownership transfers through the navigation owner. */ subscribeCameraHandoff(listener) { - return this._navigation.subscribeCameraHandoff(listener); + return this._navigation?.subscribeCameraHandoff(listener); } get _models3dEnabled() { diff --git a/src/ui/shellFacade.test.mjs b/src/ui/shellFacade.test.mjs new file mode 100644 index 000000000..abb892b37 --- /dev/null +++ b/src/ui/shellFacade.test.mjs @@ -0,0 +1,33 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { ShellFacade } from './shellFacade.js'; + +// A shell assembled without its navigation owner (as unit tests build one +// from the prototype) has no handoffs to report, like the facade's other +// optional owners; the voice runner subscribes as it is created. +test('camera handoffs without a navigation owner subscribe to nothing', () => { + const shell = Object.create(ShellFacade.prototype); + assert.equal( + shell.subscribeCameraHandoff(() => {}), + undefined, + ); +}); + +test('camera handoffs reach listeners through the navigation owner', () => { + const listeners = new Set(); + const shell = Object.create(ShellFacade.prototype); + shell._navigation = { + subscribeCameraHandoff(listener) { + listeners.add(listener); + return () => listeners.delete(listener); + }, + }; + let handoffs = 0; + const unsubscribe = shell.subscribeCameraHandoff(() => { + handoffs += 1; + }); + for (const listener of listeners) listener(); + assert.equal(handoffs, 1); + unsubscribe(); + assert.equal(listeners.size, 0); +});