import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it } from "vitest"; import { GenerationError } from "@/components/generation-error"; import { generationErrorMessage, providerErrorDiagnostic } from "@/lib/client/provider-error"; import type { GenerationJob } from "@/lib/types"; function job(overrides: Partial = {}): GenerationJob { return { id: "job-test", ownerId: "user-test", capability: "video.generate", provider: "seedance", reqKey: "doubao-seedance-2-0-260128", status: "failed", inputAssetIds: [], inputUrls: [], outputAssetIds: [], requestPayload: {}, error: { code: "InputImageSensitiveContentDetected.PrivacyInformation", message: "参考图片涉及真人肖像,未通过服务商审核。" }, ...overrides } as GenerationJob; } describe("generation task error presentation", () => { it("shows the actionable reason without diagnostics to ordinary users", () => { const result = renderToStaticMarkup(createElement(GenerationError, { job: job({ responsePayload: { providerError: { status: 400, code: "InputImageSensitiveContentDetected.PrivacyInformation", requestId: "request-secret", detail: "provider-private-detail", phase: "submit" } } }), isAdmin: false, providerName: "Seedance" })); expect(result).toContain("失败原因"); expect(result).toContain("参考图片涉及真人肖像"); expect(result).not.toContain("错误详情"); expect(result).not.toContain("request-secret"); expect(result).not.toContain("provider-private-detail"); }); it("shows only available diagnostic fields to an administrator", () => { const result = renderToStaticMarkup(createElement(GenerationError, { job: job({ responsePayload: { providerError: { status: 400, code: "InputImageSensitiveContentDetected.PrivacyInformation", requestId: "", detail: "已脱敏的服务商说明", phase: "submit" } } }), isAdmin: true, providerName: "Seedance" })); expect(result).toContain("错误详情"); expect(result).toContain("HTTP 状态"); expect(result).toContain("400"); expect(result).toContain("错误码"); expect(result).toContain("已脱敏的服务商说明"); expect(result).not.toContain("请求 ID"); }); it("does not describe a queued retry as a final failure", () => { const result = renderToStaticMarkup(createElement(GenerationError, { job: job({ status: "queued", error: { message: "服务商暂时繁忙,系统稍后重试。" } }), isAdmin: false, providerName: "Seedance" })); expect(result).toContain("任务提示"); expect(result).not.toContain("失败原因"); }); it("translates old unknown-submission records without falsely claiming rejection", () => { const legacy = job({ error: { message: "provider submission outcome is unknown; refusing duplicate submission" }, responsePayload: undefined }); expect(generationErrorMessage(legacy)).toContain("平台已停止自动重试"); expect(generationErrorMessage(legacy)).not.toContain("服务商拒绝"); expect(generationErrorMessage(legacy)).not.toContain("稍后刷新"); }); it("uses a known privacy code for an old task but ignores unrelated payload data", () => { const legacy = job({ error: { code: "InputImageSensitiveContentDetected.PrivacyInformation", message: "provider submission outcome is unknown; refusing duplicate submission" }, responsePayload: { raw: { accessToken: "must-not-appear" } } }); expect(generationErrorMessage(legacy)).toContain("真人肖像"); expect(providerErrorDiagnostic(legacy)).toEqual({ code: "InputImageSensitiveContentDetected.PrivacyInformation" }); }); it("does not infer a privacy review from a code with an extra suffix", () => { const other = job({ error: { code: "InputImageSensitiveContentDetected.PrivacyInformation.Unknown", message: "provider submission outcome is unknown; refusing duplicate submission" } }); expect(generationErrorMessage(other)).toContain("暂时无法确认服务商是否已接收"); expect(generationErrorMessage(other)).not.toContain("真人肖像"); }); });