Files
miaojingAI/scripts/test-custom-image-fallback.mjs

96 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
const {
parseCustomApiError,
} = await import('../src/lib/custom-api-fetch.ts');
const {
buildSynchronousImageRequestBody,
getSystemPollingFailureMessage,
shouldRetryImageRequestWithoutStream,
STREAM_UNSUPPORTED_SYNC_CONFIRM_PREFIX,
} = await import('../src/lib/custom-image-fallback.ts');
const repoRoot = path.resolve(import.meta.dirname, '..');
async function runTest(name, fn) {
try {
await fn();
console.log(`PASS ${name}`);
} catch (error) {
console.error(`FAIL ${name}`);
console.error(error);
process.exitCode = 1;
}
}
function read(relativePath) {
return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8');
}
await runTest('detects stream timeout confirmation errors for synchronous fallback', () => {
assert.equal(
shouldRetryImageRequestWithoutStream(
{ model: 'gpt-image-2', prompt: 'test', stream: true },
`${STREAM_UNSUPPORTED_SYNC_CONFIRM_PREFIX}上游流式生图没有持续返回数据`,
),
true,
);
assert.equal(
shouldRetryImageRequestWithoutStream(
{ model: 'gpt-image-2', prompt: 'test', stream: false },
`${STREAM_UNSUPPORTED_SYNC_CONFIRM_PREFIX}上游流式生图没有持续返回数据`,
),
false,
);
});
await runTest('builds a synchronous retry body without mutating the original request', () => {
const original = { model: 'gpt-image-2', prompt: 'test', n: 1, stream: true };
const next = buildSynchronousImageRequestBody(original);
assert.deepEqual(next, { model: 'gpt-image-2', prompt: 'test', n: 1, stream: false });
assert.equal(original.stream, true);
});
await runTest('system polling exposes actionable upstream errors instead of generic busy message', () => {
assert.equal(
getSystemPollingFailureMessage('上游 API 同步生图请求超时Cloudflare 524。请降低分辨率后重试。'),
'上游 API 同步生图请求超时Cloudflare 524。请降低分辨率后重试。',
);
assert.equal(
getSystemPollingFailureMessage(`${STREAM_UNSUPPORTED_SYNC_CONFIRM_PREFIX}上游流式生图没有持续返回数据`),
'上游流式生图没有持续返回数据',
);
assert.equal(
getSystemPollingFailureMessage(''),
'因使用人数较多,模型繁忙,请稍后再试',
);
});
await runTest('Cloudflare gateway errors are shown as concise retryable upstream messages', () => {
const message = parseCustomApiError(502, '<!DOCTYPE html><title>mozhevip.top | 502: Bad gateway</title>');
assert.equal(message.includes('<!DOCTYPE html>'), false);
assert.match(message, /上游网关/);
assert.match(message, /502/);
});
await runTest('text-to-image custom fetch enables one retry for 502 503 504 gateway failures', () => {
const source = read('src/app/api/generate/image/route.ts');
assert.match(
source,
/fetchWithRetry\(\s*endpoint,\s*\{ method: 'POST', headers: buildCustomApiHeaders\(apiKey\), body: JSON\.stringify\(requestBody\) \},\s*GENERATION_TIMEOUT,\s*1,\s*\)/s,
);
});
await runTest('multimodal 524 errors do not reuse image-generation timeout wording', () => {
const message = parseCustomApiError(524, '<!DOCTYPE html><title>mozhevip.top | 524: A timeout occurred</title>', 'multimodal');
assert.match(message, /多模态模型同步请求超时/);
assert.equal(message.includes('生图请求超时'), false);
});
if (process.exitCode) process.exit(process.exitCode);