import { describe, expect, it } from 'vitest'; import { validateHtmlArtifact } from '../../src/artifacts/validate'; describe('validateHtmlArtifact', () => { it('rejects an empty string', () => { const result = validateHtmlArtifact(''); expect(result.ok).toBe(false); if (!result.ok) expect(result.reason).toMatch(/empty/i); }); it('rejects whitespace-only content', () => { const result = validateHtmlArtifact(' \n\t '); expect(result.ok).toBe(false); }); it('rejects a one-line prose summary (the #50 phantom-artifact case)', () => { const prose = '查看 `html-ppt-xhs-white-editorial/index.html` — 已删第 2 页(章节分隔)和第 8 页(致谢),剩余 6 张移除顶部 chrome,仅保留右下角 `01/06`–`06/06` 页码。'; const result = validateHtmlArtifact(prose); expect(result.ok).toBe(false); if (!result.ok) expect(result.reason).toMatch(/html/i); }); it('rejects content shorter than the minimum threshold even if it contains angle brackets', () => { const result = validateHtmlArtifact('
hi
'); expect(result.ok).toBe(false); }); it('rejects a long prose blob that lacks any HTML structural markers', () => { const prose = '这是一段很长的中文总结,'.repeat(20); const result = validateHtmlArtifact(prose); expect(result.ok).toBe(false); }); it('rejects long prose that mentions an inline tag mid-sentence (mrcfps finding)', () => { const prose = 'Updated the attribute and cleaned up the footer layout for mobile previews.'; expect(prose.length).toBeGreaterThan(64); const result = validateHtmlArtifact(prose); expect(result.ok).toBe(false); }); it('rejects long prose that mentions mid-sentence', () => { const prose = 'I added a declaration at the top and rewrote the body section to match the brief.'; expect(prose.length).toBeGreaterThan(64); const result = validateHtmlArtifact(prose); expect(result.ok).toBe(false); }); it('rejects content where the first non-whitespace token is a non-document tag like', () => { const fragment = '
This is a paragraph that happens to contain enough chars and a stray mention.
'; const result = validateHtmlArtifact(fragment); expect(result.ok).toBe(false); }); it('rejects links to reserved project storage paths', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); if (!result.ok) expect(result.reason).toMatch(/internal project storage path/i); }); it('rejects root reserved project storage paths in URL attributes', () => { const html = 'PreviewEnough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); if (!result.ok) expect(result.reason).toMatch(/internal project storage path/i); }); it('rejects unquoted URL attributes that reference reserved storage', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); }); it('rejects CSS url references to reserved storage', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); }); it('rejects CSS import references to reserved storage', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); }); it('rejects inline style url references to reserved storage', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); }); it('rejects srcset candidates that reference reserved storage', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(false); }); it('accepts plain text mentions of reserved directory names', () => { const html = 'The .od folder and .tmp files are mentioned as documentation text only, not linked paths.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts external URLs with reserved-looking path segments', () => { const html = 'External docsEnough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts local URLs that only mention reserved paths in query or hash', () => { const html = 'Query docsHash docsEnough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts text-node mentions of CSS url syntax for reserved names', () => { const html = 'Documentation can mention CSS examples like url("/.tmp/foo.png") without linking to project storage.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts text-node mentions of HTML attribute syntax for reserved names', () => { const html = 'Documentation can mention examples like href="/.od/reference.html" without linking to project storage.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts data URLs with reserved-looking payload text', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts data URLs with reserved-looking payload text in srcset', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts the supported live artifact preview API route', () => { const html = 'Enough content to look like a real document.
'; const result = validateHtmlArtifact(html); expect(result.ok).toBe(true); }); it('accepts a complete document', () => { const html = '