import { expect, test } from "bun:test"; import { sql, type Kysely } from "kysely"; import { Migrator } from "kysely/migration"; import { newId, nowIso } from "../src/ids.ts"; import { toJson } from "../src/json.ts"; import { migrations } from "../src/migrations/index.ts"; import { forEachDialect } from "../src/testing.ts"; forEachDialect("schema", (getDb) => { test("all tables exist and unique constraints hold", async () => { const k = getDb().k; const now = nowIso(); const userId = newId(); await k .insertInto("users") .values({ id: userId, username: "ada", display_name: "Ada", password_hash: "x", role: "admin", preferences: toJson({}), created_at: now, updated_at: now, }) .execute(); const workId = newId(); await k .insertInto("works") .values({ id: workId, media_type: "book", title: "Dune", original_title: "Dune", year: 1965, release_date: null, creators: toJson([]), description: "", cover_url: "", cover_attachment_id: null, metadata: toJson({}), parent_id: null, position: null, owner_user_id: null, merged_into_id: null, created_at: now, updated_at: now, }) .execute(); await k .insertInto("external_ids") .values({ id: newId(), work_id: workId, namespace: "isbn", value: "123" }) .execute(); await expect( k.insertInto("external_ids").values({ id: newId(), work_id: workId, namespace: "isbn", value: "123" }).execute(), ).rejects.toThrow(); const entry = { user_id: userId, work_id: workId, status: "planned" as const, rating: null, review: null, private_notes: null, favorite: 0, tags: toJson([]), custom_fields: toJson({}), visibility: "private" as const, overrides: toJson({}), media_type_override: null, field_sources: toJson({}), created_at: now, updated_at: now, deleted_at: null, }; await k.insertInto("entries").values({ id: newId(), ...entry }).execute(); await expect(k.insertInto("entries").values({ id: newId(), ...entry }).execute()).rejects.toThrow(); }); test("migrating down removes the tables", async () => { const k = getDb().k as Kysely; const migrator = new Migrator({ db: k, provider: { getMigrations: async () => migrations } }); const { error } = await migrator.migrateDown(); expect(error).toBeUndefined(); const probe = sql`select 1 from users`.execute(k); await expect(probe).rejects.toThrow(); }); });