import { AppConfig } from "../src/config/AppConfig"; describe("AppConfig", () => { it("loads required fields with defaults", () => { const config = AppConfig.fromEnv({ ACI_EMAIL: "grower@example.com", ACI_PASSWORD: "super-secret" }); expect(config.mode).toBe("cloud"); expect(config.aciHost).toBe("http://www.acinfinityserver.com"); expect(config.pollIntervalSeconds).toBe(30); expect(config.listenPort).toBe(9108); expect(config.requestTimeoutMs).toBe(10000); expect(config.logLevel).toBe("info"); expect(config.enableControlApi).toBe(false); expect(config.controlListenPort).toBe(9110); expect(config.bleDefaultMac).toBeNull(); expect(config.bleAllowedMacs).toEqual([]); expect(config.bleDeviceType).toBe(11); expect(config.bleScanTimeoutMs).toBe(20000); expect(config.blePortBase).toBe(1); }); it("throws when required values are missing", () => { expect(() => AppConfig.fromEnv({})).toThrow("ACI_EMAIL is required"); expect(() => AppConfig.fromEnv({ ACI_EMAIL: "x", ACI_PASSWORD: "", POLL_INTERVAL_SECONDS: "30" }) ).toThrow("ACI_PASSWORD is required"); }); it("validates numeric ranges", () => { expect(() => AppConfig.fromEnv({ ACI_EMAIL: "x", ACI_PASSWORD: "y", POLL_INTERVAL_SECONDS: "4" }) ).toThrow("POLL_INTERVAL_SECONDS must be between 5 and 600"); }); it("supports ble mode without cloud credentials", () => { const config = AppConfig.fromEnv({ TYPHON_MODE: "ble", ENABLE_CONTROL_API: "true", TY_BLE_DEFAULT_MAC: "58:8c:81:c6:fc:f6", TY_BLE_ALLOWED_MACS: "11:22:33:44:55:66", TY_BLE_DEVICE_TYPE: "11", TY_BLE_SCAN_TIMEOUT_MS: "25000", TY_BLE_PORT_BASE: "1" }); expect(config.mode).toBe("ble"); expect(config.aciEmail).toBeNull(); expect(config.aciPassword).toBeNull(); expect(config.enableControlApi).toBe(true); expect(config.bleDefaultMac).toBe("58:8C:81:C6:FC:F6"); expect(config.bleAllowedMacs).toEqual([ "11:22:33:44:55:66", "58:8C:81:C6:FC:F6" ]); expect(config.bleDeviceType).toBe(11); expect(config.bleScanTimeoutMs).toBe(25000); expect(config.blePortBase).toBe(1); }); it("validates mode and MAC inputs", () => { expect(() => AppConfig.fromEnv({ TYPHON_MODE: "unknown", ACI_EMAIL: "x", ACI_PASSWORD: "y" })).toThrow("TYPHON_MODE must be one of: cloud, ble"); expect(() => AppConfig.fromEnv({ TYPHON_MODE: "ble", TY_BLE_DEFAULT_MAC: "not-a-mac" })).toThrow("TY_BLE_DEFAULT_MAC must be a MAC address like AA:BB:CC:DD:EE:FF"); expect(() => AppConfig.fromEnv({ TYPHON_MODE: "ble", TY_BLE_PORT_BASE: "2" })).toThrow("TY_BLE_PORT_BASE must be 0 or 1"); }); });