Files
NianAIGC/tests/generation-error.test.ts
T
2026-10-02 19:56:32 +08:00

100 lines
4.3 KiB
TypeScript

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> = {}): 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("真人肖像");
});
});