mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
fix(voice): refuse direct cctv toggles outside the shared lifecycle
This commit is contained in:
1 parent
b920d5f404
commit
b48fcc42ae
4 files changed
+21
-10
No files matched your search
@@ -1,3 +1,2 @@
|
||||
- Report actual outcomes when voice enables or disables CCTV through the shared
|
||||
layer lifecycle, including failed and cancelled changes (manjunath22466,
|
||||
#1205).
|
||||
layer lifecycle, including failed and cancelled changes (Manjunath, #1205).
|
||||
@@ -628,8 +628,9 @@ Voice action argument schemas have one portable owner under `src/voice/actionSch
|
||||
layer visibility lifecycle. Results distinguish successful changes from
|
||||
manager-reported failures or cancellation and report enabled state and lifecycle
|
||||
uncertainty. A caller-supplied abort signal reaches the manager; a late abort
|
||||
preserves an already committed change. Missing-layer errors, other CCTV actions
|
||||
and the exported `controlCctv` helper retain their existing behavior.
|
||||
preserves an already committed change. Missing-layer errors and other CCTV
|
||||
actions retain their existing behavior. The exported `controlCctv` helper refuses direct
|
||||
enable/disable requests and directs callers to `set_layer_visibility`.
|
||||
|
||||
`src/voice/layerManifest.js` declares each catalog layer's voice capabilities: spoken aliases, `toggle`, in-view `context`, `track`, and analyst `query` fields with type and unit, or `noQuery` with the reason. The `set_layer_visibility`, `show_data_layers_menu`, `get_entity_context` and `analyst_query` layer enums, the runner's alias table and the analyst field hints are generated from it. `src/voice/layerManifest.test.mjs` fails when a catalog layer is neither listed nor named in `VOICE_OFF_LAYERS` (today only the two scene-driven Bhote Koshi layers). Global Context is listed with `toggle: false`; `set_context_mode` reaches it. `set_panel_open` also opens `weather-panel` and `recent-imagery-panel`.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { after, before, test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { DataLayerManager } from '../data/manager.js';
|
||||
import { CCTV_FOCUS_RESULT } from '../layers/cctv/index.js';
|
||||
import { createGevActionRunner } from './gevActions.js';
|
||||
import { controlCctv, createGevActionRunner } from './gevActions.js';
|
||||
|
||||
const originalWindow = globalThis.window;
|
||||
before(() => {
|
||||
@@ -294,6 +294,20 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test('exported controlCctv refuses toggles without calling the manager', async () => {
|
||||
const manager = {
|
||||
layers: new Map([['cctv', { module: {} }]]),
|
||||
setEnabled: () => assert.fail('direct helper must not change visibility'),
|
||||
isEnabled: () => assert.fail('direct toggle must not read enabled state'),
|
||||
};
|
||||
for (const action of ['ENABLE', 'disable']) {
|
||||
const result = await controlCctv(manager, { action });
|
||||
assert.equal(result.ok, false);
|
||||
assert.equal(result.action, 'control_cctv');
|
||||
assert.match(result.error, /set_layer_visibility/);
|
||||
}
|
||||
});
|
||||
|
||||
test(
|
||||
'CCTV fallback managers report rejection, transitional state, and uncertainty',
|
||||
{ timeout: 2000 },
|
||||
|
||||
@@ -1444,13 +1444,10 @@ export async function controlCctv(dataManager, args = {}, styleManager = null) {
|
||||
}
|
||||
|
||||
if (action === 'enable' || action === 'disable') {
|
||||
await dataManager.setEnabled('cctv', action === 'enable', {
|
||||
origin: 'voice',
|
||||
});
|
||||
return {
|
||||
ok: true,
|
||||
ok: false,
|
||||
action: 'control_cctv',
|
||||
enabled: dataManager.isEnabled('cctv'),
|
||||
error: 'Enable or disable CCTV through set_layer_visibility',
|
||||
};
|
||||
}
|
||||
if (!dataManager.isEnabled('cctv')) {
|
||||
|
||||
Reference in new issue
Block a user