maestro/src/db/migrate.notes.test.ts
2026-06-03 05:08:00 +00:00

60 lines
2.3 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Database from 'better-sqlite3';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { runMigrations } from './migrate.js';
describe('migrate: notes tables', () => {
let tmpRoot: string;
let db: Database.Database;
beforeEach(() => {
tmpRoot = mkdtempSync(join(tmpdir(), 'migrate-notes-test-'));
db = new Database(join(tmpRoot, 'test.db'));
});
afterEach(() => {
db.close();
rmSync(tmpRoot, { recursive: true, force: true });
});
it('creates note_index, note_subscriptions, pending_reindex, note_index_fts', () => {
runMigrations(db);
const tables = db
// FTS5 virtual tables appear as type='table' in sqlite_master, not 'virtual'.
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name")
.all()
.map((r: any) => r.name);
expect(tables).toContain('note_index');
expect(tables).toContain('note_subscriptions');
expect(tables).toContain('pending_reindex');
expect(tables).toContain('note_index_fts');
});
it('note_index_fts is kept in sync via triggers on note_index insert', () => {
runMigrations(db);
db.prepare(`INSERT INTO users (id, email) VALUES ('u1','u1@x.com')`).run();
db.prepare(`
INSERT INTO note_index (owner_id, folder, file_name, title, visibility, tags_json, content_size, content_hash, updated_at, body)
VALUES ('u1','cve','foo.md','CVE foo','public','["cve"]',100,'h',1,'this is the body')
`).run();
const row: any = db.prepare(`SELECT title, tags, body FROM note_index_fts WHERE owner_id='u1'`).get();
expect(row.title).toBe('CVE foo');
expect(row.tags).toBe('["cve"]');
expect(row.body).toBe('this is the body');
});
it('CASCADE deletes note_index rows when user is deleted', () => {
runMigrations(db);
db.prepare(`INSERT INTO users (id, email) VALUES ('u1','u1@x.com')`).run();
db.prepare(`
INSERT INTO note_index (owner_id, folder, file_name, visibility, updated_at, content_size, content_hash, body)
VALUES ('u1','f','x.md','private',1,0,'h','')
`).run();
db.prepare(`DELETE FROM users WHERE id='u1'`).run();
const count: any = db.prepare(`SELECT COUNT(*) c FROM note_index WHERE owner_id='u1'`).get();
expect(count.c).toBe(0);
});
});