Files
memind/mindspace-og-tags.test.mjs
T
john 722b18326f feat(mindspace): 0630004 空间 UI、聊天连接、微信分享与 Agent 能力
含 MindSpace 三列布局与统计修复、聊天加载态与连接降级、平台页脚标记与 og:site_name 微信卡片、勾选资料删除 Agent 接口及内部话术过滤。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 18:08:06 +08:00

149 lines
7.2 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
extractSharePreviewMeta,
injectOgTags,
injectWechatShareBridge,
PLATFORM_SITE_NAME,
renderWechatSharePreviewHtml,
} from './mindspace-og-tags.mjs';
const ctx = {
origin: 'https://m.tkmind.cn',
pageUrl: 'https://m.tkmind.cn/MindSpace/john/public/space.html',
pageDirUrl: 'https://m.tkmind.cn/MindSpace/john/public/',
};
test('injects og/twitter tags with absolute image from a relative cover', () => {
const html = `<html><head><title>🚀 太空小勇士 - 闯关大冒险</title>` +
`<meta name="description" content="一起闯关大冒险">` +
`<meta name="mindspace-cover" content='{"tag":"游戏","cover":"assets/hero.jpg"}'></head><body></body></html>`;
const out = injectOgTags(html, ctx);
assert.match(out, /<meta property="og:title" content="🚀 太空小勇士 - 闯关大冒险">/);
assert.match(out, /<meta property="og:description" content="一起闯关大冒险">/);
assert.match(out, /<meta property="og:image" content="https:\/\/m\.tkmind\.cn\/MindSpace\/john\/public\/assets\/hero\.jpg">/);
assert.match(out, /<meta property="og:site_name" content="TKMind 智趣">/);
assert.match(out, /<link rel="icon" type="image\/png" href="https:\/\/m\.tkmind\.cn\/brand\/tkmind-icon\.png">/);
assert.match(out, /<meta name="twitter:card" content="summary_large_image">/);
assert.ok(out.indexOf('og:image') < out.indexOf('</head>'));
});
test('falls back to the thumbnail png when the page has no cover of its own', () => {
const html = `<head><title>纯文字页面</title></head>`;
const out = injectOgTags(html, {
...ctx,
fallbackImageUrl: 'https://m.tkmind.cn/MindSpace/john/public/space.thumbnail.png',
});
assert.match(out, /<meta property="og:image" content="https:\/\/m\.tkmind\.cn\/MindSpace\/john\/public\/space\.thumbnail\.png">/);
assert.match(out, /<meta property="og:site_name" content="TKMind 智趣">/);
assert.match(out, /<meta name="twitter:card" content="summary_large_image">/);
});
test('prefers the page cover over the thumbnail fallback', () => {
const html = `<head><title>X</title><meta name="mindspace-cover" content='{"cover":"assets/hero.jpg"}'></head>`;
const out = injectOgTags(html, { ...ctx, fallbackImageUrl: 'https://m.tkmind.cn/x.thumbnail.png' });
assert.match(out, /og:image" content="https:\/\/m\.tkmind\.cn\/MindSpace\/john\/public\/assets\/hero\.jpg"/);
assert.doesNotMatch(out, /thumbnail\.png/);
});
test('keeps an author-provided og:image and still backfills site_name', () => {
const html = `<head><title>T</title><meta property="og:image" content="https://x/y.png"></head>`;
const out = injectOgTags(html, ctx);
assert.equal((out.match(/og:image/g) ?? []).length, 1);
assert.match(out, /<meta property="og:site_name" content="TKMind 智趣">/);
});
test('skips og:image for svg-only cover, falls back to summary card', () => {
const html = `<head><title>仅SVG</title><meta name="mindspace-cover" content='{"cover":"foo.svg"}'></head>`;
const out = injectOgTags(html, ctx);
assert.doesNotMatch(out, /og:image/);
assert.match(out, /<meta name="twitter:card" content="summary">/);
assert.match(out, /<meta property="og:site_name" content="TKMind 智趣">/);
});
test('passes through a full https cover url unchanged', () => {
const html = `<head><title>X</title><meta name="mindspace-cover" content='{"cover":"https://cdn.example.com/a.png"}'></head>`;
const out = injectOgTags(html, ctx);
assert.match(out, /<meta property="og:image" content="https:\/\/cdn\.example\.com\/a\.png">/);
});
test('resolves a root-absolute cover against the origin', () => {
const html = `<head><title>X</title><meta name="mindspace-cover" content='{"cover":"/shared/cover.jpg"}'></head>`;
const out = injectOgTags(html, ctx);
assert.match(out, /<meta property="og:image" content="https:\/\/m\.tkmind\.cn\/shared\/cover\.jpg">/);
});
test('escapes quotes and ampersands in title to keep the meta tag well-formed', () => {
const html = `<head><title>say "hi" & bye</title></head>`;
const out = injectOgTags(html, ctx);
assert.match(out, /<meta property="og:title" content="say &quot;hi&quot; &amp; bye">/);
});
test('uses meta override for shell pages that only expose a title', () => {
const shell = `<head><title>连云港三天两夜攻略 🌊</title></head>`;
const out = injectOgTags(shell, {
...ctx,
fallbackImageUrl: 'https://m.tkmind.cn/MindSpace/john/public/demo.thumbnail.png',
meta: { subtitle: '三天两夜·沙滩酒店·必吃美食' },
});
assert.match(out, /<meta property="og:description" content="三天两夜·沙滩酒店·必吃美食">/);
assert.match(out, /<meta property="og:site_name" content="TKMind 智趣">/);
});
test('extractSharePreviewMeta returns the card fields used by preview tooling', () => {
const html = injectOgTags(
`<head><title>标题</title><meta name="description" content="描述"></head>`,
ctx,
);
const preview = extractSharePreviewMeta(html, ctx);
assert.equal(preview.title, '标题');
assert.equal(preview.description, '描述');
assert.equal(preview.siteName, PLATFORM_SITE_NAME);
assert.match(preview.iconUrl, /\/brand\/tkmind-icon\.png$/);
});
test('renderWechatSharePreviewHtml includes title, description and site footer', () => {
const html = renderWechatSharePreviewHtml({
title: '连云港三天两夜攻略 🌊',
description: '三天两夜·沙滩酒店·必吃美食',
siteName: PLATFORM_SITE_NAME,
imageUrl: 'https://example.com/cover.png',
iconUrl: '/brand/tkmind-icon.png',
pageUrl: ctx.pageUrl,
});
assert.match(html, /连云港三天两夜攻略/);
assert.match(html, /三天两夜·沙滩酒店·必吃美食/);
assert.match(html, /TKMind 智趣/);
assert.match(html, /example\.com\/cover\.png/);
});
test('injectWechatShareBridge adds WeChat share bootstrap with og-derived metadata', () => {
const html = `<html><head><title>页面标题</title>` +
`<meta property="og:title" content="分享标题">` +
`<meta property="og:description" content="分享描述">` +
`<meta property="og:site_name" content="TKMind 智趣">` +
`<meta property="og:image" content="https://g2.tkmind.cn/hero.png"></head><body></body></html>`;
const out = injectWechatShareBridge(html, {
pageUrl: 'https://m.tkmind.cn/u/john/pages/demo',
});
assert.match(out, /data-tkmind-wechat-share="1"/);
assert.match(out, /fetch\(endpoint \+ '\?url='/);
assert.match(out, /updateAppMessageShareData/);
assert.match(out, /https:\/\/g2\.tkmind\.cn\/hero\.png/);
assert.match(out, /分享标题/);
assert.match(out, /分享描述/);
});
test('injectWechatShareBridge falls back description when og tags are missing', () => {
const html = `<head><title>页面标题</title></head>`;
const out = injectWechatShareBridge(html, { pageUrl: 'https://m.tkmind.cn/u/john/pages/demo' });
assert.match(out, /TKMind 智趣 · 精选作品/);
});
test('injectWechatShareBridge is idempotent', () => {
const html = `<head><title>X</title></head>`;
const first = injectWechatShareBridge(html, { pageUrl: 'https://m.tkmind.cn/u/john/pages/demo' });
const second = injectWechatShareBridge(first, { pageUrl: 'https://m.tkmind.cn/u/john/pages/demo' });
assert.equal((second.match(/data-tkmind-wechat-share="1"/g) ?? []).length, 1);
});