fix(k1): restore canonical local connection lifecycle
This commit is contained in:
@@ -635,6 +635,72 @@ test("a provisioned address is not presented as a verified device connection", (
|
||||
}), "connected");
|
||||
});
|
||||
|
||||
test("K1 provisioning mutations require the operator's fresh BLE candidate", () => {
|
||||
const backendLease = {
|
||||
selected_device_id: "stale-backend-lease-device",
|
||||
connection_mode: "bridge",
|
||||
devices: [
|
||||
{
|
||||
device_id: "fresh-scan-candidate",
|
||||
name: "K1 candidate",
|
||||
connectable: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
assert.equal(
|
||||
lifecycle.provisioningCandidateById(backendLease.devices, ""),
|
||||
null,
|
||||
);
|
||||
assert.equal(
|
||||
lifecycle.provisioningCandidateById(
|
||||
backendLease.devices,
|
||||
backendLease.selected_device_id,
|
||||
),
|
||||
null,
|
||||
);
|
||||
assert.equal(lifecycle.canSubmitProvisioningMutation({
|
||||
devices: backendLease.devices,
|
||||
selectedDeviceId: "expired-scan-candidate",
|
||||
powerConfirmed: true,
|
||||
credentialsReady: true,
|
||||
isBusy: false,
|
||||
}), false);
|
||||
assert.equal(lifecycle.canSubmitProvisioningMutation({
|
||||
devices: backendLease.devices,
|
||||
selectedDeviceId: "fresh-scan-candidate",
|
||||
powerConfirmed: true,
|
||||
credentialsReady: true,
|
||||
isBusy: false,
|
||||
}), true);
|
||||
});
|
||||
|
||||
test("K1 connection status is green only for a reachable matching lease", () => {
|
||||
const unreachableLease = {
|
||||
k1_ip: "192.168.68.50",
|
||||
connection_mode: "bridge",
|
||||
connection_verification: {
|
||||
lease_state: "disconnected",
|
||||
network_reachability: "unreachable",
|
||||
},
|
||||
};
|
||||
const reachableLease = {
|
||||
...unreachableLease,
|
||||
connection_verification: {
|
||||
lease_state: "reachable",
|
||||
network_reachability: "reachable",
|
||||
},
|
||||
};
|
||||
|
||||
assert.equal(lifecycle.isReachableConnectionLease(unreachableLease, "bridge"), false);
|
||||
assert.equal(lifecycle.isReachableConnectionLease(reachableLease, "bridge"), true);
|
||||
assert.equal(lifecycle.isReachableConnectionLease(reachableLease, "quick-connect"), false);
|
||||
assert.equal(lifecycle.isReachableConnectionLease({
|
||||
k1_ip: "192.168.68.50",
|
||||
connection_mode: "bridge",
|
||||
}, "bridge"), false);
|
||||
});
|
||||
|
||||
test("provisioning intent keeps one idempotency key and exposes unsafe outcomes", () => {
|
||||
let created = 0;
|
||||
const createUuid = () => {
|
||||
@@ -751,3 +817,52 @@ test("rejected network-profile writes use safe operator copy", () => {
|
||||
);
|
||||
assert.doesNotMatch(message, /Bleak|GATT|ATT/i);
|
||||
});
|
||||
|
||||
test("host Wi-Fi helper failures do not fabricate a missing-password diagnosis", () => {
|
||||
const operationTimeout = networkProvisionFailureMessage({
|
||||
status: "failed",
|
||||
error: { code: "host-wifi-operation-timeout" },
|
||||
});
|
||||
const buildTimeout = networkProvisionFailureMessage({
|
||||
status: "failed",
|
||||
error: {
|
||||
code: "host-wifi-helper-build-timeout",
|
||||
side_effect_status: "none",
|
||||
safe_to_retry: true,
|
||||
},
|
||||
});
|
||||
const buildFailed = networkProvisionFailureMessage({
|
||||
status: "failed",
|
||||
error: {
|
||||
code: "host-wifi-helper-build-failed",
|
||||
side_effect_status: "none",
|
||||
safe_to_retry: true,
|
||||
},
|
||||
});
|
||||
const postWriteBuildFailed = networkProvisionFailureMessage({
|
||||
status: "failed",
|
||||
error: {
|
||||
code: "host-wifi-helper-build-failed",
|
||||
side_effect_status: "confirmed",
|
||||
safe_to_retry: false,
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
operationTimeout,
|
||||
"Локальная операция подготовки Wi‑Fi не завершилась вовремя. Это могло произойти до изменения состояния K1; наличие сохранённого пароля этим кодом не подтверждается и не опровергается. Проверьте состояние K1 и повторите подключение отдельным действием.",
|
||||
);
|
||||
assert.doesNotMatch(operationTimeout, /получите пароль|пароль отсутствует/i);
|
||||
assert.equal(
|
||||
buildTimeout,
|
||||
"Локальный компонент Wi‑Fi не успел собраться за отведённое время. Команда K1 не отправлялась; подготовьте локальный компонент и повторите подключение отдельным действием.",
|
||||
);
|
||||
assert.equal(
|
||||
buildFailed,
|
||||
"Локальный компонент Wi‑Fi не удалось собрать. Команда K1 не отправлялась; подготовьте локальный компонент и повторите подключение отдельным действием.",
|
||||
);
|
||||
assert.equal(
|
||||
postWriteBuildFailed,
|
||||
"Локальный компонент Wi‑Fi не удалось собрать уже после начала операции с K1. Состояние устройства нельзя выводить из этой локальной ошибки; автоматического повтора команды не было. Выполните read-only проверку K1 перед новым подключением.",
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user