Files
Newsletter-Link-Catalog/tests/database.test.ts
2026-05-17 14:05:25 -05:00

91 lines
2.3 KiB
TypeScript

import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { CatalogDatabase } from '../src/database/store.js';
let dir = '';
beforeEach(async () => {
dir = await mkdtemp(join(tmpdir(), 'nlc-db-'));
});
afterEach(async () => {
await rm(dir, { force: true, recursive: true });
});
describe('CatalogDatabase', () => {
it('creates the catalog schema', () => {
const db = new CatalogDatabase(join(dir, 'catalog.sqlite'));
db.migrate();
expect(db.tableNames()).toEqual([
'dead_links',
'issues',
'link_occurrences',
'links',
'newsletters',
'runs',
'sponsors'
]);
db.close();
});
it('persists catalog payloads and deduplicates canonical URLs', () => {
const db = new CatalogDatabase(join(dir, 'catalog.sqlite'));
db.migrate();
db.saveCatalogRun({
mode: 'test',
newslettersProcessed: 2,
linksExtracted: 2,
sponsorCount: 1,
deadLinkCount: 1,
errors: 0,
rows: [
{
'Issue Date': '2026-05-17',
Category: 'JavaScript',
'Link URL': 'https://example.com/post',
Title: 'First mention',
Description: 'One',
'Page Title + Meta': '',
'Source Newsletter': 'Alpha Weekly',
'Also In': ''
},
{
'Issue Date': '2026-05-18',
Category: 'DevOps',
'Link URL': 'https://example.com/post',
Title: 'Second mention',
Description: 'Two',
'Page Title + Meta': '',
'Source Newsletter': 'Beta Weekly',
'Also In': ''
}
],
sponsors: [
{
Newsletter: 'Alpha Weekly',
Sponsor: 'Acme',
Link: 'https://sponsor.example',
Description: 'Sponsor blurb'
}
],
deadLinks: [
{ URL: 'https://dead.example', Status: '404', Source: 'Alpha Weekly', Date: '2026-05-17' }
]
});
expect(db.count('links')).toBe(3);
expect(db.count('link_occurrences')).toBe(2);
expect(db.count('newsletters')).toBe(2);
expect(db.count('issues')).toBe(2);
expect(db.count('sponsors')).toBe(1);
expect(db.count('dead_links')).toBe(1);
expect(db.count('runs')).toBe(1);
db.close();
});
});