evOo-local/packages/adapters/src/messaging-platforms.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
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.
2026-09-20 17:15:16 +02:00

339 lines
12 KiB
TypeScript

import { Domain } from "chat-adapter-lark";
import { describe, expect, it, vi } from "vitest";
import {
enrichSlackTeamRoom,
isMessagingEnabled,
isMessagingSurfaceEnabled,
type MessagingEnvironmentValues,
messagingEnvFromProcess,
messagingPlatformsFromEnv,
parseSendblueStatus,
} from "./messaging-platforms.js";
// Fake credentials: adapters are constructed offline, never called.
const fullEnv: MessagingEnvironmentValues = {
sendblueApiKeyId: "sb-key-id",
sendblueApiSecret: "sb-secret",
sendblueSigningSecret: "sb-signing",
sendbluePhoneNumber: "+15550009999",
slackBotToken: "xoxb-fake",
slackSigningSecret: "slack-signing",
whatsappAccessToken: "wa-token",
whatsappPhoneNumberId: "wa-phone-id",
whatsappAppSecret: "wa-app-secret",
whatsappVerifyToken: "wa-verify",
telegramBotToken: "tg-token",
telegramWebhookSecret: "tg-webhook-secret",
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
};
function providers(env: MessagingEnvironmentValues): string[] {
return messagingPlatformsFromEnv(env).map((platform) => platform.provider);
}
describe("messagingPlatformsFromEnv", () => {
it("mounts nothing without credentials and everything with full credentials", () => {
expect(providers({})).toEqual([]);
expect(providers(fullEnv)).toEqual(["sendblue", "slack", "whatsapp", "telegram", "lark"]);
});
it("requires all four sendblue values", () => {
for (const key of [
"sendblueApiKeyId",
"sendblueApiSecret",
"sendblueSigningSecret",
"sendbluePhoneNumber",
] as const) {
expect(providers({ ...fullEnv, [key]: undefined })).not.toContain("sendblue");
}
});
it("requires each platform's full credential set", () => {
expect(providers({ ...fullEnv, slackSigningSecret: undefined })).not.toContain("slack");
expect(providers({ ...fullEnv, slackBotToken: undefined })).not.toContain("slack");
for (const key of [
"whatsappAccessToken",
"whatsappPhoneNumberId",
"whatsappAppSecret",
"whatsappVerifyToken",
] as const) {
expect(providers({ ...fullEnv, [key]: undefined })).not.toContain("whatsapp");
}
expect(providers({ ...fullEnv, telegramBotToken: undefined })).not.toContain("telegram");
// Without the secret token the adapter would accept unsigned webhook
// posts, so the secret is a mount gate, not optional hardening.
expect(providers({ ...fullEnv, telegramWebhookSecret: undefined })).not.toContain("telegram");
expect(providers({ telegramBotToken: "tg-token" })).toEqual([]);
expect(
providers({ telegramBotToken: "tg-token", telegramWebhookSecret: "tg-webhook-secret" }),
).toEqual(["telegram"]);
expect(providers({ ...fullEnv, larkAppId: undefined })).not.toContain("lark");
expect(providers({ ...fullEnv, larkAppSecret: undefined })).not.toContain("lark");
// Without the verification token the adapter would accept unsigned
// webhook posts, so the token is a mount gate, not optional hardening.
expect(providers({ ...fullEnv, larkVerificationToken: undefined })).not.toContain("lark");
expect(providers({ larkAppId: "cli-fake", larkAppSecret: "lark-secret" })).toEqual([]);
expect(
providers({
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
}),
).toEqual(["lark"]);
});
it("forces Telegram into webhook mode so worker initialize cannot long-poll", () => {
const telegram = messagingPlatformsFromEnv({
telegramBotToken: "tg-token",
telegramWebhookSecret: "tg-webhook-secret",
})[0]!;
// mode is protected on the adapter class but readable at runtime.
expect((telegram.adapter as unknown as { mode: string }).mode).toBe("webhook");
});
it("forces Lark into webhook inbound so worker initialize cannot open a long connection", () => {
const lark = messagingPlatformsFromEnv({
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
})[0]!;
const incoming = lark.adapter as unknown as {
incomingConfig: { events: string; callbacks: string };
shouldStartWsClient: () => boolean;
};
expect(incoming.incomingConfig).toEqual({ events: "webhook", callbacks: "webhook" });
expect(incoming.shouldStartWsClient()).toBe(false);
});
it("maps LARK_* process env and accepts the international domain switch", () => {
expect(
messagingEnvFromProcess({
LARK_APP_ID: " cli-fake ",
LARK_APP_SECRET: " lark-secret ",
LARK_VERIFICATION_TOKEN: " lark-verify ",
LARK_ENCRYPT_KEY: " lark-encrypt ",
LARK_DOMAIN: " Lark ",
}),
).toMatchObject({
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
larkEncryptKey: "lark-encrypt",
larkDomain: "Lark",
});
const international = messagingPlatformsFromEnv({
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
larkDomain: "Lark",
})[0]!;
expect((international.adapter as unknown as { config: { domain: Domain } }).config.domain).toBe(
Domain.Lark,
);
});
it.each(["", "unknown", "feishu"])("uses normalized Lark defaults for domain %s", (domain) => {
vi.stubEnv("LARK_DOMAIN", domain);
vi.stubEnv("LARK_ENCRYPT_KEY", " ");
try {
const lark = messagingPlatformsFromEnv({
...messagingEnvFromProcess(process.env),
larkAppId: "cli-fake",
larkAppSecret: "lark-secret",
larkVerificationToken: "lark-verify",
}).find((platform) => platform.provider === "lark")!;
const config = (
lark.adapter as unknown as {
config: { domain: Domain; encryptKey: string };
}
).config;
expect(config.domain).toBe(Domain.Feishu);
expect(config.encryptKey).toBe("");
} finally {
vi.unstubAllEnvs();
}
});
it("declares group and typing support only for sendblue", () => {
const platforms = messagingPlatformsFromEnv(fullEnv);
const capabilities = Object.fromEntries(
platforms.map((platform) => [platform.provider, platform.capabilities]),
);
expect(capabilities.sendblue).toEqual({ direct: true, groups: true, typing: true });
expect(capabilities.slack).toEqual({ direct: true, groups: true, typing: false });
expect(capabilities.whatsapp).toEqual({ direct: true, groups: false, typing: false });
expect(capabilities.telegram).toEqual({ direct: true, groups: false, typing: false });
expect(capabilities.lark).toEqual({ direct: true, groups: false, typing: false });
});
});
describe("sendblue platform hooks", () => {
const sendblue = messagingPlatformsFromEnv(fullEnv)[0]!;
it("filters the deployment line and non-string entries out of the roster", () => {
expect(
sendblue.participants!({
participants: ["+15551111111", "+15550009999", 42, null, "+15552222222"],
}),
).toEqual(["+15551111111", "+15552222222"]);
expect(sendblue.participants!({ participants: "not-a-list" })).toEqual([]);
expect(sendblue.participants!(null)).toEqual([]);
});
it("reads the group display name only when present", () => {
expect(sendblue.channelName!({ group_display_name: "Family" })).toBe("Family");
expect(sendblue.channelName!({ group_display_name: "" })).toBeNull();
expect(sendblue.channelName!({})).toBeNull();
expect(sendblue.channelName!(null)).toBeNull();
});
it("accepts only supported per-message transports", () => {
for (const service of ["iMessage", "SMS", "RCS"]) {
expect(sendblue.transport!({ service })).toBe(service);
}
expect(sendblue.transport!({ service: "email" })).toBeNull();
expect(sendblue.transport!({ service: 42 })).toBeNull();
expect(sendblue.transport!(null)).toBeNull();
});
it("derives deterministic provider-prefixed direct thread ids", () => {
expect(sendblue.directThreadId!("+15551234567")).toMatch(/^sendblue:/);
expect(sendblue.adapter.isDM?.(sendblue.directThreadId!("+15551234567"))).toBe(true);
});
});
describe("parseSendblueStatus", () => {
const statusPayload = {
content: "",
is_outbound: true,
status: "DELIVERED",
message_handle: "handle-1",
from_number: "+15550009999",
};
it("normalizes outbound delivery webhooks", () => {
expect(parseSendblueStatus(statusPayload)).toEqual({
type: "status",
provider: "sendblue",
handle: "handle-1",
status: "DELIVERED",
});
expect(parseSendblueStatus({ ...statusPayload, status: 7 })).toEqual(
expect.objectContaining({ status: "" }),
);
});
it("ignores inbound and malformed payloads", () => {
expect(parseSendblueStatus({ ...statusPayload, is_outbound: false })).toBeNull();
expect(parseSendblueStatus({ ...statusPayload, message_handle: "" })).toBeNull();
const { message_handle: _dropped, ...withoutHandle } = statusPayload;
expect(parseSendblueStatus(withoutHandle)).toBeNull();
expect(parseSendblueStatus(null)).toBeNull();
expect(parseSendblueStatus("nope")).toBeNull();
});
});
describe("isMessagingEnabled", () => {
it("requires at least one platform", () => {
vi.stubEnv("VITEST", "");
expect(isMessagingEnabled(messagingPlatformsFromEnv(fullEnv))).toBe(true);
expect(isMessagingEnabled([])).toBe(false);
vi.unstubAllEnvs();
});
it("is disabled under vitest even with platforms configured", () => {
expect(process.env.VITEST).toBeTruthy();
expect(isMessagingEnabled(messagingPlatformsFromEnv(fullEnv))).toBe(false);
});
it.each(["0", "false"])("does not treat VITEST=%s as an active test runner", (value) => {
vi.stubEnv("VITEST", value);
expect(isMessagingEnabled(messagingPlatformsFromEnv(fullEnv))).toBe(true);
vi.unstubAllEnvs();
});
});
describe("isMessagingSurfaceEnabled", () => {
it("requires the deployment model key only for open signup", () => {
vi.stubEnv("VITEST", "");
const platforms = messagingPlatformsFromEnv(fullEnv);
const key = (deploymentModelKey: string | undefined, openSignup: boolean) => ({
deploymentModelKey,
openSignup,
});
// Open signup provisions users with no credentials of their own.
expect(isMessagingSurfaceEnabled(platforms, key("model-key", true))).toBe(true);
expect(isMessagingSurfaceEnabled(platforms, key(undefined, true))).toBe(false);
// Linking-only deployments run linked users on their own credentials.
expect(isMessagingSurfaceEnabled(platforms, key(undefined, false))).toBe(true);
expect(isMessagingSurfaceEnabled([], key("model-key", true))).toBe(false);
vi.unstubAllEnvs();
});
});
describe("enrichSlackTeamRoom", () => {
const base = {
type: "message" as const,
provider: "slack",
handle: "Ev1",
threadId: "slack:C1",
isDirect: false,
from: "U_OTHER",
fromLabel: "Ada",
channelName: "launch",
participants: ["U_OTHER"],
content: "hello <@U_SOMEONE>",
mediaUrl: null,
};
it("marks app_mention events as mention", () => {
const enrichment = enrichSlackTeamRoom(
{
team_id: "T1",
authorizations: [{ user_id: "U_BOT", is_bot: true }],
event: { type: "app_mention", channel: "C1", text: "<@U_BOT> ship it", user: "U_OTHER" },
},
base,
);
expect(enrichment.kind).toBe("mention");
expect(enrichment.workspaceId).toBe("T1");
expect(enrichment.conversationKey).toBe("C1");
});
it("keeps ambient when another user is mentioned, not the bot", () => {
const enrichment = enrichSlackTeamRoom(
{
team_id: "T1",
authorizations: [{ user_id: "U_BOT", is_bot: true }],
event: {
type: "message",
channel: "C1",
text: "hey <@U_SOMEONE> can you look?",
user: "U_OTHER",
},
},
base,
);
expect(enrichment.kind).toBe("ambient");
});
it("marks message events that mention the authorized bot as mention", () => {
const enrichment = enrichSlackTeamRoom(
{
team_id: "T1",
authorizations: [{ user_id: "U_BOT", is_bot: true }],
event: {
type: "message",
channel: "C1",
text: "hey <@U_BOT> ship Friday?",
user: "U_OTHER",
},
},
base,
);
expect(enrichment.kind).toBe("mention");
});
});