feat(edit): 编辑上报细节优化
This commit is contained in:
@@ -3,7 +3,7 @@ import { test } from 'node:test';
|
||||
import sharp from 'sharp';
|
||||
import { GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { createMediaAiEditRequestSchema } from '@atlas/contracts';
|
||||
import { classifyAiEditFailure, normalizeAiEditOutput, pinnedLookup, providerImageResult, runMediaAiEdit } from '../src/media-ai-edit.ts';
|
||||
import { classifyAiEditFailure, downloadProviderTaskImage, normalizeAiEditOutput, pinnedLookup, providerImageResult, runMediaAiEdit } from '../src/media-ai-edit.ts';
|
||||
import { buildMediaAiPrompt } from '../src/media-ai-prompt.ts';
|
||||
|
||||
const productId = '733d0d73-3d39-4a98-ac0a-5c0e521d8998';
|
||||
@@ -57,7 +57,60 @@ test('固定 DNS 回调按 Node 的 all 选项返回地址列表或单个地址'
|
||||
});
|
||||
});
|
||||
|
||||
test('异步供应商任务分两次 Outbox 推进,并把结果登记为独立素材', async () => {
|
||||
test('同源 Pcore 任务取图使用配置地址,不发送密钥且禁止重定向', async () => {
|
||||
const oldFetch = globalThis.fetch;
|
||||
const oldBase = process.env.PCORE_BASE_URL;
|
||||
const oldKey = process.env.PCORE_API_KEY;
|
||||
process.env.PCORE_BASE_URL = 'https://pcore.ai';
|
||||
process.env.PCORE_API_KEY = 'test-key';
|
||||
let requests = 0;
|
||||
globalThis.fetch = async (url, init) => {
|
||||
requests += 1;
|
||||
assert.equal(url, 'https://pcore.ai/v1/images/content/provider-123/0');
|
||||
assert.equal(init.redirect, 'error');
|
||||
assert.equal(init.headers, undefined);
|
||||
assert.ok(init.signal);
|
||||
return new Response('image');
|
||||
};
|
||||
try {
|
||||
assert.deepEqual(await downloadProviderTaskImage('https://pcore.ai/v1/images/content/provider-123/0', 'provider-123'), Buffer.from('image'));
|
||||
for (const url of [
|
||||
'https://pcore.ai/v1/images/content/another-task/0',
|
||||
'https://pcore.ai/v1/images/content/provider-123/1',
|
||||
'https://pcore.ai/v1/images/content/provider-123%2F0/0',
|
||||
'https://pcore.ai/v1/images/content/provider-123/0?url=http://localhost',
|
||||
'https://pcore.ai/v1/images/content/provider-123/0#fragment',
|
||||
'https://user:password@pcore.ai/v1/images/content/provider-123/0',
|
||||
'https://pcore.ai/v1/images/edits/provider-123',
|
||||
'https://127.0.0.1/v1/images/content/provider-123/0',
|
||||
'http://pcore.ai/v1/images/content/provider-123/0',
|
||||
]) await assert.rejects(downloadProviderTaskImage(url, 'provider-123'), /结果地址不安全/);
|
||||
assert.equal(requests, 1, '非当前任务或非安全地址不能进入供应商内容请求');
|
||||
await assert.rejects(downloadProviderTaskImage('https://pcore.ai/v1/images/content/../0', '..'), /结果地址不安全/);
|
||||
globalThis.fetch = async () => new Response(null, { status: 302, headers: { Location: 'https://127.0.0.1/' } });
|
||||
await assert.rejects(downloadProviderTaskImage('https://pcore.ai/v1/images/content/provider-123/0', 'provider-123'), /HTTP 302/);
|
||||
globalThis.fetch = async () => new Response('oversize', { headers: { 'Content-Length': String(26 * 1024 * 1024) } });
|
||||
await assert.rejects(downloadProviderTaskImage('https://pcore.ai/v1/images/content/provider-123/0', 'provider-123'), /超过处理上限/);
|
||||
globalThis.fetch = async () => new Response(new ReadableStream({ start(controller) {
|
||||
controller.enqueue(new Uint8Array(25 * 1024 * 1024));
|
||||
controller.enqueue(new Uint8Array(1));
|
||||
controller.close();
|
||||
} }));
|
||||
await assert.rejects(downloadProviderTaskImage('https://pcore.ai/v1/images/content/provider-123/0', 'provider-123'), /超过处理上限/);
|
||||
globalThis.fetch = async () => { throw new TypeError('fetch failed'); };
|
||||
await assert.rejects(downloadProviderTaskImage('https://pcore.ai/v1/images/content/provider-123/0', 'provider-123'), (error) => {
|
||||
assert.equal(classifyAiEditFailure(error).source, 'pcore');
|
||||
assert.equal(error.message, 'Pcore 结果下载连接失败');
|
||||
return true;
|
||||
});
|
||||
} finally {
|
||||
globalThis.fetch = oldFetch;
|
||||
if (oldBase === undefined) delete process.env.PCORE_BASE_URL; else process.env.PCORE_BASE_URL = oldBase;
|
||||
if (oldKey === undefined) delete process.env.PCORE_API_KEY; else process.env.PCORE_API_KEY = oldKey;
|
||||
}
|
||||
});
|
||||
|
||||
test('异步供应商任务登记独立素材,完成结果兼容 base64 和同源图片接口', async () => {
|
||||
const sourceId = '664d0d73-3d39-4a98-ac0a-5c0e521d8998';
|
||||
const referenceId = '6ebfe347-bc77-4270-8213-b2021271c6b2';
|
||||
const outputId = '113d0d73-3d39-4a98-ac0a-5c0e521d8998';
|
||||
@@ -101,6 +154,7 @@ test('异步供应商任务分两次 Outbox 推进,并把结果登记为独立
|
||||
process.env.PCORE_BASE_URL = 'https://pcore.ai/v1';
|
||||
process.env.PCORE_API_KEY = 'test-key';
|
||||
let requests = 0;
|
||||
let useContentUrl = false;
|
||||
globalThis.fetch = async (url, init) => {
|
||||
requests += 1;
|
||||
if (init.method === 'POST') {
|
||||
@@ -119,8 +173,15 @@ test('异步供应商任务分两次 Outbox 推进,并把结果登记为独立
|
||||
assert.equal(body.mask, undefined);
|
||||
return Response.json({ task_id: 'provider-123' });
|
||||
}
|
||||
if (url === 'https://pcore.ai/v1/images/content/provider-123/0') {
|
||||
assert.equal(init.headers, undefined);
|
||||
assert.equal(init.redirect, 'error');
|
||||
return new Response(generated);
|
||||
}
|
||||
assert.equal(url, 'https://pcore.ai/v1/images/edits/provider-123');
|
||||
return Response.json({ status: 'completed', data: [{ b64_json: generated.toString('base64') }] });
|
||||
return Response.json({ status: 'completed', data: [useContentUrl
|
||||
? { b64_json: '', url: 'https://pcore.ai/v1/images/content/provider-123/0' }
|
||||
: { b64_json: generated.toString('base64') }] });
|
||||
};
|
||||
try {
|
||||
const job = { workspaceId: '30cf54b7-06a3-4e5f-a5fc-d74165115094', payload: { edit_id: editId } };
|
||||
@@ -133,6 +194,12 @@ test('异步供应商任务分两次 Outbox 推进,并把结果登记为独立
|
||||
assert.equal(stored.length, 1);
|
||||
assert.equal(stored[0].ContentType, 'image/jpeg');
|
||||
assert.equal(requests, 2);
|
||||
task.status = 'running';
|
||||
useContentUrl = true;
|
||||
await runMediaAiEdit(database, storage, job);
|
||||
assert.equal(task.status, 'succeeded');
|
||||
assert.equal(stored.length, 2);
|
||||
assert.equal(requests, 4, '已保存任务只查询状态和取图,不重新提交生成');
|
||||
} finally {
|
||||
globalThis.fetch = oldFetch;
|
||||
if (oldBase === undefined) delete process.env.PCORE_BASE_URL; else process.env.PCORE_BASE_URL = oldBase;
|
||||
|
||||
Reference in New Issue
Block a user