import assert from 'node:assert/strict'; import { test } from 'node:test'; import { publicObjectUrl, publicResourceUrl, } from '../src/content/public-resource-url'; import { previewUrl, type PreviewAssetRow } from '../src/content/preview-url'; const config = { qiniuPublicDomain: 'https://cdn.joeyone.cn', qiniuKeyPrefix: 'doodle-assets/', }; test('公开资源:字体相对路径与完整对象 key 生成相同地址,中文按段编码', () => { const path = 'assets/fonts/ToneOZ-Pinyin-Regular.ttf'; const expected = 'https://cdn.joeyone.cn/doodle-assets/assets/fonts/ToneOZ-Pinyin-Regular.ttf'; assert.equal(publicResourceUrl(config, path), expected); assert.equal( publicObjectUrl(config.qiniuPublicDomain, `doodle-assets/${path}`), expected, ); assert.equal( publicResourceUrl({ ...config, qiniuKeyPrefix: '' }, path), `${config.qiniuPublicDomain}/${path}`, ); assert.equal( publicResourceUrl(config, 'user-avatars/中文 图.png'), `${config.qiniuPublicDomain}/doodle-assets/user-avatars/${encodeURIComponent('中文 图.png')}`, ); for (const path of [ '', '/absolute', '../escape', 'a/../b', 'a//b', 'a\\b', 'a\n', 'a/', ]) { assert.equal(publicResourceUrl(config, path), null); assert.equal(publicObjectUrl(config.qiniuPublicDomain, path), null); } assert.equal( publicResourceUrl({ ...config, qiniuPublicDomain: null }, path), null, ); }); test('预览图:完整 key 不重复加前缀,pending 或 private 资产仍留空', () => { const row: PreviewAssetRow = { assetStatus: 'ready', assetVisibility: 'public', assetPurpose: 'preview', assetOwnerId: null, assetProvider: 'qiniu', assetKey: 'doodle-assets/assets/previews/math/example.jpg', assetExternalUrl: null, assetMimeType: 'image/jpeg', }; assert.equal( previewUrl(row, config.qiniuPublicDomain), `${config.qiniuPublicDomain}/${row.assetKey}`, ); assert.equal( previewUrl( { ...row, assetStatus: 'pending' }, config.qiniuPublicDomain, ), null, ); assert.equal( previewUrl( { ...row, assetVisibility: 'private' }, config.qiniuPublicDomain, ), null, ); });