import type { VideoGenerationResult } from "openclaw/plugin-sdk/video-generation"; import { expect, vi } from "vitest"; type ClearableMock = { mockClear(): unknown; }; type ResettableMock = { mockReset(): unknown; }; type ResolvableMock = { mockResolvedValue(value: unknown): unknown; }; type ChainableResolvedValueMock = ResettableMock & { mockResolvedValueOnce(value: unknown): ChainableResolvedValueMock; }; export type DashscopeVideoProviderMocks = { resolveApiKeyForProviderMock: ClearableMock; postJsonRequestMock: ResettableMock & ResolvableMock; fetchWithTimeoutMock: ChainableResolvedValueMock; assertOkOrThrowHttpErrorMock: ClearableMock; resolveProviderHttpRequestConfigMock: ClearableMock; }; export function resetDashscopeVideoProviderMocks(mocks: DashscopeVideoProviderMocks): void { mocks.resolveApiKeyForProviderMock.mockClear(); mocks.postJsonRequestMock.mockReset(); mocks.fetchWithTimeoutMock.mockReset(); mocks.assertOkOrThrowHttpErrorMock.mockClear(); mocks.resolveProviderHttpRequestConfigMock.mockClear(); } export function mockSuccessfulDashscopeVideoTask( mocks: Pick, params: { requestId?: string; taskId?: string; taskStatus?: string; videoUrl?: string; } = {}, ): void { const { requestId = "req-1", taskId = "task-1", taskStatus = "SUCCEEDED", videoUrl = "https://example.com/out.mp4", } = params; mocks.postJsonRequestMock.mockResolvedValue({ response: { json: async () => ({ request_id: requestId, output: { task_id: taskId, }, }), }, release: vi.fn(async () => {}), }); mocks.fetchWithTimeoutMock .mockResolvedValueOnce({ json: async () => ({ output: { task_status: taskStatus, results: [{ video_url: videoUrl }], }, }), headers: new Headers(), }) .mockResolvedValueOnce({ arrayBuffer: async () => Buffer.from("mp4-bytes"), headers: new Headers({ "content-type": "video/mp4" }), }); } export function expectDashscopeVideoTaskPoll( fetchWithTimeoutMock: ChainableResolvedValueMock, params: { baseUrl?: string; taskId?: string; timeoutMs?: number; } = {}, ): void { const { baseUrl = "https://dashscope-intl.aliyuncs.com", taskId = "task-1", timeoutMs = 120_000, } = params; expect(fetchWithTimeoutMock).toHaveBeenNthCalledWith( 1, `${baseUrl}/api/v1/tasks/${taskId}`, expect.objectContaining({ method: "GET" }), timeoutMs, fetch, ); } export function expectSuccessfulDashscopeVideoResult( result: VideoGenerationResult, params: { requestId?: string; taskId?: string; taskStatus?: string; } = {}, ): void { const { requestId = "req-1", taskId = "task-1", taskStatus = "SUCCEEDED" } = params; expect(result.videos).toHaveLength(1); expect(result.videos[0]?.mimeType).toBe("video/mp4"); expect(result.metadata).toEqual( expect.objectContaining({ requestId, taskId, taskStatus, }), ); }