feat: 完成现有小程序接口的全部迁移至新后端
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { test } from 'node:test';
|
||||
import { buildAssetMappings } from '../../../apps/server/scripts/asset-mapping.mjs';
|
||||
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
||||
function fixture() {
|
||||
const sourceRef = 'cloud://legacy.env/assets/previews/math/a.jpg';
|
||||
const asset = {
|
||||
id: 'keep-original-id',
|
||||
sourceRef,
|
||||
sourceRefHash: hash(sourceRef),
|
||||
purpose: 'preview',
|
||||
visibility: 'public',
|
||||
ownerUserId: null,
|
||||
status: 'pending',
|
||||
};
|
||||
const file = {
|
||||
relativePath: 'assets/previews/math/a.jpg',
|
||||
key: 'doodle-assets/assets/previews/math/a.jpg',
|
||||
bucket: 'test-public',
|
||||
visibility: 'public',
|
||||
mimeType: 'image/jpeg',
|
||||
size: 10,
|
||||
sha256: hash('local'),
|
||||
etag: 'etag',
|
||||
status: 'uploaded',
|
||||
verifiedBy: 'qiniu-etag-and-size',
|
||||
};
|
||||
return {
|
||||
asset,
|
||||
file,
|
||||
report: { schemaVersion: 1, mode: 'apply', ok: true, files: [file] },
|
||||
config: { publicBucket: 'test-public', prefix: 'doodle-assets/' },
|
||||
};
|
||||
}
|
||||
|
||||
test('资产回填:保留 ID、完整 key 与原始来源;重复映射幂等', () => {
|
||||
const { asset, file, report, config } = fixture();
|
||||
const [mapped] = buildAssetMappings(report, [asset], config);
|
||||
assert.equal(mapped.asset.id, asset.id);
|
||||
assert.equal(mapped.data.objectKey, file.key);
|
||||
assert.equal(
|
||||
mapped.data.objectRefHash,
|
||||
hash(JSON.stringify(['qiniu', file.bucket, file.key])),
|
||||
);
|
||||
assert.equal(mapped.data.status, 'ready');
|
||||
assert.equal(mapped.unchanged, false);
|
||||
assert.equal(
|
||||
buildAssetMappings(report, [{ ...asset, ...mapped.data }], config)[0]
|
||||
.unchanged,
|
||||
true,
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
buildAssetMappings(
|
||||
report,
|
||||
[{ ...asset, ...mapped.data, objectKey: 'edited-key' }],
|
||||
config,
|
||||
),
|
||||
/READY_ASSET_CONFLICT/,
|
||||
);
|
||||
});
|
||||
|
||||
test('资产回填:预演报告、未核对对象、缺失映射和来源不一致整批拒绝', () => {
|
||||
const { asset, file, report, config } = fixture();
|
||||
assert.throws(
|
||||
() =>
|
||||
buildAssetMappings({ ...report, mode: 'dry-run' }, [asset], config),
|
||||
/INVALID_SYNC_REPORT/,
|
||||
);
|
||||
for (const changed of [
|
||||
{ status: 'planned' },
|
||||
{ bucket: 'another-bucket' },
|
||||
{ key: 'wrong-prefix/a.jpg' },
|
||||
{ verifiedBy: null },
|
||||
{ sha256: 'bad' },
|
||||
])
|
||||
assert.throws(
|
||||
() =>
|
||||
buildAssetMappings(
|
||||
{ ...report, files: [{ ...file, ...changed }] },
|
||||
[asset],
|
||||
config,
|
||||
),
|
||||
/INVALID_REPORT_FILE/,
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
buildAssetMappings(
|
||||
report,
|
||||
[{ ...asset, sourceRefHash: 'bad' }],
|
||||
config,
|
||||
),
|
||||
/INVALID_SOURCE_REFERENCE/,
|
||||
);
|
||||
assert.throws(
|
||||
() => buildAssetMappings({ ...report, files: [] }, [asset], config),
|
||||
/ASSET_MAPPING_MISSING_OR_INELIGIBLE/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user