"use strict"; // Publishing without a broker: MemoryPublisher under a device, a device on no bridge, and the topics by name. const { test } = require("node:test"); const assert = require("node:assert/strict"); const { Alex2MQTT, MemoryPublisher, PowerController, topics } = require("alex2node"); const { endpoint } = require("./helpers/endpoint.js"); test("the topics of the contract, \"alexaResponce\" spelt as the backend spells it", () => { assert.equal(topics.discoverReply("root"), "root/discover_r"); assert.equal(topics.response("root", "lamp-1"), "root/lamp-1/alexaResponce"); assert.equal(topics.deferred("root", "lamp-1"), "root/lamp-1/deferredResponse"); assert.equal(topics.changeReport("root"), "root/changeReport"); }); test("MemoryPublisher: what a device sends, by topic, as a subscriber parses it", async () => { const lamp = endpoint("lamp-1"); const sent = lamp.publisher = new MemoryPublisher(); assert.equal(await lamp.getStatusMessage("ct", true).addPowerControllerProp(PowerController.ON).send(), "root/lamp-1/alexaResponce"); assert.equal(await lamp.getErrorMessage("ct").send(true), "root/lamp-1/deferredResponse"); assert.equal(await lamp.sendSceneResponse("ct", true), "root/lamp-1/alexaResponce"); assert.equal(await lamp.getChangeReport().addPowerControllerProp(PowerController.OFF).send(), "root/changeReport"); assert.deepEqual(sent.published.map(({ topic, message }) => [topic, message.event.header.name]), [ ["root/lamp-1/alexaResponce", "Response"], ["root/lamp-1/deferredResponse", "ErrorResponse"], ["root/lamp-1/alexaResponce", "ActivationStarted"], ["root/changeReport", "ChangeReport"], ]); assert.deepEqual(await sent.publish("root/x", { a: 1, b: undefined }), { ok: true, topic: "root/x" }); assert.deepEqual(sent.published[4].message, { a: 1 }); }); test("MemoryPublisher.failWith: send() resolves \"\" and the error is reported, nothing is kept", async () => { const lamp = endpoint("lamp-1"); const sent = lamp.publisher = new MemoryPublisher(); sent.failWith = new Error("broker gone"); const reported = []; lamp.onPublishError = (err) => reported.push(err.message); assert.equal(await lamp.sendSceneResponse("ct", false), ""); assert.equal(await lamp.getErrorMessage("ct").send(), ""); assert.deepEqual(reported, ["broker gone", "broker gone"]); assert.deepEqual(sent.published, []); }); test("a device on no bridge: send() resolves \"\" and the error says to register it", async () => { const lamp = endpoint("lamp-1"); const reported = []; lamp.onPublishError = (err) => reported.push(err.message); assert.equal(await lamp.getStatusMessage("ct", true).send(), ""); assert.deepEqual(reported, [ "nothing was published to root/lamp-1/alexaResponce: the device is on no bridge, register it with addDevice() or registerDevice()", ]); }); test("unregisterDevice and clearDevices take the publisher from the device", () => { const bridge = new Alex2MQTT("u", "p", "root"); const lamp = bridge.registerDevice("Lamp", "lamp-1", null); const plug = bridge.registerDevice("Plug", "plug-1", null); assert.ok(lamp.publisher && lamp.publisher === plug.publisher, "one publisher for the devices of a bridge"); bridge.unregisterDevice("lamp-1"); assert.equal(lamp.publisher, null); bridge.clearDevices(); assert.equal(plug.publisher, null); });