fix: recover WeChat page thumbnail delivery
Memind CI / Test, build, and release guards (pull_request) Successful in 5m1s

This commit is contained in:
john
2026-07-22 11:51:15 +08:00
parent 57d2c14fca
commit cb62b36cd5
13 changed files with 366 additions and 26 deletions
@@ -6,12 +6,14 @@ import test from 'node:test';
import {
collectWechatGeneratedImages,
extractMindspaceCoverPath,
repairUnambiguousFreshWechatPageThumbnail,
verifyFreshWechatPageThumbnails,
} from './generated-thumbnail.mjs';
function generatedImageMessages({ jobId = 'job-1', htmlSrc = 'images/fresh.webp' } = {}) {
const result = {
ok: true,
purpose: 'hero',
jobId,
source: { mimeType: 'image/webp' },
asset: {
@@ -115,3 +117,60 @@ test('auxiliary admin pages do not require a separate generated thumbnail', () =
fs.rmSync(root, { recursive: true, force: true });
}
});
test('one current-run hero repairs one page from the current write snapshot and re-verifies', () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-repair-cover-'));
try {
const htmlPath = path.join(root, 'page.html');
const diskHtml = '<html><head><meta name="mindspace-cover" content=\'{"tag":"页面","subtitle":"磁盘旧副本"}\'></head><body>disk copy</body></html>';
const currentRunHtml = '<html><head><meta name="mindspace-cover" content=\'{"tag":"页面","subtitle":"本轮副本"}\'></head><body>current run copy</body></html>';
fs.writeFileSync(htmlPath, diskHtml, 'utf8');
const artifacts = [{ localPath: htmlPath, relativePath: 'public/page.html' }];
const images = collectWechatGeneratedImages(generatedImageMessages());
const failed = verifyFreshWechatPageThumbnails(artifacts, images);
assert.equal(failed.reason, 'missing_generated_cover');
const repaired = repairUnambiguousFreshWechatPageThumbnail({
artifacts,
images,
currentRunHtmlArtifacts: [{ relativePath: 'public/page.html', content: currentRunHtml }],
verificationReason: failed.reason,
});
assert.equal(repaired.ok, true);
assert.equal(repaired.restoredCurrentRunHtml, true);
const written = fs.readFileSync(htmlPath, 'utf8');
assert.match(written, /current run copy/);
assert.doesNotMatch(written, /disk copy/);
assert.equal(extractMindspaceCoverPath(written), 'images/fresh.webp');
assert.equal(verifyFreshWechatPageThumbnails(artifacts, images).ok, true);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test('thumbnail repair refuses an ambiguous page-to-image mapping without changing the page', () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-ambiguous-repair-'));
try {
const htmlPath = path.join(root, 'page.html');
const original = '<meta name="mindspace-cover" content=\'{"tag":"页面"}\'>';
fs.writeFileSync(htmlPath, original, 'utf8');
const artifacts = [{ localPath: htmlPath, relativePath: 'public/page.html' }];
const images = collectWechatGeneratedImages([
...generatedImageMessages({ jobId: 'job-1', htmlSrc: 'images/one.webp' }),
...generatedImageMessages({ jobId: 'job-2', htmlSrc: 'images/two.webp' }),
]);
const repaired = repairUnambiguousFreshWechatPageThumbnail({
artifacts,
images,
verificationReason: 'missing_generated_cover',
});
assert.equal(repaired.ok, false);
assert.equal(repaired.reason, 'ambiguous_page_image_mapping');
assert.equal(fs.readFileSync(htmlPath, 'utf8'), original);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});