import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { buildAllowedPageImageEmbedKeys, extractHtmlImageSourceKeys, materializeWechatPublicImageForEmbed, verifyHtmlImageSourcesAllowed, } from './chat-image-materialize.mjs'; test('materializeWechatPublicImageForEmbed copies wechat-mp images into public/images date dir', (t) => { const publishDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chat-image-materialize-')); t.after(() => fs.rmSync(publishDir, { recursive: true, force: true })); const sourceRel = 'public/wechat-mp/sample-photo.jpg'; const sourceAbs = path.join(publishDir, sourceRel); fs.mkdirSync(path.dirname(sourceAbs), { recursive: true }); fs.writeFileSync(sourceAbs, Buffer.from('fresh-image-bytes')); const result = materializeWechatPublicImageForEmbed({ publishDir, rawUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/wechat-mp/sample-photo.jpg', now: new Date('2026-08-27T04:00:00.000Z'), }); assert.ok(result?.materialized); assert.match(result.relativeEmbedPath, /^images\/2026-08-27\/[a-f0-9]{8}-sample-photo\.jpg$/); assert.equal(fs.existsSync(path.join(publishDir, result.publicRelativePath)), true); }); test('verifyHtmlImageSourcesAllowed rejects stale workspace images for the current turn', () => { const publishDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chat-image-verify-')); const sourceAbs = path.join(publishDir, 'public/wechat-mp/new.jpg'); fs.mkdirSync(path.dirname(sourceAbs), { recursive: true }); fs.writeFileSync(sourceAbs, Buffer.from('new-turn-image')); const allowed = buildAllowedPageImageEmbedKeys({ publishDir, imageUrls: ['https://m.tkmind.cn/MindSpace/user-1/public/wechat-mp/new.jpg'], }); const html = [ '', 'old', '', ].join(''); const verification = verifyHtmlImageSourcesAllowed(html, allowed); assert.equal(verification.ok, false); assert.equal(verification.reason, 'stale_image_source'); fs.rmSync(publishDir, { recursive: true, force: true }); }); test('verifyHtmlImageSourcesAllowed accepts materialized current-turn image paths', () => { const publishDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chat-image-verify-ok-')); const sourceAbs = path.join(publishDir, 'public/wechat-mp/new.jpg'); fs.mkdirSync(path.dirname(sourceAbs), { recursive: true }); fs.writeFileSync(sourceAbs, Buffer.from('new-turn-image')); const materialized = materializeWechatPublicImageForEmbed({ publishDir, rawUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/wechat-mp/new.jpg', now: new Date('2026-08-27T04:00:00.000Z'), }); const allowed = buildAllowedPageImageEmbedKeys({ publishDir, imageUrls: ['https://m.tkmind.cn/MindSpace/user-1/public/wechat-mp/new.jpg'], }); const html = `new`; const keys = extractHtmlImageSourceKeys(html); assert.equal(verifyHtmlImageSourcesAllowed(html, allowed).ok, true); assert.ok(keys.size > 0); fs.rmSync(publishDir, { recursive: true, force: true }); });