Files
L'électron rare 010981846a test(desktop): vitest + OTAManager unit tests
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.
2026-05-03 14:14:59 +02:00

42 lines
1.4 KiB
JSON

{
"name": "zacus-studio",
"version": "1.0.0",
"description": "Zacus Studio — macOS control hub for Professeur Zacus escape room kits",
"main": "dist/main/index.js",
"scripts": {
"dev": "concurrently \"npm run dev:renderer\" \"npm run dev:main\"",
"dev:main": "tsc -p tsconfig.main.json --watch & sleep 2 && electron .",
"dev:renderer": "vite",
"build": "npm run build:renderer && npm run build:main",
"build:renderer": "vite build",
"build:main": "tsc -p tsconfig.main.json",
"build:mac": "npm run build && electron-builder --mac --universal",
"build:mac-arm64": "npm run build && electron-builder --mac --arm64",
"notarize": "node scripts/notarize.js",
"rebuild-native": "electron-rebuild -f -w zacus-native",
"test": "vitest run",
"postinstall": "electron-builder install-app-deps"
},
"dependencies": {
"electron-updater": "^6.3.0",
"serialport": "^12.0.0",
"node-addon-api": "^8.0.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"concurrently": "^9.0.0",
"electron": "^33.0.0",
"electron-builder": "^25.0.0",
"electron-rebuild": "^3.2.9",
"typescript": "^5.6.0",
"vite": "^6.0.0",
"vite-plugin-electron": "^0.28.0",
"vitest": "^2.1.8",
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}