Desktop had zero tests before. This commit adds vitest at
the desktop package level and 6 unit tests for the OTA
manager logic. The tests run with mocked electron / fs /
http so they need neither a real ESP32 nor the native
serialport / zacus-native rebuild.
Setup:
- vitest.config.ts: node env, scans src/**/__tests__/**/*.test.ts
- desktop/package.json: vitest@^2.1.8 devDep, "test" script
- npm install --ignore-scripts to avoid the
electron-builder install-app-deps postinstall + native
ABI rebuild (these matter for app launch, not unit tests)
Coverage (6 tests, all green in 251 ms):
- construction triggers ensureCacheDir() (mkdir -p
~/.zacus-studio/firmwares stubbed via os homedir mock)
- checkUpdate returns 'unknown' when device + manifest
unreachable (catch swallows the error)
- startUpdate rejects unknown OTA method
- startUpdate rate-limits on same device within 60 s
- importFirmware rejects a binary whose first byte is not
0xE9 (ESP32 image magic)
- importFirmware accepts 0xE9 and copies to cache dir
Documented gap: the activeOTAs concurrent-call guard is
unreachable from external callers because rate-limit
triggers first; left in source as belt-and-braces, not
covered by a test (would need bypass via reflection).
Out of scope (deferred):
- Playwright Electron mode (would require building the
desktop app + mocking serialport at runtime)
- HTTP-flow tests (otaViaWiFi, pollOTAStatus,
waitForReboot) — these need an HTTP server fixture
- BLE / USB delegation paths (executeJavaScript -> renderer)
Acceptance: pnpm test (or npm test) inside desktop/
prints "6 passed (6)" in <1 s.