diff --git a/package.json b/package.json index 159a24cf..30dd030f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "jszip": "^3.10.1", "mqtt": "^5.14.1", "object-assign-deep": "^0.4.0", - "rimraf": "^6.1.0", + "rimraf": "^6.1.2", "semver": "^7.7.3", "source-map-support": "^0.5.21", "throttleit": "^2.1.0", @@ -68,11 +68,11 @@ "zigbee2mqtt-windfront": "2.3.1" }, "devDependencies": { - "@biomejs/biome": "^2.3.4", + "@biomejs/biome": "^2.3.7", "@types/finalhandler": "^1.2.3", "@types/humanize-duration": "^3.27.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^24.10.0", + "@types/node": "^24.10.1", "@types/object-assign-deep": "^0.4.3", "@types/readable-stream": "4.0.22", "@types/serve-static": "^2.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e045ccbe..0c54269b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,8 +48,8 @@ importers: specifier: ^0.4.0 version: 0.4.0 rimraf: - specifier: ^6.1.0 - version: 6.1.0 + specifier: ^6.1.2 + version: 6.1.2 semver: specifier: ^7.7.3 version: 7.7.3 @@ -85,8 +85,8 @@ importers: version: 2.3.1 devDependencies: '@biomejs/biome': - specifier: ^2.3.4 - version: 2.3.4 + specifier: ^2.3.7 + version: 2.3.7 '@types/finalhandler': specifier: ^1.2.3 version: 1.2.4 @@ -97,8 +97,8 @@ importers: specifier: ^4.0.9 version: 4.0.9 '@types/node': - specifier: ^24.10.0 - version: 24.10.0 + specifier: ^24.10.1 + version: 24.10.1 '@types/object-assign-deep': specifier: ^0.4.3 version: 0.4.3 @@ -113,7 +113,7 @@ importers: version: 8.18.1 '@vitest/coverage-v8': specifier: ^3.1.1 - version: 3.2.4(vitest@3.2.4(@types/node@24.10.0)) + version: 3.2.4(vitest@3.2.4(@types/node@24.10.1)) tmp: specifier: ^0.2.5 version: 0.2.5 @@ -122,7 +122,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/node@24.10.0) + version: 3.2.4(@types/node@24.10.1) optionalDependencies: unix-dgram: specifier: ^2.0.7 @@ -159,55 +159,55 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.3.4': - resolution: {integrity: sha512-TU08LXjBHdy0mEY9APtEtZdNQQijXUDSXR7IK1i45wgoPD5R0muK7s61QcFir6FpOj/RP1+YkPx5QJlycXUU3w==} + '@biomejs/biome@2.3.7': + resolution: {integrity: sha512-CTbAS/jNAiUc6rcq94BrTB8z83O9+BsgWj2sBCQg9rD6Wkh2gjfR87usjx0Ncx0zGXP1NKgT7JNglay5Zfs9jw==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.3.4': - resolution: {integrity: sha512-w40GvlNzLaqmuWYiDU6Ys9FNhJiclngKqcGld3iJIiy2bpJ0Q+8n3haiaC81uTPY/NA0d8Q/I3Z9+ajc14102Q==} + '@biomejs/cli-darwin-arm64@2.3.7': + resolution: {integrity: sha512-LirkamEwzIUULhXcf2D5b+NatXKeqhOwilM+5eRkbrnr6daKz9rsBL0kNZ16Hcy4b8RFq22SG4tcLwM+yx/wFA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.3.4': - resolution: {integrity: sha512-3s7TLVtjJ7ni1xADXsS7x7GMUrLBZXg8SemXc3T0XLslzvqKj/dq1xGeBQ+pOWQzng9MaozfacIHdK2UlJ3jGA==} + '@biomejs/cli-darwin-x64@2.3.7': + resolution: {integrity: sha512-Q4TO633kvrMQkKIV7wmf8HXwF0dhdTD9S458LGE24TYgBjSRbuhvio4D5eOQzirEYg6eqxfs53ga/rbdd8nBKg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.3.4': - resolution: {integrity: sha512-IruVGQRwMURivWazchiq7gKAqZSFs5so6gi0hJyxk7x6HR+iwZbO2IxNOqyLURBvL06qkIHs7Wffl6Bw30vCbQ==} + '@biomejs/cli-linux-arm64-musl@2.3.7': + resolution: {integrity: sha512-/afy8lto4CB8scWfMdt+NoCZtatBUF62Tk3ilWH2w8ENd5spLhM77zKlFZEvsKJv9AFNHknMl03zO67CiklL2Q==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@2.3.4': - resolution: {integrity: sha512-y7efHyyM2gYmHy/AdWEip+VgTMe9973aP7XYKPzu/j8JxnPHuSUXftzmPhkVw0lfm4ECGbdBdGD6+rLmTgNZaA==} + '@biomejs/cli-linux-arm64@2.3.7': + resolution: {integrity: sha512-inHOTdlstUBzgjDcx0ge71U4SVTbwAljmkfi3MC5WzsYCRhancqfeL+sa4Ke6v2ND53WIwCFD5hGsYExoI3EZQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@2.3.4': - resolution: {integrity: sha512-mzKFFv/w66e4/jCobFmD3kymCqG+FuWE7sVa4Yjqd9v7qt2UhXo67MSZKY9Ih18V2IwPzRKQPCw6KwdZs6AXSA==} + '@biomejs/cli-linux-x64-musl@2.3.7': + resolution: {integrity: sha512-CQUtgH1tIN6e5wiYSJqzSwJumHYolNtaj1dwZGCnZXm2PZU1jOJof9TsyiP3bXNDb+VOR7oo7ZvY01If0W3iFQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@2.3.4': - resolution: {integrity: sha512-gKfjWR/6/dfIxPJCw8REdEowiXCkIpl9jycpNVHux8aX2yhWPLjydOshkDL6Y/82PcQJHn95VCj7J+BRcE5o1Q==} + '@biomejs/cli-linux-x64@2.3.7': + resolution: {integrity: sha512-fJMc3ZEuo/NaMYo5rvoWjdSS5/uVSW+HPRQujucpZqm2ZCq71b8MKJ9U4th9yrv2L5+5NjPF0nqqILCl8HY/fg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@2.3.4': - resolution: {integrity: sha512-5TJ6JfVez+yyupJ/iGUici2wzKf0RrSAxJhghQXtAEsc67OIpdwSKAQboemILrwKfHDi5s6mu7mX+VTCTUydkw==} + '@biomejs/cli-win32-arm64@2.3.7': + resolution: {integrity: sha512-aJAE8eCNyRpcfx2JJAtsPtISnELJ0H4xVVSwnxm13bzI8RwbXMyVtxy2r5DV1xT3WiSP+7LxORcApWw0LM8HiA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.3.4': - resolution: {integrity: sha512-FGCijXecmC4IedQ0esdYNlMpx0Jxgf4zceCaMu6fkjWyjgn50ZQtMiqZZQ0Q/77yqPxvtkgZAvt5uGw0gAAjig==} + '@biomejs/cli-win32-x64@2.3.7': + resolution: {integrity: sha512-pulzUshqv9Ed//MiE8MOUeeEkbkSHVDVY5Cz5wVAnH1DUqliCQG3j6s1POaITTFqFfo7AVIx2sWdKpx/GS+Nqw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -557,8 +557,8 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - '@types/node@24.10.0': - resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} '@types/object-assign-deep@0.4.3': resolution: {integrity: sha512-d9Gxaj5j1hzrxJ61EFEg13B4g4FgrT/DYtcDWFXPehR8DF2SUZbVMFtZIs8exkVRiqrqBpdTc/lUUZjncsPpMw==} @@ -867,14 +867,13 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true - glob@11.0.3: - resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + glob@13.0.0: + resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} engines: {node: 20 || >=22} - hasBin: true glossy@0.1.7: resolution: {integrity: sha512-mTCC51QFadK75MvAhrL5nPVIP291NjML1guo10Sa7Yj04tJU4V++Vgm780NIddg9etQD9D8FM67hFGqM8EE2HQ==} @@ -947,10 +946,6 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.1.1: - resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} - engines: {node: 20 || >=22} - js-sdsl@4.3.0: resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} @@ -1090,8 +1085,8 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} pathe@2.0.3: @@ -1141,8 +1136,8 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rimraf@6.1.0: - resolution: {integrity: sha512-DxdlA1bdNzkZK7JiNWH+BAx1x4tEJWoTofIopFo6qWUU94jYrFZ0ubY05TqH3nWPJ1nKa1JWVFDINZ3fnrle/A==} + rimraf@6.1.2: + resolution: {integrity: sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==} engines: {node: 20 || >=22} hasBin: true @@ -1511,39 +1506,39 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.3.4': + '@biomejs/biome@2.3.7': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.3.4 - '@biomejs/cli-darwin-x64': 2.3.4 - '@biomejs/cli-linux-arm64': 2.3.4 - '@biomejs/cli-linux-arm64-musl': 2.3.4 - '@biomejs/cli-linux-x64': 2.3.4 - '@biomejs/cli-linux-x64-musl': 2.3.4 - '@biomejs/cli-win32-arm64': 2.3.4 - '@biomejs/cli-win32-x64': 2.3.4 + '@biomejs/cli-darwin-arm64': 2.3.7 + '@biomejs/cli-darwin-x64': 2.3.7 + '@biomejs/cli-linux-arm64': 2.3.7 + '@biomejs/cli-linux-arm64-musl': 2.3.7 + '@biomejs/cli-linux-x64': 2.3.7 + '@biomejs/cli-linux-x64-musl': 2.3.7 + '@biomejs/cli-win32-arm64': 2.3.7 + '@biomejs/cli-win32-x64': 2.3.7 - '@biomejs/cli-darwin-arm64@2.3.4': + '@biomejs/cli-darwin-arm64@2.3.7': optional: true - '@biomejs/cli-darwin-x64@2.3.4': + '@biomejs/cli-darwin-x64@2.3.7': optional: true - '@biomejs/cli-linux-arm64-musl@2.3.4': + '@biomejs/cli-linux-arm64-musl@2.3.7': optional: true - '@biomejs/cli-linux-arm64@2.3.4': + '@biomejs/cli-linux-arm64@2.3.7': optional: true - '@biomejs/cli-linux-x64-musl@2.3.4': + '@biomejs/cli-linux-x64-musl@2.3.7': optional: true - '@biomejs/cli-linux-x64@2.3.4': + '@biomejs/cli-linux-x64@2.3.7': optional: true - '@biomejs/cli-win32-arm64@2.3.4': + '@biomejs/cli-win32-arm64@2.3.7': optional: true - '@biomejs/cli-win32-x64@2.3.4': + '@biomejs/cli-win32-x64@2.3.7': optional: true '@colors/colors@1.6.0': {} @@ -1770,7 +1765,7 @@ snapshots: '@types/finalhandler@1.2.4': dependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 '@types/http-errors@2.0.5': {} @@ -1778,7 +1773,7 @@ snapshots: '@types/js-yaml@4.0.9': {} - '@types/node@24.10.0': + '@types/node@24.10.1': dependencies: undici-types: 7.16.0 @@ -1786,20 +1781,20 @@ snapshots: '@types/readable-stream@4.0.22': dependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.10.0 + '@types/node': 24.10.1 '@types/triple-beam@1.3.5': {} '@types/ws@8.18.1': dependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.10.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.10.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -1814,7 +1809,7 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.10.0) + vitest: 3.2.4(@types/node@24.10.1) transitivePeerDependencies: - supports-color @@ -1826,13 +1821,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.10.0))': + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.10.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@24.10.0) + vite: 6.3.5(@types/node@24.10.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -2111,7 +2106,7 @@ snapshots: fsevents@2.3.3: optional: true - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 @@ -2120,14 +2115,11 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.0.3: + glob@13.0.0: dependencies: - foreground-child: 3.3.1 - jackspeak: 4.1.1 minimatch: 10.1.1 minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 + path-scurry: 2.0.1 glossy@0.1.7: {} @@ -2194,10 +2186,6 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.1.1: - dependencies: - '@isaacs/cliui': 8.0.2 - js-sdsl@4.3.0: {} js-tokens@9.0.1: {} @@ -2349,7 +2337,7 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-scurry@2.0.0: + path-scurry@2.0.1: dependencies: lru-cache: 11.2.2 minipass: 7.1.2 @@ -2402,9 +2390,9 @@ snapshots: rfdc@1.4.1: {} - rimraf@6.1.0: + rimraf@6.1.2: dependencies: - glob: 11.0.3 + glob: 13.0.0 package-json-from-dist: 1.0.1 rollup@4.44.0: @@ -2549,7 +2537,7 @@ snapshots: test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 + glob: 10.5.0 minimatch: 9.0.5 text-hex@1.0.0: {} @@ -2601,13 +2589,13 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@3.2.4(@types/node@24.10.0): + vite-node@3.2.4(@types/node@24.10.1): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.10.0) + vite: 6.3.5(@types/node@24.10.1) transitivePeerDependencies: - '@types/node' - jiti @@ -2622,7 +2610,7 @@ snapshots: - tsx - yaml - vite@6.3.5(@types/node@24.10.0): + vite@6.3.5(@types/node@24.10.1): dependencies: esbuild: 0.25.5 fdir: 6.4.6(picomatch@4.0.2) @@ -2631,14 +2619,14 @@ snapshots: rollup: 4.44.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 fsevents: 2.3.3 - vitest@3.2.4(@types/node@24.10.0): + vitest@3.2.4(@types/node@24.10.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.10.0)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.10.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -2656,11 +2644,11 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@24.10.0) - vite-node: 3.2.4(@types/node@24.10.0) + vite: 6.3.5(@types/node@24.10.1) + vite-node: 3.2.4(@types/node@24.10.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 transitivePeerDependencies: - jiti - less diff --git a/test/extensions/otaUpdate.test.ts b/test/extensions/otaUpdate.test.ts index b5d8d4df..7f16939f 100644 --- a/test/extensions/otaUpdate.test.ts +++ b/test/extensions/otaUpdate.test.ts @@ -276,50 +276,55 @@ describe("Extension: OTAUpdate", () => { ); }); - it.each(["check", "check/downgrade", "update", "update/downgrade", "schedule", "schedule/downgrade", "unschedule"])( - "refuses to %s when already in progress", - async (type) => { - if (type.includes("schedule") || type.includes("check")) { - isUpdateAvailableSpy.mockImplementationOnce(async () => { - return await new Promise((resolve) => { - setTimeout( - () => - resolve({ - available: false, - currentFileVersion: 1, - otaFileVersion: 1, - }), - 99999, - ); - }); + it.each([ + "check", + "check/downgrade", + "update", + "update/downgrade", + "schedule", + "schedule/downgrade", + "unschedule", + ])("refuses to %s when already in progress", async (type) => { + if (type.includes("schedule") || type.includes("check")) { + isUpdateAvailableSpy.mockImplementationOnce(async () => { + return await new Promise((resolve) => { + setTimeout( + () => + resolve({ + available: false, + currentFileVersion: 1, + otaFileVersion: 1, + }), + 99999, + ); }); - } else { - updateSpy.mockImplementationOnce(async () => { - return await new Promise((resolve) => { - setTimeout(() => resolve(1), 99999); - }); + }); + } else { + updateSpy.mockImplementationOnce(async () => { + return await new Promise((resolve) => { + setTimeout(() => resolve(1), 99999); }); - } + }); + } - mockMQTTEvents.message(`zigbee2mqtt/bridge/request/device/ota_update/${type.includes("schedule") ? "check" : type}`, "bulb"); - await flushPromises(); - mockMQTTEvents.message(`zigbee2mqtt/bridge/request/device/ota_update/${type}`, "bulb"); - await flushPromises(); + mockMQTTEvents.message(`zigbee2mqtt/bridge/request/device/ota_update/${type.includes("schedule") ? "check" : type}`, "bulb"); + await flushPromises(); + mockMQTTEvents.message(`zigbee2mqtt/bridge/request/device/ota_update/${type}`, "bulb"); + await flushPromises(); - if (type.includes("schedule") || type.includes("check")) { - expect(isUpdateAvailableSpy).toHaveBeenCalledTimes(1); - } else { - expect(updateSpy).toHaveBeenCalledTimes(1); - } + if (type.includes("schedule") || type.includes("check")) { + expect(isUpdateAvailableSpy).toHaveBeenCalledTimes(1); + } else { + expect(updateSpy).toHaveBeenCalledTimes(1); + } - await vi.runOnlyPendingTimersAsync(); - expect(mockMQTTPublishAsync).toHaveBeenCalledWith( - `zigbee2mqtt/bridge/response/device/ota_update/${type.replace("/downgrade", "")}`, - stringify({data: {}, status: "error", error: `Update or check for update already in progress for 'bulb'`}), - {}, - ); - }, - ); + await vi.runOnlyPendingTimersAsync(); + expect(mockMQTTPublishAsync).toHaveBeenCalledWith( + `zigbee2mqtt/bridge/response/device/ota_update/${type.replace("/downgrade", "")}`, + stringify({data: {}, status: "error", error: `Update or check for update already in progress for 'bulb'`}), + {}, + ); + }); it("does not crash when read modelID before/after OTA update fails", async () => { devices.bulb.endpoints[0].read.mockRejectedValueOnce("Failed from").mockRejectedValueOnce("Failed to");