import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { collectPublicHtmlReferences, findMissingPublicHtmlReferences, isDownloadLikeReference, isFilesystemPublicReference, scanPublicHtmlLinks, } from './mindspace-public-links.mjs'; test('isFilesystemPublicReference skips external and absolute server paths', () => { assert.equal(isFilesystemPublicReference('duck.docx'), true); assert.equal(isFilesystemPublicReference('assets/hero.jpg'), true); assert.equal(isFilesystemPublicReference('https://example.com/a.docx'), false); assert.equal(isFilesystemPublicReference('/api/mindspace/v1/assets/a/download'), false); assert.equal(isFilesystemPublicReference('/MindSpace/u/public/page.html'), false); }); test('isDownloadLikeReference matches download attr and attachment extensions', () => { assert.equal(isDownloadLikeReference('report.docx', 'href="report.docx" download'), true); assert.equal(isDownloadLikeReference('assets/chart.png', 'src="assets/chart.png"'), false); assert.equal(isDownloadLikeReference('data/report.pdf', 'href="data/report.pdf"'), true); }); test('collectPublicHtmlReferences downloads-only ignores api src and cover', () => { const html = ` 下载 chart `; const all = collectPublicHtmlReferences(html, '/tmp/public'); const downloads = collectPublicHtmlReferences(html, '/tmp/public', { downloadsOnly: true }); assert.deepEqual( all.map((item) => item.ref).sort(), ['assets/chart.png', 'assets/hero.jpg', 'report.docx'], ); assert.deepEqual(downloads.map((item) => item.ref), ['report.docx']); }); test('findMissingPublicHtmlReferences reports missing sibling files', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ms-links-')); const htmlPath = path.join(dir, 'report.html'); fs.writeFileSync(htmlPath, '下载'); const missing = findMissingPublicHtmlReferences(htmlPath, null, { downloadsOnly: true }); assert.equal(missing.length, 1); assert.equal(missing[0].ref, 'report.docx'); fs.writeFileSync(path.join(dir, 'report.docx'), 'doc'); assert.deepEqual(findMissingPublicHtmlReferences(htmlPath, null, { downloadsOnly: true }), []); }); test('normalizeReferencePath decodes percent-encoded filenames', () => { const html = 'x'; const refs = collectPublicHtmlReferences(html, '/tmp/public', { downloadsOnly: true }); assert.equal(refs[0]?.ref, '养猪.docx'); }); test('scanPublicHtmlLinks walks MindSpace user public html files', () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ms-root-')); const publicDir = path.join(root, 'user-a', 'public'); fs.mkdirSync(publicDir, { recursive: true }); fs.writeFileSync(path.join(publicDir, 'page.html'), 'pdf'); const issues = scanPublicHtmlLinks(root, { downloadsOnly: true }); assert.equal(issues.length, 1); assert.match(issues[0].htmlPath, /page\.html$/); assert.equal(issues[0].ref, 'missing.pdf'); });