import assert from "node:assert/strict"; import { after, test } from "node:test"; import { randomUUID } from "node:crypto"; import { rmSync } from "node:fs"; const databasePath = `/tmp/mebbling-sync-${randomUUID()}.db`; process.env.DATABASE_PATH = databasePath; delete process.env.HUB_BUILD; let database: typeof import("../lib/db").db | undefined; after(() => { database?.close(); rmSync(databasePath, { force: true }); rmSync(`${databasePath}-wal`, { force: true }); rmSync(`${databasePath}-shm`, { force: true }); }); test("applies tracked migrations and deduplicates active pull jobs", async () => { const { db } = await import("../lib/db"); database = db; const { queuePull } = await import("../lib/sync"); const { notify } = await import("../lib/notifications"); const migrations = db.prepare("SELECT version FROM schema_migrations ORDER BY version").all() as { version: number }[]; assert.deepEqual(migrations.map((item) => item.version), Array.from({ length: 40 }, (_, index) => index + 1)); const userId = Number(db.prepare("INSERT INTO users(username,password_hash) VALUES('sync-test','hash')").run().lastInsertRowid); const sourceId = Number(db.prepare("INSERT INTO sources(user_id,name,base_url,token_encrypted,is_enabled) VALUES(?,?,?,?,1)").run(userId, "Test", "https://example.test", "encrypted").lastInsertRowid); assert.equal(queuePull(sourceId, "manual"), true); assert.equal(queuePull(sourceId, "webhook", { event: "memo.updated" }), false); const jobs = db.prepare("SELECT kind,trigger,status FROM sync_jobs WHERE source_id=?").all(sourceId) as { kind: string; trigger: string; status: string }[]; assert.deepEqual(jobs, [{ kind: "pull", trigger: "manual", status: "queued" }]); const actorId = Number(db.prepare("INSERT INTO users(username,password_hash) VALUES('actor-test','hash')").run().lastInsertRowid); const postId = Number(db.prepare("INSERT INTO posts(author_id,content) VALUES(?,?)").run(userId, "Notification test").lastInsertRowid); assert.equal(Number((db.prepare("SELECT count(*) AS count FROM posts_fts WHERE posts_fts MATCH 'Notification'").get() as { count: number }).count), 1); notify(userId, actorId, postId, "comment", "commented"); notify(userId, userId, postId, "reaction", "ignored"); assert.deepEqual(db.prepare("SELECT type,message FROM notifications WHERE user_id=?").all(userId), [{ type: "comment", message: "commented" }]); });