From 8e0bcd05850b22e8cda0f5d37d82ab319816f9f0 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Fri, 17 Apr 2026 19:01:25 -0400 Subject: [PATCH] test: keep Zalo outbound contracts lightweight Use shared SDK payload helpers directly in the outbound payload contract helper and narrow ZaloUser target parsing to its session-route module. This preserves the contract proof without loading broad extension runtime/test barrels. --- .../channels/outbound-payload-contract.ts | 109 ++++-------------- 1 file changed, 24 insertions(+), 85 deletions(-) diff --git a/test/helpers/channels/outbound-payload-contract.ts b/test/helpers/channels/outbound-payload-contract.ts index e84620c0a60..785a2c194da 100644 --- a/test/helpers/channels/outbound-payload-contract.ts +++ b/test/helpers/channels/outbound-payload-contract.ts @@ -3,43 +3,16 @@ import type { ReplyPayload } from "../../../src/auto-reply/types.js"; import { primeChannelOutboundSendMock } from "../../../src/channels/plugins/contracts/test-helpers.js"; import { createDirectTextMediaOutbound } from "../../../src/channels/plugins/outbound/direct-text-media.js"; import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js"; +import { sendPayloadWithChunkedTextAndMedia } from "../../../src/plugin-sdk/reply-payload.js"; +import { chunkTextForOutbound } from "../../../src/plugin-sdk/text-chunking.js"; import { resetGlobalHookRunner } from "../../../src/plugins/hook-runner-global.js"; -import { - loadBundledPluginPublicSurfaceSync, - loadBundledPluginTestApiSync, - resolveRelativeBundledPluginPublicModuleId, -} from "../../../src/test-utils/bundled-plugin-public-surface.js"; +import { resolveRelativeBundledPluginPublicModuleId } from "../../../src/test-utils/bundled-plugin-public-surface.js"; type ParseZalouserOutboundTarget = (raw: string) => { threadId: string; isGroup: boolean }; type CreateSlackOutboundPayloadHarness = (params: PayloadHarnessParams) => { run: () => Promise>; sendMock: Mock; to: string; }; -type ChunkZaloTextForOutbound = (text: string, maxLength?: number) => string[]; -type SendPayloadWithChunkedTextAndMedia = (params: { - ctx: { - cfg: unknown; - to: string; - text: string; - payload: ReplyPayload; - }; - sendText: (ctx: { - cfg: unknown; - to: string; - text: string; - payload: ReplyPayload; - }) => Promise<{ channel: string; messageId: string }>; - sendMedia: (ctx: { - cfg: unknown; - to: string; - text: string; - payload: ReplyPayload; - mediaUrl?: string; - }) => Promise<{ channel: string; messageId: string }>; - emptyResult: { channel: string; messageId: string }; - textChunkLimit?: number; - chunker?: ChunkZaloTextForOutbound | null; -}) => Promise<{ channel: string; messageId: string }>; const discordOutboundAdapterModuleId = resolveRelativeBundledPluginPublicModuleId({ fromModuleUrl: import.meta.url, @@ -56,9 +29,18 @@ const whatsappTestApiModuleId = resolveRelativeBundledPluginPublicModuleId({ pluginId: "whatsapp", artifactBasename: "test-api.js", }); +const zalouserSessionRouteModuleId = resolveRelativeBundledPluginPublicModuleId({ + fromModuleUrl: import.meta.url, + pluginId: "zalouser", + artifactBasename: "src/session-route.js", +}); let discordOutboundCache: Promise | undefined; -let parseZalouserOutboundTargetCache: ParseZalouserOutboundTarget | undefined; +let parseZalouserOutboundTargetPromise: + | Promise<{ + parseZalouserOutboundTarget: ParseZalouserOutboundTarget; + }> + | undefined; let slackTestApiPromise: | Promise<{ createSlackOutboundPayloadHarness: CreateSlackOutboundPayloadHarness; @@ -69,9 +51,6 @@ let whatsappTestApiPromise: whatsappOutbound: ChannelOutboundAdapter; }> | undefined; -let chunkZaloTextForOutboundCache: ChunkZaloTextForOutbound | undefined; -let sendZaloPayloadWithChunkedTextAndMediaCache: SendPayloadWithChunkedTextAndMedia | undefined; -let sendZalouserPayloadWithChunkedTextAndMediaCache: SendPayloadWithChunkedTextAndMedia | undefined; async function getDiscordOutbound(): Promise { discordOutboundCache ??= (async () => { @@ -99,52 +78,12 @@ async function getWhatsAppOutboundAsync(): Promise { return whatsappOutbound; } -function getChunkZaloTextForOutbound(): ChunkZaloTextForOutbound { - if (!chunkZaloTextForOutboundCache) { - ({ chunkTextForOutbound: chunkZaloTextForOutboundCache } = loadBundledPluginPublicSurfaceSync<{ - chunkTextForOutbound: ChunkZaloTextForOutbound; - }>({ - pluginId: "zalo", - artifactBasename: "runtime-api.js", - })); - } - return chunkZaloTextForOutboundCache; -} - -function getSendZaloPayloadWithChunkedTextAndMedia(): SendPayloadWithChunkedTextAndMedia { - if (!sendZaloPayloadWithChunkedTextAndMediaCache) { - ({ sendPayloadWithChunkedTextAndMedia: sendZaloPayloadWithChunkedTextAndMediaCache } = - loadBundledPluginPublicSurfaceSync<{ - sendPayloadWithChunkedTextAndMedia: SendPayloadWithChunkedTextAndMedia; - }>({ - pluginId: "zalo", - artifactBasename: "runtime-api.js", - })); - } - return sendZaloPayloadWithChunkedTextAndMediaCache; -} - -function getParseZalouserOutboundTarget(): ParseZalouserOutboundTarget { - if (!parseZalouserOutboundTargetCache) { - ({ parseZalouserOutboundTarget: parseZalouserOutboundTargetCache } = - loadBundledPluginTestApiSync<{ - parseZalouserOutboundTarget: ParseZalouserOutboundTarget; - }>("zalouser")); - } - return parseZalouserOutboundTargetCache; -} - -function getSendZalouserPayloadWithChunkedTextAndMedia(): SendPayloadWithChunkedTextAndMedia { - if (!sendZalouserPayloadWithChunkedTextAndMediaCache) { - ({ sendPayloadWithChunkedTextAndMedia: sendZalouserPayloadWithChunkedTextAndMediaCache } = - loadBundledPluginPublicSurfaceSync<{ - sendPayloadWithChunkedTextAndMedia: SendPayloadWithChunkedTextAndMedia; - }>({ - pluginId: "zalouser", - artifactBasename: "runtime-api.js", - })); - } - return sendZalouserPayloadWithChunkedTextAndMediaCache; +async function getParseZalouserOutboundTarget(): Promise { + parseZalouserOutboundTargetPromise ??= import(zalouserSessionRouteModuleId) as Promise<{ + parseZalouserOutboundTarget: ParseZalouserOutboundTarget; + }>; + const { parseZalouserOutboundTarget } = await parseZalouserOutboundTargetPromise; + return parseZalouserOutboundTarget; } type PayloadHarnessParams = { @@ -367,10 +306,10 @@ function createZaloHarness(params: PayloadHarnessParams) { }; return { run: async () => - await getSendZaloPayloadWithChunkedTextAndMedia()({ + await sendPayloadWithChunkedTextAndMedia({ ctx, textChunkLimit: 2000, - chunker: getChunkZaloTextForOutbound(), + chunker: chunkTextForOutbound, sendText: async (nextCtx) => buildChannelSendResult( "zalo", @@ -406,10 +345,10 @@ function createZalouserHarness(params: PayloadHarnessParams) { }; return { run: async () => - await getSendZalouserPayloadWithChunkedTextAndMedia()({ + await sendPayloadWithChunkedTextAndMedia({ ctx, sendText: async (nextCtx) => { - const target = getParseZalouserOutboundTarget()(nextCtx.to); + const target = (await getParseZalouserOutboundTarget())(nextCtx.to); return buildChannelSendResult( "zalouser", await sendZalouser(target.threadId, nextCtx.text, { @@ -422,7 +361,7 @@ function createZalouserHarness(params: PayloadHarnessParams) { ); }, sendMedia: async (nextCtx) => { - const target = getParseZalouserOutboundTarget()(nextCtx.to); + const target = (await getParseZalouserOutboundTarget())(nextCtx.to); return buildChannelSendResult( "zalouser", await sendZalouser(target.threadId, nextCtx.text, {