test(agents): share media background task fixtures

This commit is contained in:
Vincent Koc
2026-04-12 10:40:20 +01:00
parent 7b7489f41f
commit d96120ad7b
3 changed files with 260 additions and 128 deletions

View File

@@ -0,0 +1,162 @@
import { expect, vi } from "vitest";
type MockWithReset = {
mockReset(): void;
};
export const taskExecutorMocks = {
createRunningTaskRun: vi.fn(),
recordTaskRunProgressByRunId: vi.fn(),
completeTaskRunByRunId: vi.fn(),
failTaskRunByRunId: vi.fn(),
};
export const announceDeliveryMocks = {
deliverSubagentAnnouncement: vi.fn(),
};
export const taskDeliveryRuntimeMocks = {
sendMessage: vi.fn(),
};
type TaskExecutorBackgroundMocks = {
createRunningTaskRun: MockWithReset;
recordTaskRunProgressByRunId: MockWithReset;
};
type TaskDeliveryBackgroundMocks = {
sendMessage: MockWithReset;
};
type AnnouncementBackgroundMocks = {
deliverSubagentAnnouncement: MockWithReset;
};
type MediaBackgroundResetMocks = {
taskExecutorMocks: TaskExecutorBackgroundMocks;
taskDeliveryRuntimeMocks: TaskDeliveryBackgroundMocks;
announceDeliveryMocks: AnnouncementBackgroundMocks;
};
type QueuedTaskExpectation = {
taskExecutorMocks: TaskExecutorBackgroundMocks;
taskKind: string;
sourceId: string;
progressSummary: string;
};
type ProgressExpectation = {
taskExecutorMocks: TaskExecutorBackgroundMocks;
runId: string;
progressSummary: string;
};
type DirectSendExpectation = {
sendMessageMock: unknown;
channel: string;
to: string;
threadId: string;
content: string;
mediaUrls: string[];
};
type FallbackAnnouncementExpectation = {
deliverAnnouncementMock: unknown;
requesterSessionKey: string;
channel: string;
to: string;
source: string;
announceType: string;
resultMediaPath: string;
mediaUrls: string[];
};
export function resetMediaBackgroundMocks({
taskExecutorMocks,
taskDeliveryRuntimeMocks,
announceDeliveryMocks,
}: MediaBackgroundResetMocks): void {
taskExecutorMocks.createRunningTaskRun.mockReset();
taskExecutorMocks.recordTaskRunProgressByRunId.mockReset();
taskDeliveryRuntimeMocks.sendMessage.mockReset();
announceDeliveryMocks.deliverSubagentAnnouncement.mockReset();
}
export function expectQueuedTaskRun({
taskExecutorMocks,
taskKind,
sourceId,
progressSummary,
}: QueuedTaskExpectation): void {
expect(taskExecutorMocks.createRunningTaskRun).toHaveBeenCalledWith(
expect.objectContaining({
taskKind,
sourceId,
progressSummary,
}),
);
}
export function expectRecordedTaskProgress({
taskExecutorMocks,
runId,
progressSummary,
}: ProgressExpectation): void {
expect(taskExecutorMocks.recordTaskRunProgressByRunId).toHaveBeenCalledWith(
expect.objectContaining({
runId,
progressSummary,
}),
);
}
export function expectDirectMediaSend({
sendMessageMock,
channel,
to,
threadId,
content,
mediaUrls,
}: DirectSendExpectation): void {
expect(sendMessageMock).toHaveBeenCalledWith(
expect.objectContaining({
channel,
to,
threadId,
content,
mediaUrls,
}),
);
}
export function expectFallbackMediaAnnouncement({
deliverAnnouncementMock,
requesterSessionKey,
channel,
to,
source,
announceType,
resultMediaPath,
mediaUrls,
}: FallbackAnnouncementExpectation): void {
expect(deliverAnnouncementMock).toHaveBeenCalledWith(
expect.objectContaining({
requesterSessionKey,
requesterOrigin: expect.objectContaining({
channel,
to,
}),
expectsCompletionMessage: true,
internalEvents: expect.arrayContaining([
expect.objectContaining({
source,
announceType,
status: "ok",
result: expect.stringContaining(resultMediaPath),
mediaUrls,
replyInstruction: expect.stringContaining("Prefer the message tool for delivery"),
}),
]),
}),
);
}

