test(migrations): cover initial schema, idempotency, and legacy upgrade
Some checks failed
CI / check (push) Failing after 17s

This commit is contained in:
Julien Calixte
2026-06-07 22:17:54 +02:00
parent 2d7863d9cc
commit 292fe8f85a

115
tests/migrations_test.ts Normal file
View File

@@ -0,0 +1,115 @@
import { assertEquals } from "@std/assert";
import { Database } from "@db/sqlite";
import { applyMigrations } from "../src/migrations/apply.ts";
type TableInfoRow = { name: string };
type ColumnInfoRow = { name: string };
const tableNames = (db: Database): string[] =>
db.prepare(
"SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name",
).all<TableInfoRow>().map((r) => r.name);
const columnNames = (db: Database, table: string): string[] =>
db.prepare(`PRAGMA table_info(${table})`)
.all<ColumnInfoRow>()
.map((r) => r.name)
.sort();
const indexNames = (db: Database): string[] =>
db.prepare(
"SELECT name FROM sqlite_master WHERE type = 'index' AND name NOT LIKE 'sqlite_%' ORDER BY name",
).all<TableInfoRow>().map((r) => r.name);
Deno.test("applyMigrations creates expected tables, columns, and indices", () => {
const db = new Database(":memory:");
try {
applyMigrations(db);
const tables = tableNames(db);
assertEquals(
tables.includes("note") &&
tables.includes("state") &&
tables.includes("webhook_subscription"),
true,
);
const noteCols = columnNames(db, "note");
for (
const col of [
"title",
"publishedAt",
"createdAt",
"did",
"rkey",
"discoverable",
"language",
]
) {
assertEquals(noteCols.includes(col), true, `note.${col} missing`);
}
const webhookCols = columnNames(db, "webhook_subscription");
for (const col of ["id", "did", "method", "url", "token", "verb"]) {
assertEquals(
webhookCols.includes(col),
true,
`webhook_subscription.${col} missing`,
);
}
const indices = indexNames(db);
assertEquals(indices.includes("idx_webhook_subscription_did"), true);
assertEquals(indices.includes("idx_webhook_subscription_did_verb"), true);
} finally {
db.close();
}
});
Deno.test("applyMigrations is idempotent", () => {
const db = new Database(":memory:");
try {
applyMigrations(db);
db.exec(
"INSERT INTO webhook_subscription (did, method, url, verb) VALUES ('did:plc:x', 'POST', 'https://e.com', 'create')",
);
applyMigrations(db);
applyMigrations(db);
const [{ count }] = db.prepare(
"SELECT COUNT(*) AS count FROM webhook_subscription WHERE did = 'did:plc:x' AND verb = 'create'",
).all<{ count: number }>();
assertEquals(count, 1);
} finally {
db.close();
}
});
Deno.test(
"applyMigrations upgrades a legacy schema missing language and discoverable",
() => {
const db = new Database(":memory:");
try {
db.exec(`
CREATE TABLE note (
title TEXT NOT NULL,
publishedAt DATETIME,
createdAt DATETIME NOT NULL,
did TEXT NOT NULL,
rkey TEXT NOT NULL,
listed INTEGER NOT NULL DEFAULT 1,
PRIMARY KEY (did, rkey)
);
`);
applyMigrations(db);
const cols = columnNames(db, "note");
assertEquals(cols.includes("discoverable"), true);
assertEquals(cols.includes("language"), true);
assertEquals(cols.includes("listed"), false);
} finally {
db.close();
}
},
);