typhon/tests/BleControlBackend.test.ts

98 lines
3.0 KiB
TypeScript

import { BleControllerClient, BleTelemetryReading } from "../src/ble/BleControllerClient";
import { Logger } from "../src/observability/Logger";
import { BleControlBackend } from "../src/services/BleControlBackend";
class FakeBleClient implements BleControllerClient {
public lastSet: { mac: string; portByte: number; speedLevel: number } | null = null;
public telemetry: BleTelemetryReading = {
temperatureCelsius: 24.06,
temperatureFahrenheit: 75.31,
humidityPercent: 41.06,
vpdKpa: 1.76,
choosePort: 3,
workType: 2,
fanSpeedGuess: 7,
receivedAtEpochSeconds: 1_700_000_123
};
public async verifyConnection(): Promise<void> {
return;
}
public async readTelemetry(): Promise<BleTelemetryReading> {
return this.telemetry;
}
public async setPortSpeed(macAddress: string, portByte: number, speedLevel: number): Promise<void> {
this.lastSet = { mac: macAddress, portByte, speedLevel };
}
}
describe("BleControlBackend", () => {
it("pairs and enforces allowed MAC list", async () => {
const client = new FakeBleClient();
const backend = new BleControlBackend({
defaultMac: null,
allowedMacs: ["58:8C:81:C6:FC:F6"],
requestTimeoutMs: 10000,
scanTimeoutMs: 10000,
deviceType: 11,
portBase: 1,
logger: new Logger("error", "test"),
client
});
await expect(backend.pair("11:22:33:44:55:66")).rejects.toThrow("mac address is not in TY_BLE_ALLOWED_MACS");
const status = await backend.pair("58:8c:81:c6:fc:f6");
expect(status.controllerMac).toBe("58:8C:81:C6:FC:F6");
expect(status.connected).toBe(true);
});
it("maps port numbers to device bytes and updates speed cache", async () => {
const client = new FakeBleClient();
const backend = new BleControlBackend({
defaultMac: "58:8C:81:C6:FC:F6",
allowedMacs: [],
requestTimeoutMs: 10000,
scanTimeoutMs: 10000,
deviceType: 11,
portBase: 1,
logger: new Logger("error", "test"),
client
});
await backend.setPortSpeed(4, 9);
expect(client.lastSet).toEqual({
mac: "58:8C:81:C6:FC:F6",
portByte: 3,
speedLevel: 9
});
const ports = await backend.getPorts();
expect(ports.find((p) => p.port === 4)?.currentSpeedLevel).toBe(9);
});
it("builds a climate snapshot from BLE telemetry", async () => {
const client = new FakeBleClient();
const backend = new BleControlBackend({
defaultMac: "58:8C:81:C6:FC:F6",
allowedMacs: [],
requestTimeoutMs: 10000,
scanTimeoutMs: 10000,
deviceType: 11,
portBase: 1,
logger: new Logger("error", "test"),
client
});
const snapshot = await backend.refreshTelemetry();
const controller = snapshot.controllers[0];
expect(controller?.temperatureCelsius).toBeCloseTo(24.06, 2);
expect(controller?.relativeHumidityRatio).toBeCloseTo(0.4106, 4);
expect(controller?.vpdKpa).toBeCloseTo(1.76, 2);
expect(controller?.ports.find((p) => p.port === 4)?.currentSpeedLevel).toBe(7);
});
});