View File

@@ -1,35 +1,33 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { MUSIC_GENERATION_TASK_KIND } from "../music-generation-task-status.js";
import {
createMusicGenerationTaskRun,
recordMusicGenerationTaskProgress,
wakeMusicGenerationTaskCompletion,
} from "./music-generate-background.js";
const taskExecutorMocks = vi.hoisted(() => ({
createRunningTaskRun: vi.fn(),
recordTaskRunProgressByRunId: vi.fn(),
completeTaskRunByRunId: vi.fn(),
failTaskRunByRunId: vi.fn(),
}));
const announceDeliveryMocks = vi.hoisted(() => ({
deliverSubagentAnnouncement: vi.fn(),
}));
const taskDeliveryRuntimeMocks = vi.hoisted(() => ({
sendMessage: vi.fn(),
}));
announceDeliveryMocks,
expectDirectMediaSend,
expectFallbackMediaAnnouncement,
expectQueuedTaskRun,
expectRecordedTaskProgress,
resetMediaBackgroundMocks,
taskDeliveryRuntimeMocks,
taskExecutorMocks,
} from "./media-generate-background.test-support.js";
vi.mock("../../tasks/task-executor.js", () => taskExecutorMocks);
vi.mock("../../tasks/task-registry-delivery-runtime.js", () => taskDeliveryRuntimeMocks);
vi.mock("../subagent-announce-delivery.js", () => announceDeliveryMocks);
const {
createMusicGenerationTaskRun,
recordMusicGenerationTaskProgress,
wakeMusicGenerationTaskCompletion,
} = await import("./music-generate-background.js");
describe("music generate background helpers", () => {
beforeEach(() => {
taskExecutorMocks.createRunningTaskRun.mockReset();
taskExecutorMocks.recordTaskRunProgressByRunId.mockReset();
taskDeliveryRuntimeMocks.sendMessage.mockReset();
announceDeliveryMocks.deliverSubagentAnnouncement.mockReset();
resetMediaBackgroundMocks({
taskExecutorMocks,
taskDeliveryRuntimeMocks,
announceDeliveryMocks,
});
});
it("creates a running task with queued progress text", () => {
@@ -52,13 +50,12 @@ describe("music generate background helpers", () => {
requesterSessionKey: "agent:main:discord:direct:123",
taskLabel: "night-drive synthwave",
});
expect(taskExecutorMocks.createRunningTaskRun).toHaveBeenCalledWith(
expect.objectContaining({
taskKind: MUSIC_GENERATION_TASK_KIND,
sourceId: "music_generate:google",
progressSummary: "Queued music generation",
}),
);
expectQueuedTaskRun({
taskExecutorMocks,
taskKind: MUSIC_GENERATION_TASK_KIND,
sourceId: "music_generate:google",
progressSummary: "Queued music generation",
});
});
it("records task progress updates", () => {
@@ -72,12 +69,11 @@ describe("music generate background helpers", () => {
progressSummary: "Saving generated music",
});
expect(taskExecutorMocks.recordTaskRunProgressByRunId).toHaveBeenCalledWith(
expect.objectContaining({
runId: "tool:music_generate:abc",
progressSummary: "Saving generated music",
}),
);
expectRecordedTaskProgress({
taskExecutorMocks,
runId: "tool:music_generate:abc",
progressSummary: "Saving generated music",
});
});
it("queues a completion event by default when direct send is disabled", async () => {
@@ -132,15 +128,14 @@ describe("music generate background helpers", () => {
result: "Generated 1 track.\nMEDIA:/tmp/generated-night-drive.mp3",
});
expect(taskDeliveryRuntimeMocks.sendMessage).toHaveBeenCalledWith(
expect.objectContaining({
channel: "discord",
to: "channel:1",
threadId: "thread-1",
content: "Generated 1 track.",
mediaUrls: ["/tmp/generated-night-drive.mp3"],
}),
);
expectDirectMediaSend({
sendMessageMock: taskDeliveryRuntimeMocks.sendMessage,
channel: "discord",
to: "channel:1",
threadId: "thread-1",
content: "Generated 1 track.",
mediaUrls: ["/tmp/generated-night-drive.mp3"],
});
expect(announceDeliveryMocks.deliverSubagentAnnouncement).not.toHaveBeenCalled();
});
@@ -170,25 +165,15 @@ describe("music generate background helpers", () => {
mediaUrls: ["/tmp/generated-night-drive.mp3"],
});
expect(announceDeliveryMocks.deliverSubagentAnnouncement).toHaveBeenCalledWith(
expect.objectContaining({
requesterSessionKey: "agent:main:discord:direct:123",
requesterOrigin: expect.objectContaining({
channel: "discord",
to: "channel:1",
}),
expectsCompletionMessage: true,
internalEvents: expect.arrayContaining([
expect.objectContaining({
source: "music_generation",
announceType: "music generation task",
status: "ok",
result: expect.stringContaining("MEDIA:/tmp/generated-night-drive.mp3"),
mediaUrls: ["/tmp/generated-night-drive.mp3"],
replyInstruction: expect.stringContaining("Prefer the message tool for delivery"),
}),
]),
}),
);
expectFallbackMediaAnnouncement({
deliverAnnouncementMock: announceDeliveryMocks.deliverSubagentAnnouncement,
requesterSessionKey: "agent:main:discord:direct:123",
channel: "discord",
to: "channel:1",
source: "music_generation",
announceType: "music generation task",
resultMediaPath: "MEDIA:/tmp/generated-night-drive.mp3",
mediaUrls: ["/tmp/generated-night-drive.mp3"],
});
});
});

