100 lines
4.3 KiB
TypeScript
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("真人肖像");
|
|
});
|
|
});
|