Защита Bridge и камеры K1 при переподключении

This commit is contained in:
DCCONSTRUCTIONS
2026-08-23 01:25:25 +03:00
parent 0752e5c6bf
commit 71c8b043c9
8 changed files with 737 additions and 87 deletions
@@ -5355,6 +5355,55 @@ test("an unresolved physical command has one explicit server-bound read-only rec
/Результаты последнего Bluetooth-поиска|nearby-unrelated-device|>Выбрать<|>Применить</,
);
const quickRecoveryInsideBridgeState = structuredClone(state);
quickRecoveryInsideBridgeState.physical_command.record.connection.connection_mode =
"quick-connect";
quickRecoveryInsideBridgeState.physical_command.record.connection.target_ipv4 =
"192.168.56.1";
quickRecoveryInsideBridgeState.semantic_topology_store.record.connection_mode =
"quick-connect";
quickRecoveryInsideBridgeState.semantic_topology_store.record.ipv4 = "192.168.56.1";
quickRecoveryInsideBridgeState.connection_policy.actions[
"observe-configured-device-network"
].required_connection_mode = "quick-connect";
const quickRecoveryInsideBridgeMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(quickRecoveryInsideBridgeState),
desiredMode: "bridge",
},
));
assert.equal(
buttonMarkupWithText(
quickRecoveryInsideBridgeMarkup,
"Переподключиться",
).length,
0,
);
assert.equal(
buttonMarkupWithText(
quickRecoveryInsideBridgeMarkup,
"Подключить новый K1",
).length,
1,
);
const selectedQuickRecoveryState = structuredClone(
quickRecoveryInsideBridgeState,
);
selectedQuickRecoveryState.desired_connection_mode = "quick-connect";
const selectedQuickRecoveryMarkup = renderToStaticMarkup(createElement(
K1ProvisioningPipeline,
{
controller: provisioningController(selectedQuickRecoveryState),
desiredMode: "quick-connect",
},
));
assert.equal(
buttonMarkupWithText(selectedQuickRecoveryMarkup, "Переподключиться").length,
1,
);
const networkSetupState = structuredClone(state);
networkSetupState.connection_verification = {
status: "unreachable",
@@ -5454,6 +5503,14 @@ test("an unresolved physical command has one explicit server-bound read-only rec
);
assert.match(physicalRecovery, /physicalRecoveryTarget\?\.serverBound/);
assert.match(physicalRecovery, /surfaceErrors: false/);
assert.match(
physicalRecovery,
/physicalRecoveryTarget\.connectionMode !== connectionMode/,
);
assert.doesNotMatch(
physicalRecovery,
/commitDesiredModeForExplicitAction|selectConnectionMode\(/,
);
});
test("supervisor DeviceInfo Verify outranks a stale exact fresh row for physical recovery", () => {
@@ -310,7 +310,7 @@ test("a sequential live acquisition re-arms the same camera without reopening a
]);
});
test("a restored layout admits a selected delivery after reload and only same-acquisition successors", () => {
test("a restored layout admits same-lineage replacements and the next acquisition", () => {
const camera = (acquisitionId, deliveryId) => ({
id: "k1:sensor.camera.right",
sourceId: "sensor.camera.right",
@@ -344,7 +344,11 @@ test("a restored layout admits a selected delivery after reload and only same-ac
assert.equal(restoredLayoutMayAdmitLiveDefault([original], new Set()), true);
assert.equal(restoredLayoutMayAdmitLiveDefault([successor], presented), true);
assert.equal(restoredLayoutMayAdmitLiveDefault([unrelated], presented), false);
assert.equal(
restoredLayoutMayAdmitLiveDefault([unrelated], presented),
true,
"Bridge acquisition A must not suppress the first Quick Connect camera in acquisition B",
);
assert.equal(restoredLayoutMayAdmitLiveDefault([{
...original,
activation: { ...original.activation, selected: false },