View File

@@ -1,35 +1,33 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { VIDEO_GENERATION_TASK_KIND } from "../video-generation-task-status.js";
import {
createVideoGenerationTaskRun,
recordVideoGenerationTaskProgress,
wakeVideoGenerationTaskCompletion,
} from "./video-generate-background.js";
const taskExecutorMocks = vi.hoisted(() => ({
createRunningTaskRun: vi.fn(),
recordTaskRunProgressByRunId: vi.fn(),
completeTaskRunByRunId: vi.fn(),
failTaskRunByRunId: vi.fn(),
}));
const announceDeliveryMocks = vi.hoisted(() => ({
deliverSubagentAnnouncement: vi.fn(),
}));
const taskDeliveryRuntimeMocks = vi.hoisted(() => ({
sendMessage: vi.fn(),
}));
announceDeliveryMocks,
expectDirectMediaSend,
expectFallbackMediaAnnouncement,
expectQueuedTaskRun,
expectRecordedTaskProgress,
resetMediaBackgroundMocks,
taskDeliveryRuntimeMocks,
taskExecutorMocks,
} from "./media-generate-background.test-support.js";
vi.mock("../../tasks/task-executor.js", () => taskExecutorMocks);
vi.mock("../../tasks/task-registry-delivery-runtime.js", () => taskDeliveryRuntimeMocks);
vi.mock("../subagent-announce-delivery.js", () => announceDeliveryMocks);
const {
createVideoGenerationTaskRun,
recordVideoGenerationTaskProgress,
wakeVideoGenerationTaskCompletion,
} = await import("./video-generate-background.js");
describe("video generate background helpers", () => {
beforeEach(() => {
taskExecutorMocks.createRunningTaskRun.mockReset();
taskExecutorMocks.recordTaskRunProgressByRunId.mockReset();
taskDeliveryRuntimeMocks.sendMessage.mockReset();
announceDeliveryMocks.deliverSubagentAnnouncement.mockReset();
resetMediaBackgroundMocks({
taskExecutorMocks,
taskDeliveryRuntimeMocks,
announceDeliveryMocks,
});
});
it("creates a running task with queued progress text", () => {
@@ -52,13 +50,12 @@ describe("video generate background helpers", () => {
requesterSessionKey: "agent:main:discord:direct:123",
taskLabel: "friendly lobster surfing",
});
expect(taskExecutorMocks.createRunningTaskRun).toHaveBeenCalledWith(
expect.objectContaining({
taskKind: VIDEO_GENERATION_TASK_KIND,
sourceId: "video_generate:openai",
progressSummary: "Queued video generation",
}),
);
expectQueuedTaskRun({
taskExecutorMocks,
taskKind: VIDEO_GENERATION_TASK_KIND,
sourceId: "video_generate:openai",
progressSummary: "Queued video generation",
});
});
it("records task progress updates", () => {
@@ -72,12 +69,11 @@ describe("video generate background helpers", () => {
progressSummary: "Saving generated video",
});
expect(taskExecutorMocks.recordTaskRunProgressByRunId).toHaveBeenCalledWith(
expect.objectContaining({
runId: "tool:video_generate:abc",
progressSummary: "Saving generated video",
}),
);
expectRecordedTaskProgress({
taskExecutorMocks,
runId: "tool:video_generate:abc",
progressSummary: "Saving generated video",
});
});
it("queues a completion event by default when direct send is disabled", async () => {
@@ -132,15 +128,14 @@ describe("video generate background helpers", () => {
result: "Generated 1 video.\nMEDIA:/tmp/generated-lobster.mp4",
});
expect(taskDeliveryRuntimeMocks.sendMessage).toHaveBeenCalledWith(
expect.objectContaining({
channel: "discord",
to: "channel:1",
threadId: "thread-1",
content: "Generated 1 video.",
mediaUrls: ["/tmp/generated-lobster.mp4"],
}),
);
expectDirectMediaSend({
sendMessageMock: taskDeliveryRuntimeMocks.sendMessage,
channel: "discord",
to: "channel:1",
threadId: "thread-1",
content: "Generated 1 video.",
mediaUrls: ["/tmp/generated-lobster.mp4"],
});
expect(announceDeliveryMocks.deliverSubagentAnnouncement).not.toHaveBeenCalled();
});
@@ -170,25 +165,15 @@ describe("video generate background helpers", () => {
mediaUrls: ["/tmp/generated-lobster.mp4"],
});
expect(announceDeliveryMocks.deliverSubagentAnnouncement).toHaveBeenCalledWith(
expect.objectContaining({
requesterSessionKey: "agent:main:discord:direct:123",
requesterOrigin: expect.objectContaining({
channel: "discord",
to: "channel:1",
}),
expectsCompletionMessage: true,
internalEvents: expect.arrayContaining([
expect.objectContaining({
source: "video_generation",
announceType: "video generation task",
status: "ok",
result: expect.stringContaining("MEDIA:/tmp/generated-lobster.mp4"),
mediaUrls: ["/tmp/generated-lobster.mp4"],
replyInstruction: expect.stringContaining("Prefer the message tool for delivery"),
}),
]),
}),
);
expectFallbackMediaAnnouncement({
deliverAnnouncementMock: announceDeliveryMocks.deliverSubagentAnnouncement,
requesterSessionKey: "agent:main:discord:direct:123",
channel: "discord",
to: "channel:1",
source: "video_generation",
announceType: "video generation task",
resultMediaPath: "MEDIA:/tmp/generated-lobster.mp4",
mediaUrls: ["/tmp/generated-lobster.mp4"],
});
});
});