Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
import { EVENTS_CODES, EventsError } from "@suaveplan/events";
import { describe, expect, it } from "@suaveplan/testing/runner";
import type { SubscriptionEntry } from "./event-bus-service.types.js";
import {
buildEmitOptions,
nextSubscriptionId,
projectSubscription,
recordPublishMetric,
stableHash,
toErrorReport,
} from "./helpers.js";
describe("nextSubscriptionId", () => {
it("returns a unique id on every call", { timeout: 5000 }, () => {
const a = nextSubscriptionId();
const b = nextSubscriptionId();
expect(a).not.toBe(b);
expect(a.startsWith("sub_")).toBe(true);
});
});
describe("stableHash", () => {
it("returns deterministic JSON for plain objects", {
timeout: 5000,
}, () => {
expect(stableHash({ a: 1, b: 2 })).toBe(JSON.stringify({ a: 1, b: 2 }));
});
it("returns empty string for undefined", { timeout: 5000 }, () => {
expect(stableHash(undefined)).toBe("");
});
it("falls back to String(payload) on JSON failure", {
timeout: 5000,
}, () => {
const circular: Record<string, unknown> = {};
circular.self = circular;
expect(stableHash(circular)).toBe(String(circular));
});
});
describe("toErrorReport", () => {
it("preserves EventsError code", { timeout: 5000 }, () => {
const err = new EventsError(EVENTS_CODES["LISTENER.THREW"], "boom");
const report = toErrorReport(err);
expect(report.code).toBe("EVENTS.LISTENER.THREW");
expect(report.message).toBe("boom");
});
it("uses LISTENER_FAILED envelope for plain Error", {
timeout: 5000,
}, () => {
const report = toErrorReport(new Error("oops"));
expect(report.code).toBe("EVENT_BUS.LISTENER_FAILED");
expect(report.message).toBe("oops");
});
it("stringifies non-Error throwables", { timeout: 5000 }, () => {
const report = toErrorReport("literal");
expect(report.code).toBe("EVENT_BUS.LISTENER_FAILED");
expect(report.message).toBe("literal");
});
});
describe("projectSubscription", () => {
const base: SubscriptionEntry = {
id: "s",
topic: "t",
scopedTopic: "t",
listener: () => undefined,
detach: () => undefined,
createdAt: 0,
once: false,
idempotent: false,
};
it("includes tenantId when present", { timeout: 5000 }, () => {
const view = projectSubscription({ ...base, tenantId: "ta" });
expect(view.tenantId).toBe("ta");
});
it("omits tenantId when absent", { timeout: 5000 }, () => {
const view = projectSubscription(base);
expect("tenantId" in view).toBe(false);
});
});
describe("buildEmitOptions", () => {
it("returns an empty object when nothing is supplied", {
timeout: 5000,
}, () => {
expect(buildEmitOptions({})).toEqual({});
});
it("forwards signal/timeoutMs/traceId", { timeout: 5000 }, () => {
const ac = new AbortController();
const out = buildEmitOptions({
signal: ac.signal,
timeoutMs: 1234,
traceId: "trace-1",
});
expect(out?.signal).toBe(ac.signal);
expect(out?.timeoutMs).toBe(1234);
expect(out?.traceId).toBe("trace-1");
});
it("falls back from traceId to idempotencyKey", { timeout: 5000 }, () => {
const out = buildEmitOptions({ idempotencyKey: "k1" });
expect(out?.traceId).toBe("k1");
});
});
describe("recordPublishMetric", () => {
it("does not throw for either outcome", { timeout: 5000 }, () => {
expect(() =>
recordPublishMetric("order.created", "success", 1)
).not.toThrow();
expect(() =>
recordPublishMetric("order.created", "error", 1)
).not.toThrow();
});
});