Files
memind/mindspace-html-download-links.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

110 lines
4.1 KiB
JavaScript

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 { downloadLinkInternals } from './mindspace-html-download-links.mjs';
const {
isRelativeDownloadReference,
resolveWorkspaceRelativeFilePath,
buildWorkspaceDownloadLinkIndex,
resolveDownloadTargetUrl,
rewriteRelativeDownloadLinks,
inferWorkspaceHtmlRelativePath,
} = downloadLinkInternals;
test('isRelativeDownloadReference accepts sibling docx links only', () => {
assert.equal(isRelativeDownloadReference('半导体行业趋势分析报告.docx'), true);
assert.equal(isRelativeDownloadReference('public/report.docx'), true);
assert.equal(isRelativeDownloadReference('/MindSpace/u/public/a.docx'), false);
assert.equal(isRelativeDownloadReference('https://example.com/a.pdf'), false);
assert.equal(isRelativeDownloadReference('#summary'), false);
});
test('resolveWorkspaceRelativeFilePath resolves from public html directory', () => {
assert.equal(
resolveWorkspaceRelativeFilePath('public/index.html', '半导体行业趋势分析报告.docx'),
'public/半导体行业趋势分析报告.docx',
);
assert.equal(
resolveWorkspaceRelativeFilePath('public/report.html', 'assets/data.csv'),
'public/assets/data.csv',
);
});
test('resolveDownloadTargetUrl prefers asset download API in preview mode', () => {
const linkIndex = buildWorkspaceDownloadLinkIndex([
{ id: 'asset-1', original_filename: 'ai-robot-report.docx' },
]);
const url = resolveDownloadTargetUrl({
relativeRef: 'AI机器人研究报告.docx',
htmlRelativePath: 'public/ai-robot-report.html',
linkIndex,
preferAssetDownload: true,
});
assert.equal(url, '/api/mindspace/v1/assets/asset-1/download');
});
test('resolveDownloadTargetUrl falls back to sibling docx beside html page', () => {
const publishDir = fs.mkdtempSync(path.join(os.tmpdir(), 'download-links-'));
const publicDir = path.join(publishDir, 'public');
fs.mkdirSync(publicDir, { recursive: true });
fs.writeFileSync(path.join(publicDir, 'ai-robot-report.html'), '<html></html>');
fs.writeFileSync(path.join(publicDir, 'ai-robot-report.docx'), 'docx');
try {
const url = resolveDownloadTargetUrl({
relativeRef: 'AI机器人研究报告.docx',
htmlRelativePath: 'public/ai-robot-report.html',
publishDir,
publishKey: 'user-1',
publicBaseUrl: 'https://m.tkmind.cn',
preferAssetDownload: false,
});
assert.match(url, /MindSpace\/user-1\/public\/ai-robot-report\.docx$/);
} finally {
fs.rmSync(publishDir, { recursive: true, force: true });
}
});
test('rewriteRelativeDownloadLinks rewrites href and src download attributes', () => {
const html = [
'<a href="半导体行业趋势分析报告.docx" download>下载</a>',
'<a href="#summary">摘要</a>',
].join('');
const linkIndex = buildWorkspaceDownloadLinkIndex([
{ id: 'asset-1', original_filename: '半导体行业趋势分析报告.docx' },
]);
const { html: rewritten, count } = rewriteRelativeDownloadLinks(html, {
htmlRelativePath: 'public/index.html',
linkIndex,
preferAssetDownload: true,
});
assert.equal(count, 1);
assert.match(rewritten, /href="\/api\/mindspace\/v1\/assets\/asset-1\/download"/);
assert.match(rewritten, /href="#summary"/);
});
test('inferWorkspaceHtmlRelativePath matches workspace html by title', () => {
const publishDir = fs.mkdtempSync(path.join(os.tmpdir(), 'infer-html-path-'));
const publicDir = path.join(publishDir, 'public');
fs.mkdirSync(publicDir, { recursive: true });
fs.writeFileSync(
path.join(publicDir, 'ai-robot-report.html'),
'<html><head><title>AI 机器人研究报告 2026</title></head><body></body></html>',
'utf8',
);
try {
assert.equal(
inferWorkspaceHtmlRelativePath({
pageTitle: 'AI 机器人研究报告 2026',
htmlContent: '<html><head><title>AI 机器人研究报告 2026</title></head><body></body></html>',
publishDir,
}),
'public/ai-robot-report.html',
);
} finally {
fs.rmSync(publishDir, { recursive: true, force: true });
}
});