import { create } from "@bufbuild/protobuf"; import * as Protobuf from "@meshtastic/protobufs"; import { describe, expect, it } from "vitest"; import { MeshClient } from "../../src/core/client/MeshClient.ts"; import { createFakeTransport } from "../../src/core/testing/createFakeTransport.ts"; import { ChannelNumber } from "../../src/core/types.ts"; describe("MeshClient with fake transport", () => { it("wires MyNodeInfo → device.myNodeNum signal", async () => { const { transport, respond } = createFakeTransport(); const client = new MeshClient({ transport }); respond.withMyNodeInfo({ myNodeNum: 42 }); await new Promise((r) => setTimeout(r, 10)); expect(client.device.myNodeNum.value).toBe(42); }); it("wires NodeInfo → nodes.list signal", async () => { const { transport, respond } = createFakeTransport(); const client = new MeshClient({ transport }); respond.withNodeInfo({ num: 1234 }); await new Promise((r) => setTimeout(r, 10)); expect(client.nodes.list.value.length).toBe(1); expect(client.nodes.list.value[0]?.num).toBe(1234); }); it("routes a TEXT_MESSAGE_APP mesh packet into chat.messages", async () => { const { transport, respond } = createFakeTransport(); const client = new MeshClient({ transport }); const text = new TextEncoder().encode("hello mesh"); const packet = create(Protobuf.Mesh.MeshPacketSchema, { id: 5, from: 9, to: 0xffffffff, channel: ChannelNumber.Primary, rxTime: Math.trunc(Date.now() / 1000), payloadVariant: { case: "decoded", value: { portnum: Protobuf.Portnums.PortNum.TEXT_MESSAGE_APP, payload: text, wantResponse: false, }, }, }); respond.withMeshPacket(packet); await new Promise((r) => setTimeout(r, 10)); const messages = client.chat.messages(ChannelNumber.Primary).value; expect(messages.length).toBe(1); expect(messages[0]?.text).toBe("hello mesh"); }); }); describe("MeshClient rebooted event", () => { it("dispatches onRebooted when firmware emits a `rebooted` FromRadio", async () => { const { transport, respond } = createFakeTransport(); const client = new MeshClient({ transport }); let fired = 0; client.events.onRebooted.subscribe(() => { fired += 1; }); respond.withRaw( create(Protobuf.Mesh.FromRadioSchema, { payloadVariant: { case: "rebooted", value: true }, }), ); await new Promise((r) => setTimeout(r, 10)); expect(fired).toBe(1); }); });