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'), ''); 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 = [ '下载', '摘要', ].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'), '