feat(edit): 优化图片导入ozon问题
This commit is contained in:
@@ -45,7 +45,7 @@ async function request(
|
||||
});
|
||||
return { status: res.status, body: (await res.json()) as any };
|
||||
}
|
||||
async function fixture(count = 2) {
|
||||
async function fixture(count = 2, mediaCount = 1) {
|
||||
const created = await request(
|
||||
'/collection-items',
|
||||
'POST',
|
||||
@@ -106,16 +106,18 @@ async function fixture(count = 2) {
|
||||
[profile, `TEST-${randomUUID()}`, quote, variant],
|
||||
)
|
||||
).rows[0].id;
|
||||
const asset = (
|
||||
await tx.query<{ id: string }>(
|
||||
`INSERT INTO atlas.media_assets(workspace_id,storage_provider,bucket,object_key,content_type,byte_size,checksum_sha256) VALUES($1,'qiniu_kodo','test-bucket',$2,'image/png',100,$3) RETURNING id`,
|
||||
[workspace, randomUUID(), randomUUID()],
|
||||
)
|
||||
).rows[0].id;
|
||||
await tx.query(
|
||||
`INSERT INTO atlas.product_variant_listing_media(workspace_id,product_id,profile_id,listing_id,product_variant_id,asset_id,sort_order) VALUES($1,$2,$3,$4,$5,$6,0)`,
|
||||
[workspace, product, profile, listing, variant, asset],
|
||||
);
|
||||
for (let mediaIndex = 0; mediaIndex < mediaCount; mediaIndex++) {
|
||||
const asset = (
|
||||
await tx.query<{ id: string }>(
|
||||
`INSERT INTO atlas.media_assets(workspace_id,storage_provider,bucket,object_key,content_type,byte_size,checksum_sha256) VALUES($1,'qiniu_kodo','test-bucket',$2,'image/png',100,$3) RETURNING id`,
|
||||
[workspace, randomUUID(), randomUUID()],
|
||||
)
|
||||
).rows[0].id;
|
||||
await tx.query(
|
||||
`INSERT INTO atlas.product_variant_listing_media(workspace_id,product_id,profile_id,listing_id,product_variant_id,asset_id,sort_order) VALUES($1,$2,$3,$4,$5,$6,$7)`,
|
||||
[workspace, product, profile, listing, variant, asset, mediaIndex],
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
return { profile, product, ids };
|
||||
@@ -666,7 +668,9 @@ describe('首次发布 HTTP / 数据库 / Worker 闭环', () => {
|
||||
});
|
||||
assert.equal(job.items[0].status, 'polling');
|
||||
const offers = job.items.map((i) => i.offer_id);
|
||||
job = await run(job, async () => ({
|
||||
job = await run(job, async (_c, _k, path) => path === '/v2/product/pictures/info' ? ({
|
||||
items: [{ product_id: 101, primary_photo: ['https://images.example.test/fixture.png'], photo: [], errors: [] }],
|
||||
}) : ({
|
||||
result: {
|
||||
items: [
|
||||
{
|
||||
@@ -735,12 +739,70 @@ describe('首次发布 HTTP / 数据库 / Worker 闭环', () => {
|
||||
});
|
||||
assert.equal(job.status, 'reconciling');
|
||||
assert.equal(imports, 1);
|
||||
job = await run(job, async () => ({
|
||||
items: [{ offer_id: job.items[0].offer_id, id: 999 }],
|
||||
job = await run(job, async (_c, _k, path) => ({
|
||||
items: path === '/v2/product/pictures/info'
|
||||
? [{ product_id: 999, primary_photo: ['https://images.example.test/fixture.png'], photo: [], errors: [] }]
|
||||
: [{ offer_id: job.items[0].offer_id, id: 999 }],
|
||||
}));
|
||||
assert.equal(job.status, 'succeeded');
|
||||
assert.equal(imports, 1);
|
||||
});
|
||||
it('导入成功后等待图片结果,缺图警告保留到 HTTP 结果与 SKU,并且不重复导入', async () => {
|
||||
const f = await fixture(1, 3);
|
||||
let job = (await publish(f)).body.data.publish_job as ProductPublishJob;
|
||||
let imports = 0;
|
||||
job = await run(job, async (_c, _k, path) => {
|
||||
if (path === '/v3/product/info/list') return { items: [] };
|
||||
assert.equal(path, '/v3/product/import');
|
||||
imports++;
|
||||
return { result: { task_id: 456 } };
|
||||
});
|
||||
const imported = { result: { items: [{ offer_id: job.items[0].offer_id, product_id: 102,
|
||||
status: 'imported', errors: [] }] } };
|
||||
job = await run(job, async (_c, _k, path) => path === '/v1/product/import/info' ? imported
|
||||
: { items: [{ product_id: 102, primary_photo: [], photo: [], errors: [] }] });
|
||||
assert.equal(job.status, 'running');
|
||||
assert.equal(job.items[0].status, 'polling');
|
||||
job = await run(job, async (_c, _k, path) => path === '/v1/product/import/info' ? {
|
||||
result: { items: [{ ...imported.result.items[0], errors: [{ code: 'primary_image_load_failed',
|
||||
message: 'https://private.example.test/primary.png?token=hidden' }] }] },
|
||||
} : { items: [{ product_id: 102, primary_photo: ['https://images.example.test/second.png'], photo: [],
|
||||
errors: [{ url: 'https://private.example.test/primary.png?token=hidden', message: 'request process failed: unknown error host unreachable' },
|
||||
{ url: 'https://private.example.test/third.png?token=hidden', message: 'failed https://private.example.test/third.png?token=hidden' }] }] });
|
||||
assert.equal(job.status, 'succeeded');
|
||||
assert.equal(job.items[0].status, 'imported');
|
||||
assert.equal(job.items[0].platform_product_id, '102');
|
||||
assert.ok(job.items[0].errors.some((error) => error.code === 'OZON_IMAGES_INCOMPLETE' && error.message.includes('1/3')));
|
||||
assert.ok(job.items[0].errors.some((error) => error.code === 'primary_image_load_failed'));
|
||||
assert.ok(job.items[0].errors.some((error) => error.message.includes('全球加速')));
|
||||
assert.ok(!JSON.stringify(job).includes('token='));
|
||||
assert.ok(!JSON.stringify(job).includes('private.example.test'));
|
||||
const listing = (await db.workspaceTransaction(workspace, tx => tx.query(
|
||||
'SELECT status,last_error FROM atlas.product_variant_platform_listings WHERE profile_id=$1', [f.profile],
|
||||
))).rows[0];
|
||||
assert.equal(listing.status, 'imported');
|
||||
assert.deepEqual(listing.last_error, job.items[0].errors);
|
||||
await run(job, async () => { imports++; throw new Error('终态不得重复上报'); });
|
||||
assert.equal(imports, 1);
|
||||
});
|
||||
it('图片全部到齐才报告无警告成功,长时间未齐时以已导入并提示缺图结束', async () => {
|
||||
for (const completePictures of [true, false]) {
|
||||
const f = await fixture(1, 3);
|
||||
let job = (await publish(f)).body.data.publish_job as ProductPublishJob;
|
||||
job = await run(job, async (_c, _k, path) => path === '/v3/product/info/list'
|
||||
? { items: [] } : { result: { task_id: 457 } });
|
||||
if (!completePictures) await db.workspaceTransaction(workspace, tx => tx.query(
|
||||
'UPDATE atlas.product_publish_jobs SET poll_count=121 WHERE id=$1', [job.id],
|
||||
));
|
||||
job = await run(job, async (_c, _k, path) => path === '/v1/product/import/info'
|
||||
? { result: { items: [{ offer_id: job.items[0].offer_id, product_id: 103, status: 'imported', errors: [] }] } }
|
||||
: { items: [{ product_id: 103, primary_photo: completePictures ? ['https://images.example.test/1.png'] : [],
|
||||
photo: completePictures ? ['https://images.example.test/2.png', 'https://images.example.test/3.png'] : [], errors: [] }] });
|
||||
assert.equal(job.status, 'succeeded');
|
||||
assert.equal(job.items[0].status, 'imported');
|
||||
assert.equal(job.items[0].errors.length, completePictures ? 0 : 1);
|
||||
}
|
||||
});
|
||||
it('任一图片准备失败时整批不提交,并隐藏存储路径', async () => {
|
||||
const f = await fixture(2);
|
||||
const created = (await publish(f)).body.data
|
||||
|
||||
Reference in New Issue
Block a user