Files
doodle-store/packages/asset-sync/test/asset-mapping.test.mjs
T

101 lines
3.2 KiB
JavaScript

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/,
);
});