import assert from 'node:assert/strict'; import test from 'node:test'; import { convertDailyNewsHtmlToWechatInlineArticle, wechatDailyNewsInlineInternals, } from './wechat-daily-news-inline.mjs'; const WEATHER_HTML = `

📰 每日新闻早报

要闻

头条

正文

🌤️ 今日天气
📍 北京
☀️ 晴 · 温差大
30°
🌧️ 华南有雨☀️ 华北晴好
中央气象台:未来三天降水减弱。
北京☀️ 晴
30°
上海🌧️ 小雨
26°

数据来源:中央气象台

`; test('splitSections preserves section ids after opening tag split', () => { const sections = wechatDailyNewsInlineInternals.splitSections(WEATHER_HTML); assert.deepEqual(sections.map((item) => item.id), ['headlines', 'weather']); }); test('renderWeatherSection uses tourist city title and two-column city cards', () => { const sections = wechatDailyNewsInlineInternals.splitSections(WEATHER_HTML); const weather = sections.find((item) => item.id === 'weather'); const rendered = wechatDailyNewsInlineInternals.renderWeatherSection(weather.html); assert.match(rendered, /热门旅游城市天气/u); assert.match(rendered, /📍 北京/u); assert.match(rendered, /☀️ 晴 · 温差大/u); assert.match(rendered, /width:50%;box-sizing:border-box/u); assert.match(rendered, /display:inline-block/u); assert.doesNotMatch(rendered, /display:flex/u); assert.match(rendered, /30°/u); assert.match(rendered, /26°/u); assert.doesNotMatch(rendered, /中央气象台/u); assert.doesNotMatch(rendered, /今日天气/u); }); test('renderWeatherSection skips regional fallback cards and national summary', () => { const regionalWeatherHtml = `
🌤️ 今日天气 · 9月16日
📍 全国概况 · 江汉西南阴雨开场
🌧️ 湖北西部局地暴雨
湖北西部🌧️ 暴雨
雨
北京☀️ 晴
30°
上海🌧️ 小雨
26°
`; const rendered = wechatDailyNewsInlineInternals.renderWeatherSection(regionalWeatherHtml); assert.match(rendered, /热门旅游城市天气 · 9月16日/u); assert.match(rendered, /北京/u); assert.match(rendered, /上海/u); assert.doesNotMatch(rendered, /湖北西部/u); assert.doesNotMatch(rendered, /全国概况/u); }); test('renderWeatherSection supports news002 wc/we/wt cards', () => { const news002Weather = `
🌤️ 今日天气 · 9月24日
全国重点城市 · 9月24日
中央气象台预报,广东广西局地大到暴雨
北京
🌤
14/26℃
上海
🌧
22/28℃
`; const rendered = wechatDailyNewsInlineInternals.renderWeatherSection(news002Weather); assert.match(rendered, /北京/u); assert.match(rendered, /14\/26℃/u); assert.match(rendered, /上海/u); assert.match(rendered, /22\/28℃/u); }); test('buildWechatInlineContent renders weather and optional quick links', () => { const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(WEATHER_HTML, { includeFixedLayout: false, trimProfile: { skipHistory: true, skipQuickLinks: false }, }); assert.match(built.content, /🌤️ 天气/u); assert.match(built.content, /📍 北京/u); assert.match(built.content, /30°/u); }); const HISTORY_HTML = `

📰 每日新闻早报

要闻

头条

正文

📜 历史上的今天 · 9月24日
  1. 1949年中国人民政治协商会议第一届全体会议开幕。
  2. 1957年美国小石城中央高中发生种族融合冲突。
  3. 1996年《全面禁止核试验条约》在联合国开放签署。
  4. 2008年神舟七号载人飞船成功发射。
`; test('renderHistorySection renders up to three compact history items', () => { const sections = wechatDailyNewsInlineInternals.splitSections(HISTORY_HTML); const history = sections.find((item) => item.id === 'history'); const rendered = wechatDailyNewsInlineInternals.renderHistorySection(history.html); assert.match(rendered, /历史上的今天 · 9月24日/u); assert.match(rendered, /1949年/u); assert.match(rendered, /1957年/u); assert.match(rendered, /1996年/u); assert.doesNotMatch(rendered, /2008年/u); assert.match(rendered, /中国人民政治协商会议/u); }); test('buildWechatInlineContent includes history snippet by default', () => { const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(HISTORY_HTML, { includeFixedLayout: false, }); assert.match(built.content, /历史上的今天 · 9月24日/u); assert.match(built.content, /1949年/u); assert.doesNotMatch(built.content, /2008年/u); }); test('buildWechatInlineContent can skip history when trimProfile requests it', () => { const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(HISTORY_HTML, { includeFixedLayout: false, trimProfile: { skipHistory: true }, }); assert.doesNotMatch(built.content, /历史上的今天/u); }); test('convertDailyNewsHtmlToWechatInlineArticle keeps weather when trimming', () => { const article = convertDailyNewsHtmlToWechatInlineArticle(WEATHER_HTML, { includeFixedLayout: false, fixedLayoutLength: 1200, }); assert.match(article.content, /📍 北京/u); assert.match(article.content, /30°/u); }); test('trimWechatInlineBodyByRemovingCards drops tail cards instead of hard slicing', () => { const html = `${WEATHER_HTML.slice(0, -24)}
国际

国际一

正文一

国际二

正文二

`; const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(html, { includeFixedLayout: false, }); const beforeCards = wechatDailyNewsInlineInternals.countInlineCards(built.content); const trimmed = wechatDailyNewsInlineInternals.trimWechatInlineBodyByRemovingCards( built.content, built.content.length - 260, { minCards: 1 }, ); const afterCards = wechatDailyNewsInlineInternals.countInlineCards(trimmed); assert.ok(beforeCards >= 3); assert.ok(afterCards < beforeCards); assert.ok(trimmed.length < built.content.length); assert.match(trimmed, /<\/section>\s*$/u); }); test('section list numbering starts at 01 after feature cards', () => { const html = `

每日新闻早报

头条一 · 头条二
今日要闻

头条卡

重点摘要

普通要闻

普通摘要

国际热点

国际一

国际摘要一

`; const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(html, { includeFixedLayout: false, }); assert.match(built.content, /头条卡[\s\S]*?01<\/span> 普通要闻/u); assert.match(built.content, /WORLD[\s\S]*?01<\/span> 国际一/u); assert.doesNotMatch(built.content, /02<\/span> 普通要闻/u); }); test('hero highlights render as a separate readable digest', () => { const digest = wechatDailyNewsInlineInternals.renderTodayDigest( '
平陆运河通航 · 海上火箭发射 · 全球市场聚焦议息
', ); assert.match(digest, /今日导读/u); assert.match(digest, /平陆运河通航
/u); assert.match(digest, /海上火箭发射
/u); }); test('renderHero does not insert the cover image as a large logo', () => { const html = `

每日新闻早报

9月16日
`; const rendered = wechatDailyNewsInlineInternals.renderHero(html, new Map([ ['https://mmbiz.qpic.cn/logo.png', 'https://mmbiz.qpic.cn/logo.png'], ])); assert.match(rendered, /每日新闻早报/u); assert.doesNotMatch(rendered, /
TKMIND DAILY

每日新闻早报

2026年9月21日星期一第 221 期
中美外长再次通话 · 东博会南宁开幕 · Kimi 发布金融方案

国内

🇨🇳
时政

沈阳举行九一八纪念活动

国内正文摘要。

为什么重要:影响当天交通管制。
`; test('news002 lead-card renders as compact left-thumb card in the wechat draft', () => { const rendered = wechatDailyNewsInlineInternals.renderGenericSection( NEWS002_HTML.match(/
[\s\S]*?<\/a>\n<\/div>/)[0], { sectionId: 'headlines', news002Mode: true }, ); assert.match(rendered, /王毅同鲁比奥通电话/u); assert.match(rendered, /中美关系/u, 'lead-card 的 tag 必须保留'); assert.doesNotMatch(rendered, /01<\/span>/u, '头条卡不占列表序号'); assert.doesNotMatch(rendered, /calc\(100% \+ 28px\)/u, 'news002 头条不走全宽 feature 大图'); }); test('news002 card with media block still yields title and body', () => { const rendered = wechatDailyNewsInlineInternals.renderGenericSection( NEWS002_HTML.match(/
[\s\S]*$/)[0], { sectionId: 'domestic', news002Mode: true }, ); assert.match(rendered, /沈阳举行九一八纪念活动/u); assert.match(rendered, /国内正文摘要/u, '.media 在前不应挤掉正文

'); }); test('news002 cards render uploaded source images in the wechat draft', () => { const sourceImage = 'https://news.example/story.jpg'; const wechatImage = 'https://mmbiz.qpic.cn/wechat-story.jpg'; const html = NEWS002_HTML .replace('

📰
', `
头条
`) .replace('
🇨🇳
', `
国内
`); const imageUrlMap = new Map([[sourceImage, wechatImage]]); const lead = wechatDailyNewsInlineInternals.renderGenericSection( html.match(/
[\s\S]*?<\/a>\n<\/div>/)[0], { sectionId: 'headlines', imageUrlMap, news002Mode: true }, ); const domestic = wechatDailyNewsInlineInternals.renderGenericSection( html.match(/
[\s\S]*$/)[0], { sectionId: 'domestic', imageUrlMap, news002Mode: true }, ); assert.match(lead, /mmbiz\.qpic\.cn\/wechat-story\.jpg/u); assert.match(domestic, /mmbiz\.qpic\.cn\/wechat-story\.jpg/u); assert.doesNotMatch(lead, /news\.example\/story\.jpg/u); assert.match(lead, /width:72px;height:54px/u, '配图必须是左上角小图'); assert.doesNotMatch(domestic, /width:100%;height:auto;margin:0 0 9px/u, '列表卡不再用顶部全宽图'); }); test('renderHero reads news002 masthead meta and lede', () => { const rendered = wechatDailyNewsInlineInternals.renderHero(NEWS002_HTML); assert.match(rendered, /每日新闻早报/u); assert.match(rendered, /2026年9月21日/u, 'news002 用 .meta 取代 .date-badge'); assert.match(rendered, /东博会南宁开幕/u, 'news002 用 .lede 取代 .subtitle'); }); test('renderTodayDigest works off the news002 lede', () => { const digest = wechatDailyNewsInlineInternals.renderTodayDigest(NEWS002_HTML); assert.match(digest, /今日导读/u); assert.match(digest, /中美外长再次通话
/u); });