feat(FN-2979): add droid CLI probe module for node diagnostics

Added a new `droid-cli-probe` module to the dashboard package with test coverage, implementing a CLI probe capability for the droid system.

Fusion-Task-Id: FN-2979
This commit is contained in:
Fusion
2026-05-01 04:03:02 -07:00
committed by gsxdsm
parent 9f141800cd
commit 2a766fe8d6
12 changed files with 784 additions and 43 deletions

View File

@@ -0,0 +1,43 @@
import { describe, expect, it } from "vitest";
import { probeDroidCli } from "../droid-cli-probe.js";
/**
* These tests exercise the real probe — we deliberately do NOT mock
* `spawn`. The probe's job is to tell the truth about the local system,
* and mocking defeats that. Instead we:
*
* 1. Assert the shape is sound regardless of binary availability
* 2. Assert timeouts fire when the binary hangs (we don't have a
* hanging binary fixture, so we cover the structural case only)
* 3. Let the suite pass whether or not `droid` is installed on the
* test runner — both outcomes are legitimate.
*
* If you need mocked probe behavior for a higher-level route test, spy
* on `probeDroidCli` at the import boundary rather than shimming spawn.
*/
describe("probeDroidCli", () => {
it("returns a well-formed result whether or not droid is installed", async () => {
const result = await probeDroidCli();
expect(typeof result.available).toBe("boolean");
expect(typeof result.probeDurationMs).toBe("number");
if (result.available) {
// When available: version string should come back populated.
expect(typeof result.version).toBe("string");
} else {
// When unavailable: reason must be populated so the UI can render.
expect(typeof result.reason).toBe("string");
}
});
it("respects a short timeout", async () => {
// Not a true hang test (we don't have a hanging binary), but
// confirms the timeoutMs option wires through and probe completes
// in a bounded window when using a very small timeout.
const result = await probeDroidCli({ timeoutMs: 50 });
expect(result.probeDurationMs).toBeLessThan(5000);
// Either it completed fast enough or hit the timeout — both fine.
if (!result.available && result.reason?.includes("timed out")) {
expect(result.reason).toContain("50ms");
}
});
});