import { mkdir, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { compareSitemapToHtml } from '../../src/main/engine/SiteValidationDiffService'; function makeTempName(): string { return `bds-site-validation-${Date.now()}-${Math.random().toString(36).slice(2)}`; } describe('SiteValidationDiffService', () => { it('computes missing and extra URL paths from sitemap xml and html tree', async () => { const tempRoot = path.join('/tmp', makeTempName()); const htmlDir = path.join(tempRoot, 'html'); await mkdir(path.join(htmlDir, 'category', 'news', 'page', '2'), { recursive: true }); await mkdir(path.join(htmlDir, 'stale'), { recursive: true }); await writeFile(path.join(htmlDir, 'index.html'), 'root', 'utf-8'); await writeFile(path.join(htmlDir, 'category', 'news', 'index.html'), 'news', 'utf-8'); await writeFile(path.join(htmlDir, 'category', 'news', 'page', '2', 'index.html'), 'news p2', 'utf-8'); await writeFile(path.join(htmlDir, 'stale', 'index.html'), 'stale', 'utf-8'); const sitemapXml = [ '', '', ' https://example.com/', ' https://example.com/category/news/', ' https://example.com/category/news/page/2/', ' https://example.com/tag/dev/', '', '', ].join('\n'); const result = await compareSitemapToHtml({ sitemapXml, baseUrl: 'https://example.com', htmlDir, }); expect(result.missingUrlPaths).toEqual(['/tag/dev']); expect(result.extraUrlPaths).toEqual(['/stale']); expect(result.expectedUrlCount).toBe(4); expect(result.existingHtmlUrlCount).toBe(4); }); it('normalizes base path urls and tolerates missing html dir', async () => { const sitemapXml = [ '', '', ' https://example.com/blog/', ' https://example.com/blog/page/2/', '', '', ].join('\n'); const result = await compareSitemapToHtml({ sitemapXml, baseUrl: 'https://example.com/blog', htmlDir: path.join('/tmp', makeTempName(), 'missing-html-dir'), }); expect(result.missingUrlPaths).toEqual(['/', '/page/2']); expect(result.extraUrlPaths).toEqual([]); expect(result.expectedUrlCount).toBe(2); expect(result.existingHtmlUrlCount).toBe(0); }); it('treats zero-byte index pages as missing routes that need regeneration', async () => { const tempRoot = path.join('/tmp', makeTempName()); const htmlDir = path.join(tempRoot, 'html'); await mkdir(path.join(htmlDir, '2026', '02', '22'), { recursive: true }); await writeFile(path.join(htmlDir, '2026', '02', '22', 'index.html'), '', 'utf-8'); const sitemapXml = [ '', '', ' https://example.com/2026/02/22/', '', '', ].join('\n'); const result = await compareSitemapToHtml({ sitemapXml, baseUrl: 'https://example.com', htmlDir, }); expect(result.missingUrlPaths).toEqual(['/2026/02/22']); expect(result.extraUrlPaths).toEqual([]); expect(result.expectedUrlCount).toBe(1); expect(result.existingHtmlUrlCount).toBe(0); }); });