test: split media understanding helper coverage

This commit is contained in:
Peter Steinberger
2026-04-07 11:15:46 +01:00
parent 1395650d95
commit 874ca3d691
3 changed files with 109 additions and 90 deletions

View File

@@ -273,21 +273,6 @@ describe("applyMediaUnderstanding echo transcript", () => {
expect(callArgs.payloads[0].text).toBe('📝 "hello world"');
});
it("uses custom echoFormat when provided", async () => {
const mediaPath = await createTempAudioFile();
const ctx = createAudioCtxWithProvider(mediaPath);
const { cfg, providers } = createAudioConfigWithEcho({
echoTranscript: true,
echoFormat: "🎙️ Heard: {transcript}",
transcribedText: "custom message",
});
await applyMediaUnderstanding({ ctx, cfg, providers });
const callArgs = expectSingleEchoDeliveryCall();
expect(callArgs.payloads[0].text).toBe("🎙️ Heard: custom message");
});
it("does NOT echo when there are no audio attachments", async () => {
// Image-only context — no audio attachment
const dir = await fs.mkdtemp(path.join(suiteTempMediaRootDir, "img-"));
@@ -329,72 +314,4 @@ describe("applyMediaUnderstanding echo transcript", () => {
expect(ctx.Transcript).toBeUndefined();
expect(mockDeliverOutboundPayloads).not.toHaveBeenCalled();
});
it("does NOT echo when channel is not deliverable", async () => {
const mediaPath = await createTempAudioFile();
// Use an internal/non-deliverable channel
const ctx = createAudioCtxWithProvider(mediaPath, {
Provider: "internal-system",
From: "some-source",
});
const { cfg, providers } = createAudioConfigWithEcho({ echoTranscript: true });
await applyMediaUnderstanding({ ctx, cfg, providers });
// Transcript should be set (transcription succeeded)
expect(ctx.Transcript).toBe("hello world");
// But echo should be skipped
expect(mockDeliverOutboundPayloads).not.toHaveBeenCalled();
});
it("does NOT echo when ctx has no From or OriginatingTo", async () => {
const mediaPath = await createTempAudioFile();
const ctx: MsgContext = {
Body: "<media:audio>",
MediaPath: mediaPath,
MediaType: "audio/ogg",
Provider: "whatsapp",
// From and OriginatingTo intentionally absent
};
const { cfg, providers } = createAudioConfigWithEcho({ echoTranscript: true });
await applyMediaUnderstanding({ ctx, cfg, providers });
expect(ctx.Transcript).toBe("hello world");
expect(mockDeliverOutboundPayloads).not.toHaveBeenCalled();
});
it("uses OriginatingTo when From is absent", async () => {
const mediaPath = await createTempAudioFile();
const ctx: MsgContext = {
Body: "<media:audio>",
MediaPath: mediaPath,
MediaType: "audio/ogg",
Provider: "whatsapp",
OriginatingTo: "+19999999999",
};
const { cfg, providers } = createAudioConfigWithEcho({ echoTranscript: true });
await applyMediaUnderstanding({ ctx, cfg, providers });
const callArgs = expectSingleEchoDeliveryCall();
expect(callArgs.to).toBe("+19999999999");
});
it("echo delivery failure does not throw or break transcription", async () => {
const mediaPath = await createTempAudioFile();
const ctx = createAudioCtxWithProvider(mediaPath);
const { cfg, providers } = createAudioConfigWithEcho({ echoTranscript: true });
mockDeliverOutboundPayloads.mockRejectedValueOnce(new Error("delivery timeout"));
// Should not throw
const result = await applyMediaUnderstanding({ ctx, cfg, providers });
// Transcription itself succeeded
expect(result.appliedAudio).toBe(true);
expect(ctx.Transcript).toBe("hello world");
// Deliver was attempted
expect(mockDeliverOutboundPayloads).toHaveBeenCalledOnce();
});
});

View File

