137 lines
5.2 KiB
JavaScript
137 lines
5.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import { test } from 'node:test';
|
|
import vm from 'node:vm';
|
|
import ts from 'typescript';
|
|
import {
|
|
assetConfig,
|
|
resolvePreviewUrl,
|
|
normalizePreviewImages,
|
|
} from '../miniprogram/config/assets.ts';
|
|
|
|
const legacyRoot =
|
|
'cloud://cloud1-9gifs7a2756e2c87.636c-cloud1-9gifs7a2756e2c87-1351593184/';
|
|
const preview = 'assets/previews/math/number-find.jpg';
|
|
const expected = `https://cdn.joeyone.cn/doodle-assets/${preview}`;
|
|
|
|
test('预览图:旧 fileID 和云存储临时链接映射到统一七牛配置', () => {
|
|
assert.equal(resolvePreviewUrl(`${legacyRoot}${preview}`), expected);
|
|
assert.equal(
|
|
resolvePreviewUrl(
|
|
`https://636c-cloud1-9gifs7a2756e2c87-1351593184.tcb.qcloud.la/${preview}?sign=old&t=123`,
|
|
),
|
|
expected,
|
|
);
|
|
assert.equal(resolvePreviewUrl(expected), expected);
|
|
const previous = { ...assetConfig };
|
|
try {
|
|
assetConfig.publicDomain = 'https://assets.example.test';
|
|
assetConfig.keyPrefix = 'next/';
|
|
assert.equal(
|
|
resolvePreviewUrl(`${legacyRoot}${preview}`),
|
|
`https://assets.example.test/next/${preview}`,
|
|
);
|
|
} finally {
|
|
Object.assign(assetConfig, previous);
|
|
}
|
|
});
|
|
|
|
test('预览图:外部地址、本地图片和头像不替换,畸形预览不产生 CDN 请求', () => {
|
|
for (const raw of [
|
|
'/assets/local.png',
|
|
'https://elsewhere.test/assets/previews/a.jpg',
|
|
'https://636c-cloud1-9gifs7a2756e2c87-1351593184.tcb.qcloud.la.evil.test/assets/previews/a.jpg',
|
|
`${legacyRoot}user-avatars/u.png`,
|
|
'cloud://another-env/assets/previews/a.jpg',
|
|
'',
|
|
])
|
|
assert.equal(resolvePreviewUrl(raw), raw);
|
|
for (const raw of [
|
|
`${legacyRoot}assets/previews/../private.jpg`,
|
|
`${legacyRoot}assets/previews/%2e%2e/private.jpg`,
|
|
`${legacyRoot}assets/previews/%broken.jpg`,
|
|
])
|
|
assert.equal(resolvePreviewUrl(raw), '');
|
|
assert.equal(resolvePreviewUrl(null), '');
|
|
});
|
|
|
|
test('预览图:嵌套首页分区、收藏及下载记录转换且不修改原数据', () => {
|
|
const raw = {
|
|
home: {
|
|
featured: [{ previewImg: `${legacyRoot}${preview}` }],
|
|
sections: [{ items: [{ previewImg: `${legacyRoot}${preview}` }] }],
|
|
},
|
|
records: [{ worksheet: { previewImg: `${legacyRoot}${preview}` } }],
|
|
avatarUrl: `${legacyRoot}user-avatars/u.png`,
|
|
};
|
|
const converted = normalizePreviewImages(raw);
|
|
assert.equal(converted.home.featured[0].previewImg, expected);
|
|
assert.equal(converted.home.sections[0].items[0].previewImg, expected);
|
|
assert.equal(converted.records[0].worksheet.previewImg, expected);
|
|
assert.equal(raw.home.featured[0].previewImg, `${legacyRoot}${preview}`);
|
|
assert.equal(converted.avatarUrl, raw.avatarUrl);
|
|
});
|
|
|
|
test('首页配置:预拉取、旧 storage 缓存及新后端兜底均写回七牛预览图', async () => {
|
|
const source = readFileSync(
|
|
new URL('../miniprogram/app.ts', import.meta.url),
|
|
'utf8',
|
|
);
|
|
const code = ts.transpileModule(source, {
|
|
compilerOptions: {
|
|
module: ts.ModuleKind.CommonJS,
|
|
target: ts.ScriptTarget.ES2020,
|
|
},
|
|
}).outputText;
|
|
for (const entry of ['prefetch', 'storage', 'backend']) {
|
|
const old = {
|
|
home: { featured: [{ previewImg: `${legacyRoot}${preview}` }] },
|
|
};
|
|
let app;
|
|
let stored;
|
|
const sandbox = {
|
|
exports: {},
|
|
getCurrentPages: () => [],
|
|
require(name) {
|
|
if (name === './services/site-api')
|
|
return { fetchPageConfig: async () => old };
|
|
if (name === './config/api')
|
|
return {
|
|
getApiConfig: () => ({ version: 'release' }),
|
|
apiContextKey: () => 'test-production',
|
|
isCurrentApiConfig: () => true,
|
|
};
|
|
if (name === './config/assets')
|
|
return { normalizePreviewImages };
|
|
return {};
|
|
},
|
|
App(definition) {
|
|
app = definition;
|
|
},
|
|
wx: {
|
|
getBackgroundFetchData({ success, fail }) {
|
|
if (entry === 'prefetch')
|
|
success({ fetchedData: JSON.stringify({ data: old }) });
|
|
else fail(new Error('not available'));
|
|
},
|
|
getStorageSync() {
|
|
return entry === 'storage' ? old : null;
|
|
},
|
|
setStorageSync(key, value) {
|
|
assert.equal(key, 'doodle_page_config_v2:test-production');
|
|
stored = value;
|
|
},
|
|
},
|
|
};
|
|
vm.runInNewContext(code, sandbox);
|
|
const waiting = app.getPageConfig();
|
|
await app.loadPageConfig();
|
|
assert.equal((await waiting).home.featured[0].previewImg, expected);
|
|
assert.equal(
|
|
app.globalData.pageConfig.home.featured[0].previewImg,
|
|
expected,
|
|
);
|
|
assert.equal(stored.home.featured[0].previewImg, expected);
|
|
}
|
|
});
|