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);
});
});