@@ -1,4 +1,5 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { transcribeFirstAudio } from "./audio-preflight.js";
const runAudioTranscriptionMock = vi.hoisted(() => vi.fn());
@@ -6,13 +7,7 @@ vi.mock("./audio-transcription-runner.js", () => ({
runAudioTranscription: (...args: unknown[]) => runAudioTranscriptionMock(...args),
}));
let transcribeFirstAudio: typeof import("./audio-preflight.js").transcribeFirstAudio;
describe("transcribeFirstAudio", () => {
beforeAll(async () => {
({ transcribeFirstAudio } = await import("./audio-preflight.js"));
});
beforeEach(() => {
runAudioTranscriptionMock.mockReset();
});

View File

@@ -0,0 +1,107 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
const mockDeliverOutboundPayloads = vi.hoisted(() => vi.fn());
vi.mock("../infra/outbound/deliver-runtime.js", () => ({
deliverOutboundPayloads: (...args: unknown[]) => mockDeliverOutboundPayloads(...args),
}));
import { DEFAULT_ECHO_TRANSCRIPT_FORMAT, sendTranscriptEcho } from "./echo-transcript.js";
function createCtx(overrides?: Partial<MsgContext>): MsgContext {
return {
Provider: "whatsapp",
From: "+10000000001",
AccountId: "acc1",
...overrides,
};
}
describe("sendTranscriptEcho", () => {
beforeEach(() => {
mockDeliverOutboundPayloads.mockReset();
mockDeliverOutboundPayloads.mockResolvedValue([{ channel: "whatsapp", messageId: "echo-1" }]);
});
it("sends the default formatted transcript to the resolved origin", async () => {
await sendTranscriptEcho({
ctx: createCtx(),
cfg: {} as OpenClawConfig,
transcript: "hello world",
});
expect(mockDeliverOutboundPayloads).toHaveBeenCalledOnce();
expect(mockDeliverOutboundPayloads).toHaveBeenCalledWith({
cfg: {},
channel: "whatsapp",
to: "+10000000001",
accountId: "acc1",
threadId: undefined,
payloads: [{ text: DEFAULT_ECHO_TRANSCRIPT_FORMAT.replace("{transcript}", "hello world") }],
bestEffort: true,
});
});
it("uses a custom format when provided", async () => {
await sendTranscriptEcho({
ctx: createCtx(),
cfg: {} as OpenClawConfig,
transcript: "custom message",
format: "🎙️ Heard: {transcript}",
});
expect(mockDeliverOutboundPayloads).toHaveBeenCalledWith(
expect.objectContaining({
payloads: [{ text: "🎙️ Heard: custom message" }],
}),
);
});
it("skips non-deliverable channels", async () => {
await sendTranscriptEcho({
ctx: createCtx({ Provider: "internal-system", From: "some-source" }),
cfg: {} as OpenClawConfig,
transcript: "hello world",
});
expect(mockDeliverOutboundPayloads).not.toHaveBeenCalled();
});
it("skips when ctx has no resolved destination", async () => {
await sendTranscriptEcho({
ctx: createCtx({ From: undefined, OriginatingTo: undefined }),
cfg: {} as OpenClawConfig,
transcript: "hello world",
});
expect(mockDeliverOutboundPayloads).not.toHaveBeenCalled();
});
it("prefers OriginatingTo when From is absent", async () => {
await sendTranscriptEcho({
ctx: createCtx({ From: undefined, OriginatingTo: "+19999999999" }),
cfg: {} as OpenClawConfig,
transcript: "hello world",
});
expect(mockDeliverOutboundPayloads).toHaveBeenCalledWith(
expect.objectContaining({
to: "+19999999999",
}),
);
});
it("swallows delivery failures", async () => {
mockDeliverOutboundPayloads.mockRejectedValueOnce(new Error("delivery timeout"));
await expect(
sendTranscriptEcho({
ctx: createCtx(),
cfg: {} as OpenClawConfig,
transcript: "hello world",
}),
).resolves.toBeUndefined();
});
});