import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { after, before, test } from "node:test"; import React, { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { createServer } from "vite"; let server; let activeStreamForceFinishAuthority; let activeStreamForceFinishAuthorityMatches; let activeStreamRecoveredBrowserAuthority; let activeStreamRecoveryPresentation; let activeStreamRecoveryPresentationAuthority; let activeStreamRecoveryOwnsPresentationDecision; let exactActiveStreamRecoveryLineage; let formatActiveStreamRecoveryElapsed; let suppressGenericErrorDuringActiveStreamRecovery; let isXgridsActiveStreamRecovery; let K1AcquisitionPipeline; let K1SpatialControlsView; let runSpatialActiveStreamForceFinish; let shouldRenderK1GenericRuntimeError; let shouldRenderK1OperationalPanels; let xgridsK1Actions; let xgridsK1Api; const hookSourceUrl = new URL( "../../../plugins/xgrids-k1/frontend/src/useXgridsK1Runtime.ts", import.meta.url, ); const acquisitionSourceUrl = new URL( "../../../plugins/xgrids-k1/frontend/src/components/K1AcquisitionPipeline.tsx", import.meta.url, ); const recoverySurfaceSourceUrl = new URL( "../../../plugins/xgrids-k1/frontend/src/components/ActiveStreamRecoverySurface.tsx", import.meta.url, ); const spatialControlsSourceUrl = new URL( "../../../plugins/xgrids-k1/frontend/src/components/K1SpatialControls.tsx", import.meta.url, ); const connectionSourceUrl = new URL( "../../../plugins/xgrids-k1/frontend/src/XgridsK1Connection.tsx", import.meta.url, ); before(async () => { server = await createServer({ appType: "custom", logLevel: "silent", server: { middlewareMode: true }, }); ({ activeStreamForceFinishAuthority, activeStreamForceFinishAuthorityMatches, activeStreamRecoveredBrowserAuthority, activeStreamRecoveryPresentation, activeStreamRecoveryPresentationAuthority, activeStreamRecoveryOwnsPresentationDecision, exactActiveStreamRecoveryLineage, formatActiveStreamRecoveryElapsed, suppressGenericErrorDuringActiveStreamRecovery, } = await server.ssrLoadModule("@xgrids-k1/frontend/activeStreamRecovery.ts")); ({ isXgridsActiveStreamRecovery, xgridsK1Api } = await server.ssrLoadModule( "@xgrids-k1/frontend/api.ts", )); ({ xgridsK1Actions } = await server.ssrLoadModule( "@xgrids-k1/frontend/manifest.ts", )); ({ K1AcquisitionPipeline } = await server.ssrLoadModule( "@xgrids-k1/frontend/components/K1AcquisitionPipeline.tsx", )); ({ K1SpatialControlsView, runSpatialActiveStreamForceFinish, } = await server.ssrLoadModule( "@xgrids-k1/frontend/components/K1SpatialControls.tsx", )); ({ shouldRenderK1GenericRuntimeError, shouldRenderK1OperationalPanels, } = await server.ssrLoadModule( "@xgrids-k1/frontend/XgridsK1Connection.tsx", )); }); after(async () => { await server?.close(); }); function recoveryContract(overrides = {}) { return { schema_version: "missioncore.xgrids-k1-active-stream-recovery/v1", state: "reconnecting", generation: 7, acquisition_id: "acquisition-recovery-001", attempt: 3, started_at_utc: "2026-08-11T19:31:00Z", elapsed_ms: 12_400, reason_code: "read-only-rebind-in-progress", force_finish_allowed: true, automatic_read_only_rebind: true, automatic_command_retry: false, start_performed: false, stop_performed: false, ble_operation_performed: false, network_mutation_performed: false, runtime_producer_generation: 11, camera_recovery: "owned", camera_media_state: "pending-first-media", camera_media_ready: false, camera_epoch: { generation: 7, init_committed: true, init_committed_age_ms: 250, first_media_committed: false, first_media_committed_age_ms: null, committed_media_segment_count: 0, last_media_segment_age_ms: null, }, ...overrides, }; } function recoveryState(recoveryOverrides = {}, stateOverrides = {}) { return { snapshot_runtime_id: "snapshot-runtime-recovery-001", snapshot_revision: 43, producer_generation: 11, phase: "reconnecting", source_mode: "live", acquisition: { acquisition_id: "acquisition-recovery-001", device_id: "device-k1-001", device_session_id: "device-session-001", compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.local-network.v2", control_mode: "plugin-commanded", requested_streams: ["spatial.point-cloud.live"], target_host: "127.0.0.1", duration_seconds: 0, evidence_policy: "required", state: "acquiring", state_revision: 9, cleanup_pending: false, }, connection_recovery: recoveryContract(recoveryOverrides), ...stateOverrides, }; } function coldRestartPrePclState() { const state = recoveryState({ generation: 1, acquisition_id: "acquisition-before-backend-restart-001", attempt: 0, started_at_utc: "2026-08-14T00:31:00Z", elapsed_ms: 450, reason_code: "restart-receiver-awaiting-first-pcl", runtime_producer_generation: 1, camera_recovery: "inactive", camera_media_state: "inactive", camera_media_ready: false, camera_epoch: null, }, { snapshot_runtime_id: "snapshot-runtime-after-cold-restart-001", snapshot_revision: 2, producer_generation: 1, acquisition: { ...recoveryState().acquisition, acquisition_id: "acquisition-before-backend-restart-001", state: "awaiting_external_start", state_revision: 4, }, camera_preview: { activation_admission: { state: "waiting-for-first-authoritative-pcl", basis: "post-rerun-publish-pcl-frame", runtime_producer_generation: 1, device_command_sent: false, }, }, }); return state; } function coldRestartRecoveredState() { const state = coldRestartPrePclState(); return { ...state, snapshot_revision: state.snapshot_revision + 1, phase: "live", acquisition: { ...state.acquisition, state: "acquiring", state_revision: state.acquisition.state_revision + 1, }, connection_recovery: { ...state.connection_recovery, state: "recovered", elapsed_ms: null, reason_code: null, force_finish_allowed: false, camera_recovery: "owned", camera_media_state: "pending-epoch", camera_media_ready: false, camera_epoch: null, }, camera_preview: { activation_admission: { state: "activating", basis: "post-rerun-publish-pcl-frame", runtime_producer_generation: 1, device_command_sent: false, }, }, }; } function controller(state, overrides = {}) { return { state, pendingAction: null, error: null, physicalStopIntentSpent: false, physicalStopInFlight: false, closeApplicationControlSession: async () => false, prepareCanonicalAcquisition: async () => false, startPreparedAcquisition: async () => false, startReplay: async () => false, stop: async () => false, stopLocalReceiver: async () => false, forceFinishActiveStreamLocally: async () => false, abort: async () => false, ...overrides, }; } function renderPipeline(state, overrides = {}) { return renderToStaticMarkup(createElement(K1AcquisitionPipeline, { controller: controller(state, overrides), desiredConnectionMode: "bridge", openSpatialScene() {}, activateAutomaticSpatialSource() {}, })); } function renderSpatialControls(state, overrides = {}) { return renderToStaticMarkup(createElement(K1SpatialControlsView, { controller: controller(state, overrides), })); } function buttonsWithText(markup, text) { return (markup.match(//g) ?? []) .filter((button) => button.includes(text)); } function sourceSlice(source, startMarker, endMarker) { const start = source.indexOf(startMarker); const end = source.indexOf(endMarker, start + startMarker.length); assert.notEqual(start, -1, `missing source marker: ${startMarker}`); assert.notEqual(end, -1, `missing source marker: ${endMarker}`); return source.slice(start, end); } test("active recovery contract is strict about all no-write invariants", () => { assert.equal(isXgridsActiveStreamRecovery(recoveryContract()), true); for (const field of [ "automatic_command_retry", "start_performed", "stop_performed", "ble_operation_performed", "network_mutation_performed", ]) { assert.equal( isXgridsActiveStreamRecovery(recoveryContract({ [field]: true })), false, field, ); } assert.equal( isXgridsActiveStreamRecovery(recoveryContract({ state: "retrying-command" })), false, ); assert.equal( isXgridsActiveStreamRecovery(recoveryContract({ elapsed_ms: -1 })), false, ); const missingMediaState = recoveryContract(); delete missingMediaState.camera_media_state; assert.equal(isXgridsActiveStreamRecovery(missingMediaState), false); assert.equal( isXgridsActiveStreamRecovery(recoveryContract({ camera_media_ready: true })), false, ); assert.equal( isXgridsActiveStreamRecovery(recoveryContract({ camera_media_state: "ready", camera_media_ready: true, camera_epoch: { ...recoveryContract().camera_epoch, generation: 0, first_media_committed: true, first_media_committed_age_ms: 1, committed_media_segment_count: 1, last_media_segment_age_ms: 1, }, })), false, ); }); test("cold restart before first PCL owns exact reconnect UI without camera or physical actions", () => { const state = coldRestartPrePclState(); assert.equal(isXgridsActiveStreamRecovery(state.connection_recovery), true); const lineage = exactActiveStreamRecoveryLineage(state); assert.deepEqual(lineage && { runtime: lineage.snapshotRuntimeId, acquisition: lineage.acquisitionId, revision: lineage.acquisitionStateRevision, recovery: lineage.recoveryGeneration, producer: lineage.runtimeProducerGeneration, }, { runtime: "snapshot-runtime-after-cold-restart-001", acquisition: "acquisition-before-backend-restart-001", revision: 4, recovery: 1, producer: 1, }); assert.notEqual(activeStreamRecoveryPresentationAuthority(state), null); assert.notEqual(activeStreamForceFinishAuthority(state), null); assert.equal(activeStreamRecoveredBrowserAuthority(state), null); assert.equal(state.connection_recovery.camera_recovery, "inactive"); assert.equal(state.connection_recovery.camera_media_state, "inactive"); assert.equal(state.connection_recovery.camera_media_ready, false); assert.equal(state.connection_recovery.camera_epoch, null); assert.deepEqual(state.camera_preview.activation_admission, { state: "waiting-for-first-authoritative-pcl", basis: "post-rerun-publish-pcl-frame", runtime_producer_generation: 1, device_command_sent: false, }); const pipeline = renderPipeline(state); assert.match(pipeline, /Восстанавливаем соединение/); assert.match(pipeline, /START, STOP, Bluetooth и настройки устройства не отправляются/); assert.equal(buttonsWithText(pipeline, "Прервать соединение").length, 1); assert.equal(buttonsWithText(pipeline, "Запустить приём").length, 0); assert.equal(buttonsWithText(pipeline, "Остановить устройство и запись").length, 0); assert.equal(buttonsWithText(pipeline, "Остановить сканирование").length, 0); assert.doesNotMatch( pipeline, /СВЯЗЬ ВОССТАНОВЛЕНА|Связь восстановлена · приём продолжается|Продолжаем тот же приём/, ); const spatial = renderSpatialControls(state); assert.match(spatial, /Восстанавливаем соединение/); assert.equal(buttonsWithText(spatial, "Прервать соединение").length, 1); assert.doesNotMatch( spatial, /Остановить устройство|Остановить K1|Завершить локальный приём/, ); }); test("cold restart first PCL preserves lineage and renders recovered continuation copy", () => { const beforePcl = coldRestartPrePclState(); const state = coldRestartRecoveredState(); assert.equal(isXgridsActiveStreamRecovery(state.connection_recovery), true); assert.equal( state.connection_recovery.acquisition_id, beforePcl.connection_recovery.acquisition_id, ); assert.equal( state.connection_recovery.generation, beforePcl.connection_recovery.generation, ); assert.equal( state.connection_recovery.runtime_producer_generation, beforePcl.connection_recovery.runtime_producer_generation, ); const lineage = exactActiveStreamRecoveryLineage(state); const browserAuthority = activeStreamRecoveredBrowserAuthority(state); assert.deepEqual(lineage && { runtime: lineage.snapshotRuntimeId, acquisition: lineage.acquisitionId, revision: lineage.acquisitionStateRevision, recovery: lineage.recoveryGeneration, producer: lineage.runtimeProducerGeneration, }, { runtime: "snapshot-runtime-after-cold-restart-001", acquisition: "acquisition-before-backend-restart-001", revision: 5, recovery: 1, producer: 1, }); assert.deepEqual(browserAuthority, lineage); assert.equal(activeStreamRecoveryPresentationAuthority(state), null); assert.equal(activeStreamForceFinishAuthority(state), null); assert.equal(state.connection_recovery.camera_recovery, "owned"); assert.equal(state.camera_preview.activation_admission.device_command_sent, false); const pipeline = renderPipeline(state); assert.doesNotMatch(pipeline, /Восстанавливаем соединение|Прервать соединение/); assert.match(pipeline, /СВЯЗЬ ВОССТАНОВЛЕНА · АКТИВНЫЙ ПРИЁМ/); assert.match(pipeline, /Связь восстановлена · приём продолжается/); assert.match(pipeline, /Продолжаем тот же приём без нового START/); assert.doesNotMatch(pipeline, /Назовите проект и запустите приём|Запустить приём/); }); test("force-finish authority requires exact runtime, acquisition, revision and generations", () => { const state = recoveryState(); const authority = activeStreamForceFinishAuthority(state); assert.deepEqual(authority && { snapshotRuntimeId: authority.snapshotRuntimeId, acquisitionId: authority.acquisitionId, acquisitionStateRevision: authority.acquisitionStateRevision, recoveryGeneration: authority.recoveryGeneration, runtimeProducerGeneration: authority.runtimeProducerGeneration, }, { snapshotRuntimeId: "snapshot-runtime-recovery-001", acquisitionId: "acquisition-recovery-001", acquisitionStateRevision: 9, recoveryGeneration: 7, runtimeProducerGeneration: 11, }); assert.equal(activeStreamForceFinishAuthorityMatches(authority, state), true); const staleCases = [ (() => { const value = structuredClone(state); value.snapshot_runtime_id = "snapshot-runtime-recovery-002"; return value; })(), (() => { const value = structuredClone(state); value.acquisition.acquisition_id = "acquisition-recovery-002"; return value; })(), (() => { const value = structuredClone(state); value.acquisition.state_revision += 1; return value; })(), (() => { const value = structuredClone(state); value.connection_recovery.generation += 1; return value; })(), (() => { const value = structuredClone(state); value.producer_generation += 1; return value; })(), ]; for (const stale of staleCases) { assert.equal(activeStreamForceFinishAuthorityMatches(authority, stale), false); } assert.equal( activeStreamForceFinishAuthority(recoveryState({ state: "recovered", force_finish_allowed: false })), null, ); assert.equal( activeStreamForceFinishAuthority(recoveryState({ force_finish_allowed: false })), null, ); }); test("reconnecting presentation is exact and owns stale supervisor projection", () => { const state = recoveryState({ force_finish_allowed: false }); const authority = activeStreamRecoveryPresentationAuthority(state); assert.deepEqual(authority && { runtime: authority.snapshotRuntimeId, acquisition: authority.acquisitionId, producer: authority.runtimeProducerGeneration, recovery: authority.recoveryGeneration, }, { runtime: "snapshot-runtime-recovery-001", acquisition: "acquisition-recovery-001", producer: 11, recovery: 7, }); assert.equal(activeStreamRecoveryOwnsPresentationDecision(state), true); const wrongProducer = structuredClone(state); wrongProducer.producer_generation += 1; assert.equal(activeStreamRecoveryPresentationAuthority(wrongProducer), null); assert.equal( activeStreamRecoveryOwnsPresentationDecision(wrongProducer), true, "a valid reconnect contract must block stale ordinary data projection", ); for (const recoveryStateName of [ "blocked", "standby", "fault", "force-finishing", "force-finished", ]) { const terminal = recoveryState({ state: recoveryStateName }); assert.equal(activeStreamRecoveryPresentationAuthority(terminal), null); assert.equal(activeStreamRecoveryOwnsPresentationDecision(terminal), true); } assert.equal( activeStreamRecoveryOwnsPresentationDecision(recoveryState({ state: "recovered" })), false, ); }); test("recovered browser carryover keeps exact lineage without restoring recovery controls", () => { const state = recoveryState({ state: "recovered", force_finish_allowed: false, elapsed_ms: null, reason_code: null, }, { phase: "live", }); const authority = activeStreamRecoveredBrowserAuthority(state); assert.deepEqual(authority && { runtime: authority.snapshotRuntimeId, acquisition: authority.acquisitionId, revision: authority.acquisitionStateRevision, producer: authority.runtimeProducerGeneration, recovery: authority.recoveryGeneration, }, { runtime: "snapshot-runtime-recovery-001", acquisition: "acquisition-recovery-001", revision: 9, producer: 11, recovery: 7, }); assert.equal(activeStreamRecoveryPresentation(state), null); assert.equal(activeStreamForceFinishAuthority(state), null); const staleProducer = structuredClone(state); staleProducer.producer_generation += 1; assert.equal(activeStreamRecoveredBrowserAuthority(staleProducer), null); assert.equal( activeStreamRecoveredBrowserAuthority(recoveryState({ state: "recovered", camera_recovery: "blocked", force_finish_allowed: false, }, { phase: "live" })), null, ); }); test("only an exact reconnecting lineage suppresses the generic red error", () => { const state = recoveryState(); assert.equal(suppressGenericErrorDuringActiveStreamRecovery(state, null), true); assert.equal( shouldRenderK1GenericRuntimeError("Ошибка локального приёмника", false, state, null), false, ); assert.equal( suppressGenericErrorDuringActiveStreamRecovery(state, "force-finish"), false, ); assert.equal( shouldRenderK1GenericRuntimeError( "Локальное завершение не выполнено", false, state, "force-finish", ), true, "a failed explicit local finish must keep the generic error banner visible", ); const wrongProducer = structuredClone(state); wrongProducer.producer_generation += 1; assert.equal(suppressGenericErrorDuringActiveStreamRecovery(wrongProducer), false); const wrongAcquisition = structuredClone(state); wrongAcquisition.connection_recovery.acquisition_id = "acquisition-stale"; assert.equal(suppressGenericErrorDuringActiveStreamRecovery(wrongAcquisition), false); const missingRuntime = structuredClone(state); delete missingRuntime.snapshot_runtime_id; assert.equal(suppressGenericErrorDuringActiveStreamRecovery(missingRuntime), false); const blocked = recoveryState({ state: "blocked" }); assert.equal(suppressGenericErrorDuringActiveStreamRecovery(blocked), false); const nonOwned = recoveryState({ automatic_read_only_rebind: false }); assert.equal(suppressGenericErrorDuringActiveStreamRecovery(nonOwned), false); const inactiveCases = [ recoveryState({}, { phase: "error" }), recoveryState({}, { source_mode: "idle" }), recoveryState({}, { acquisition: { ...state.acquisition, state: "failed", }, }), ]; for (const inactive of inactiveCases) { assert.equal( suppressGenericErrorDuringActiveStreamRecovery(inactive, null), false, "stale recovery projection must fail open to the error banner", ); } }); test("reconnecting presentation is neutral, timed and exposes explicit local finish", () => { const state = recoveryState(); const presentation = activeStreamRecoveryPresentation(state); assert.equal(presentation?.state, "reconnecting"); assert.equal(presentation?.tone, "neutral"); assert.equal(presentation?.progressLabel, "Попытка 3 · 12 с"); assert.equal(presentation?.forceFinishAvailable, true); const markup = renderPipeline(state); assert.match(markup, /Восстанавливаем соединение/); assert.match(markup, /Попытка 3 · 12 с/); assert.match(markup, /class="nodedc-activity-indicator/); assert.equal(buttonsWithText(markup, "Прервать соединение").length, 1); assert.match(markup, /START, STOP, Bluetooth и настройки устройства не отправляются/); assert.doesNotMatch(markup, /Ошибка локального приёмника/); assert.equal(shouldRenderK1OperationalPanels(state), true); }); test("spatial scene owns the same recovery spinner and explicit local finish", () => { const markup = renderSpatialControls(recoveryState()); assert.match(markup, /Восстанавливаем соединение/); assert.match(markup, /Попытка 3 · 12 с/); assert.match(markup, /class="nodedc-activity-indicator/); assert.match(markup, /data-recovery-state="reconnecting"/); assert.equal(buttonsWithText(markup, "Прервать соединение").length, 1); assert.match(markup, /локальный front\/back-приём/); assert.doesNotMatch( markup, /Остановить устройство|Остановить K1|Завершить локальный приём/, "recovery must not expose canonical STOP or the generic receiver stop", ); }); test("spatial blocked and fault recovery copy is terminal and truthful", () => { const blocked = renderSpatialControls(recoveryState({ state: "blocked", reason_code: "exact-binding-changed", })); assert.match(blocked, /Связь не восстановлена/); assert.match(blocked, /Восстановление остановлено/); assert.doesNotMatch(blocked, /class="nodedc-activity-indicator/); assert.equal(buttonsWithText(blocked, "Прервать соединение").length, 1); const fault = renderSpatialControls(recoveryState({ state: "fault", force_finish_allowed: false, reason_code: "active-stream-recovery-system-error", })); assert.match(fault, /K1 сообщил об ошибке/); assert.match(fault, /Автоматических команд и повторов нет/); assert.equal(buttonsWithText(fault, "Прервать соединение").length, 0); }); test("spatial recovery interaction routes only to exact local force-finish", async () => { let forceFinishCalls = 0; const current = recoveryState(); const invoked = await runSpatialActiveStreamForceFinish({ state: current, forceFinishActiveStreamLocally: async () => { forceFinishCalls += 1; return true; }, }); assert.equal(invoked, true); assert.equal(forceFinishCalls, 1); const stale = structuredClone(current); stale.connection_recovery.runtime_producer_generation += 1; const rejected = await runSpatialActiveStreamForceFinish({ state: stale, forceFinishActiveStreamLocally: async () => { forceFinishCalls += 1; return true; }, }); assert.equal(rejected, false); assert.equal(forceFinishCalls, 1, "stale lineage must not dispatch any action"); }); test("spatial force-finish pending owns the surface without a second action", () => { const markup = renderSpatialControls( recoveryState({ state: "force-finishing", acquisition_id: null, force_finish_allowed: false, automatic_read_only_rebind: false, camera_recovery: "inactive", }), { pendingAction: "force-finish" }, ); assert.match(markup, /Завершаем локальный приём/); assert.match(markup, /data-recovery-state="force-finishing"/); assert.match(markup, /Команда STOP устройству не отправляется/); assert.equal(buttonsWithText(markup, "Прервать соединение").length, 0); }); test("blocked, camera-blocked, standby and fault copy stay truthful", () => { const blocked = recoveryState({ state: "blocked", reason_code: "exact-binding-changed" }); const blockedMarkup = renderPipeline(blocked); assert.match(blockedMarkup, /Связь не восстановлена/); assert.match(blockedMarkup, /Восстановление остановлено/); assert.doesNotMatch(blockedMarkup, /class="nodedc-activity-indicator/); assert.equal(buttonsWithText(blockedMarkup, "Прервать соединение").length, 1); const cameraBlocked = recoveryState({ state: "blocked", camera_recovery: "blocked", reason_code: "camera-recovery-failed", }); assert.match(renderPipeline(cameraBlocked), /Видеопоток не восстановлен/); const standby = recoveryState({ state: "standby", force_finish_allowed: false, reason_code: "device-reported-standby", }); const standbyMarkup = renderPipeline(standby); assert.match(standbyMarkup, /Устройство перешло в ожидание/); assert.match(standbyMarkup, /без команды STOP/); assert.equal(buttonsWithText(standbyMarkup, "Прервать соединение").length, 0); assert.equal(shouldRenderK1OperationalPanels(standby), true); const fault = recoveryState({ state: "fault", force_finish_allowed: false, reason_code: "active-stream-recovery-system-error", }); const faultMarkup = renderPipeline(fault); assert.match(faultMarkup, /K1 сообщил об ошибке/); assert.match(faultMarkup, /Автоматических команд и повторов нет/); assert.equal(buttonsWithText(faultMarkup, "Прервать соединение").length, 0); assert.equal(shouldRenderK1OperationalPanels(fault), true); }); test("recovered active lineage renders the continued session and one exact STOP", () => { const state = recoveryState({ state: "recovered", force_finish_allowed: false, elapsed_ms: null, reason_code: null, }, { phase: "live", compatibility: { vendor_writes_enabled: true, permitted_mode: "active-control", }, application_control_session: { session_generation: 5, state_revision: 8, state: "scanning", can_stop: true, control_socket_open: true, }, connection_policy: { schema_version: "missioncore.xgrids-k1-connection-policy/v1", facts: { retained_context_is_presence: false }, allowed_actions: ["stop-acquisition"], actions: { "stop-acquisition": { allowed: true, reason_codes: [], target_source: "connection-supervisor", required_transport_ref: null, required_connection_mode: null, requires_live_gatt_validation: false, automatic_retry: false, }, }, }, }); assert.equal(activeStreamRecoveryPresentation(state), null); const markup = renderPipeline(state); assert.doesNotMatch(markup, /Восстанавливаем соединение|Прервать соединение/); assert.match(markup, /СВЯЗЬ ВОССТАНОВЛЕНА · АКТИВНЫЙ ПРИЁМ/); assert.match(markup, /Связь восстановлена · приём продолжается/); assert.match(markup, /Продолжаем тот же приём без нового START/); assert.doesNotMatch(markup, /Назовите проект и запустите приём|Запустить приём/); const stopButtons = buttonsWithText(markup, "Остановить устройство и запись"); assert.equal(stopButtons.length, 1); assert.doesNotMatch(stopButtons[0], /\bdisabled(?:=|\s|>)/); }); test("stale recovered marker on an idle released runtime fails closed to idle UI", () => { const state = recoveryState({ state: "recovered", force_finish_allowed: false, elapsed_ms: null, reason_code: null, }, { phase: "idle", source_mode: "idle", acquisition: { ...recoveryState().acquisition, state: "completed", cleanup_pending: false, }, application_control_session: { session_generation: 5, state_revision: 9, state: "completed", can_stop: false, control_socket_open: false, }, }); assert.equal(activeStreamRecoveryPresentation(state), null); const markup = renderPipeline(state); assert.doesNotMatch( markup, /СВЯЗЬ ВОССТАНОВЛЕНА|Связь восстановлена · приём продолжается|Продолжаем тот же приём/, ); assert.match(markup, /Назовите проект и запустите приём/); assert.equal(buttonsWithText(markup, "Остановить устройство и запись").length, 0); assert.equal(buttonsWithText(markup, "Остановить сканирование").length, 0); }); test("force-finishing shows one local-only pending owner and no second action", () => { const state = recoveryState({ state: "force-finishing", acquisition_id: null, force_finish_allowed: false, automatic_read_only_rebind: false, runtime_producer_generation: 11, camera_recovery: "inactive", }); const markup = renderPipeline(state, { pendingAction: "force-finish" }); assert.match(markup, /Завершаем локальный приём/); assert.match(markup, /Команда STOP устройству не отправляется/); assert.match(markup, /class="nodedc-activity-indicator/); assert.equal(buttonsWithText(markup, "Прервать соединение").length, 0); }); test("elapsed presentation is deterministic", () => { assert.equal(formatActiveStreamRecoveryElapsed(null), null); assert.equal(formatActiveStreamRecoveryElapsed(-1), null); assert.equal(formatActiveStreamRecoveryElapsed(999), "0 с"); assert.equal(formatActiveStreamRecoveryElapsed(59_999), "59 с"); assert.equal(formatActiveStreamRecoveryElapsed(60_000), "1 мин"); assert.equal(formatActiveStreamRecoveryElapsed(125_900), "2 мин 5 с"); }); test("force-finish manifest/API sends the exact fenced local-only request", async () => { assert.equal( xgridsK1Actions.acquisitionForceFinishLocal, "acquisition.force-finish-local", ); const request = { expected_snapshot_runtime_id: "snapshot-runtime-recovery-001", acquisition_id: "acquisition-recovery-001", expected_state_revision: 9, expected_recovery_generation: 7, operator_confirmed: true, operation_id: "op-00000000-0000-4000-8000-000000000321", idempotency_key: "acquisition.force-finish-local:op-00000000-0000-4000-8000-000000000321", deadline_seconds: 30, }; let capturedUrl = null; let capturedInit = null; const originalFetch = globalThis.fetch; globalThis.fetch = async (input, init) => { capturedUrl = String(input); capturedInit = init; return new Response(JSON.stringify({ state: recoveryState() }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { await xgridsK1Api.forceFinishAcquisitionLocally(request); } finally { globalThis.fetch = originalFetch; } assert.match( capturedUrl, /\/actions\/acquisition\.force-finish-local$/, ); assert.equal(capturedInit.method, "POST"); assert.deepEqual(JSON.parse(capturedInit.body), { input: request }); }); test("state API rejects a drifted active recovery contract", async () => { const originalFetch = globalThis.fetch; globalThis.fetch = async () => new Response(JSON.stringify({ state: recoveryState({ stop_performed: true }), }), { status: 200, headers: { "Content-Type": "application/json" }, }); try { await assert.rejects( () => xgridsK1Api.getState(), /некорректное состояние/, ); } finally { globalThis.fetch = originalFetch; } }); test("frontend boundary keeps recovery automatic work read-only and local finish explicit", () => { const hookSource = readFileSync(hookSourceUrl, "utf8"); const forceFinish = sourceSlice( hookSource, "const forceFinishActiveStreamLocally", "const abort", ); assert.match(forceFinish, /run\("force-finish"/); assert.match(forceFinish, /activeStreamForceFinishAuthority\(latestState\.current\)/); assert.match(forceFinish, /expected_snapshot_runtime_id:\s*authority\.snapshotRuntimeId/); assert.match(forceFinish, /acquisition_id:\s*authority\.acquisitionId/); assert.match(forceFinish, /expected_state_revision:\s*authority\.acquisitionStateRevision/); assert.match(forceFinish, /expected_recovery_generation:\s*authority\.recoveryGeneration/); assert.match(forceFinish, /operator_confirmed:\s*true/); assert.match( forceFinish, /newMutationContext\("acquisition\.force-finish-local"\)/, ); assert.equal( (forceFinish.match(/forceFinishAcquisitionLocally\(/g) ?? []).length, 1, ); assert.doesNotMatch( forceFinish, /startAcquisition|stopAcquisition|scanBle|selectCameraPreview|connect\(/, ); const acquisitionSource = readFileSync(acquisitionSourceUrl, "utf8"); assert.equal( (acquisitionSource.match(/forceFinishActiveStreamLocally\(\)/g) ?? []).length, 1, "the explicit recovery button is the only frontend caller", ); const recoverySurface = readFileSync(recoverySurfaceSourceUrl, "utf8"); assert.match(recoverySurface, /