Files
mesh-catalog/modules/audit-logger/test/audit.test.ts
T
jochen 4128380a3d audit-logger: its test subscribes as the module does and expects local event names
The test subscribed '**', which its in-memory broker never matched, while the module subscribes
'#'; and it still expected the module-qualified type from before event names became local.
2026-10-04 01:21:40 +02:00

61 lines
2.4 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import { mkdtemp, readFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { useBroker } from "@novox/mesh-sdk/messaging";
import { emit, on } from "@novox/mesh-sdk/events";
import { record } from "../audit.ts";
test("audit-logger records every event to the trail as one line each", async () => {
const broker = memBroker();
useBroker(() => broker);
const dir = await mkdtemp(join(tmpdir(), "audit-"));
const path = join(dir, "audit.log");
// The audit-logger's whole behaviour: consume everything, record it.
await on("#", async (event) => record(event, path)); // the pattern index.ts subscribes
process.env.MESH_MODULE = "umami";
process.env.MESH_NODE = "anchor";
await emit("site.created", { domain: "my-app" });
await emit("node.anchor.joined", { role: "worker" }); // a node event, not a module one
const lines = (await readFile(path, "utf8")).trim().split("\n").map((l) => JSON.parse(l));
assert.equal(lines.length, 2);
// A module names its events locally (design 29); the module is the `source`, which together with
// the type says whose event it was. This broker does no namespacing, so the type is as emitted.
assert.deepEqual(lines.map((l) => l.type), ["site.created", "node.anchor.joined"]);
assert.equal(lines[0].source, "umami");
assert.equal(lines[0].node, "anchor");
assert.equal(lines[0].body.domain, "my-app");
delete process.env.MESH_MODULE;
delete process.env.MESH_NODE;
});
function memBroker() {
const subs: { pattern: string; handler: (env: { key: string; node: string; body: unknown }) => Promise<void> }[] = [];
return {
async request() {
throw new Error("unused");
},
async handle() {
return () => {};
},
async publish<T>(env: { key: string; node: string; body: T }): Promise<void> {
for (const s of subs) if (match(s.pattern, env.key)) await s.handler(env);
},
async subscribe<T>(pattern: string, handler: (env: { key: string; node: string; body: T }) => Promise<void>): Promise<() => void> {
subs.push({ pattern, handler: handler as (env: { key: string; node: string; body: unknown }) => Promise<void> });
return () => {};
},
async close() {},
};
}
function match(pattern: string, key: string): boolean {
return pattern === "#" || pattern === key;
}