Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
import type { AdapterContext, MessagingInboundEvent } from "@rakazo/adapter-kit";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
createRecordingMessagingSurface,
|
|
MessagingTeamChatEmulator,
|
|
} from "./messaging-team-chat-emulator.js";
|
|
import { createMessagingTeamChatSender, toTeamChatInbound } from "./team-chat-messaging.js";
|
|
|
|
const context: AdapterContext = {
|
|
operationId: "operation-1",
|
|
traceId: "trace-1",
|
|
spaceId: "space-1",
|
|
userId: "user-1",
|
|
signal: new AbortController().signal,
|
|
};
|
|
|
|
describe("MessagingTeamChatEmulator", () => {
|
|
it("rejects providers that cannot form valid thread IDs", () => {
|
|
expect(() => new MessagingTeamChatEmulator({ provider: "" })).toThrow(/provider/);
|
|
expect(() => new MessagingTeamChatEmulator({ provider: "bad:provider" })).toThrow(/provider/);
|
|
});
|
|
|
|
it("builds inbound fixtures with team-room enrichment fields", () => {
|
|
const emulator = new MessagingTeamChatEmulator();
|
|
const inbound = emulator.buildInbound({
|
|
content: "hello room",
|
|
kind: "mention",
|
|
replyThreadId: "ts-1",
|
|
participantNames: ["Ada", "Grace"],
|
|
});
|
|
expect(inbound.provider).toBe("teamchat-emulator");
|
|
expect(inbound.workspaceId).toBe("T-emulator");
|
|
expect(inbound.isDirect).toBe(false);
|
|
expect(toTeamChatInbound(inbound)).toMatchObject({
|
|
kind: "mention",
|
|
workspaceId: "T-emulator",
|
|
replyThreadId: "ts-1",
|
|
participantNames: ["Ada", "Grace"],
|
|
content: "hello room",
|
|
});
|
|
});
|
|
|
|
it("exposes a MessagingPlatform with group capabilities", () => {
|
|
const platform = new MessagingTeamChatEmulator().createPlatform();
|
|
expect(platform).toMatchObject({
|
|
provider: "teamchat-emulator",
|
|
capabilities: { direct: true, groups: true, typing: false },
|
|
});
|
|
expect(platform.directThreadId?.("U1")).toBe("teamchat-emulator:dm:U1");
|
|
});
|
|
|
|
it("works with createMessagingTeamChatSender via a recording surface", async () => {
|
|
const emulator = new MessagingTeamChatEmulator();
|
|
const recording = createRecordingMessagingSurface(emulator);
|
|
const send = createMessagingTeamChatSender(recording as never);
|
|
await send({
|
|
conversationId: "teamchat-emulator:room-2",
|
|
replyThreadId: null,
|
|
content: "shipped",
|
|
});
|
|
expect(emulator.sent[0]).toMatchObject({
|
|
threadId: "teamchat-emulator:room-2",
|
|
body: "shipped",
|
|
});
|
|
});
|
|
|
|
it("acts as a complete Slack-like messaging surface for product journeys", async () => {
|
|
const emulator = new MessagingTeamChatEmulator({
|
|
provider: "slack",
|
|
capabilities: { groups: false },
|
|
});
|
|
const sink = vi.fn<(event: MessagingInboundEvent) => Promise<void>>(async () => undefined);
|
|
emulator.onInbound(sink);
|
|
|
|
const inbound = await emulator.emitInbound({
|
|
isDirect: true,
|
|
from: "U-colleague",
|
|
fromLabel: "Teammate",
|
|
content: "How is Fairhaven Robotics doing?",
|
|
});
|
|
await emulator.sendToThread({ threadId: inbound.threadId, body: "Checking now." }, context);
|
|
|
|
expect(emulator.platforms()).toEqual([
|
|
{
|
|
provider: "slack",
|
|
capabilities: { direct: true, groups: false, typing: false },
|
|
},
|
|
]);
|
|
expect(sink).toHaveBeenCalledWith(inbound);
|
|
expect(emulator.sent).toMatchObject([
|
|
{
|
|
threadId: inbound.threadId,
|
|
body: "Checking now.",
|
|
handle: "outbound-2",
|
|
},
|
|
]);
|
|
emulator.resetWitnesses();
|
|
expect(emulator.sent).toEqual([]);
|
|
expect(emulator.handleWebhook("teams", new Request("https://example.test"))).toBeNull();
|
|
await expect(emulator.sendTyping("teams:dm:U-colleague", context)).resolves.toBeUndefined();
|
|
await expect(emulator.sendTyping(inbound.threadId, context)).resolves.toBeUndefined();
|
|
});
|
|
});
|