Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
180
packages/core/tests/database/connection.test.ts
Normal file
180
packages/core/tests/database/connection.test.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { unlinkSync } from "node:fs";
|
||||
|
||||
import type { Kysely } from "kysely";
|
||||
import { describe, it, expect, afterEach } from "vitest";
|
||||
|
||||
import {
|
||||
createDatabase,
|
||||
EmDashDatabaseError,
|
||||
formatNativeModuleVersionError,
|
||||
} from "../../src/database/connection.js";
|
||||
import type { Database } from "../../src/database/types.js";
|
||||
|
||||
describe("createDatabase", () => {
|
||||
let db: Kysely<Database> | undefined;
|
||||
|
||||
afterEach(async () => {
|
||||
if (db) {
|
||||
await db.destroy();
|
||||
db = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
describe("in-memory SQLite", () => {
|
||||
it("should create in-memory database with :memory: URL", () => {
|
||||
db = createDatabase({ url: ":memory:" });
|
||||
expect(db).toBeDefined();
|
||||
});
|
||||
|
||||
it("should allow queries on in-memory database", async () => {
|
||||
db = createDatabase({ url: ":memory:" });
|
||||
|
||||
// Create a simple table
|
||||
await db.schema
|
||||
.createTable("test")
|
||||
.addColumn("id", "text", (col) => col.primaryKey())
|
||||
.execute();
|
||||
|
||||
// Insert a row
|
||||
await db
|
||||
.insertInto("test" as any)
|
||||
.values({ id: "test-1" })
|
||||
.execute();
|
||||
|
||||
// Query it back
|
||||
const result = await db
|
||||
.selectFrom("test" as any)
|
||||
.selectAll()
|
||||
.execute();
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].id).toBe("test-1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("file-based SQLite", () => {
|
||||
const testDbPath = "./test-db.sqlite";
|
||||
|
||||
afterEach(() => {
|
||||
try {
|
||||
unlinkSync(testDbPath);
|
||||
} catch {
|
||||
// Ignore if file doesn't exist
|
||||
}
|
||||
});
|
||||
|
||||
it("should create file-based database with file: URL", () => {
|
||||
db = createDatabase({ url: `file:${testDbPath}` });
|
||||
expect(db).toBeDefined();
|
||||
});
|
||||
|
||||
it("should persist data to file", async () => {
|
||||
// Create database and insert data
|
||||
db = createDatabase({ url: `file:${testDbPath}` });
|
||||
|
||||
await db.schema
|
||||
.createTable("test")
|
||||
.addColumn("id", "text", (col) => col.primaryKey())
|
||||
.execute();
|
||||
|
||||
await db
|
||||
.insertInto("test" as any)
|
||||
.values({ id: "test-1" })
|
||||
.execute();
|
||||
await db.destroy();
|
||||
db = undefined;
|
||||
|
||||
// Reopen database and verify data persists
|
||||
db = createDatabase({ url: `file:${testDbPath}` });
|
||||
const result = await db
|
||||
.selectFrom("test" as any)
|
||||
.selectAll()
|
||||
.execute();
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].id).toBe("test-1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("libSQL / Turso", () => {
|
||||
it("should throw error for libsql URL without auth token", () => {
|
||||
expect(() => {
|
||||
createDatabase({ url: "libsql://example.turso.io" });
|
||||
}).toThrow(EmDashDatabaseError);
|
||||
|
||||
expect(() => {
|
||||
createDatabase({ url: "libsql://example.turso.io" });
|
||||
}).toThrow("Auth token required");
|
||||
});
|
||||
|
||||
it("should throw not implemented error for libsql URL with token", () => {
|
||||
expect(() => {
|
||||
createDatabase({
|
||||
url: "libsql://example.turso.io",
|
||||
authToken: "test-token",
|
||||
});
|
||||
}).toThrow("LibSQL not yet implemented");
|
||||
});
|
||||
});
|
||||
|
||||
describe("error handling", () => {
|
||||
it("should throw EmDashDatabaseError for invalid URL scheme", () => {
|
||||
expect(() => {
|
||||
createDatabase({ url: "invalid://test" });
|
||||
}).toThrow(EmDashDatabaseError);
|
||||
|
||||
expect(() => {
|
||||
createDatabase({ url: "invalid://test" });
|
||||
}).toThrow("Unsupported database URL scheme");
|
||||
});
|
||||
|
||||
it("should throw EmDashDatabaseError for malformed file path", () => {
|
||||
expect(() => {
|
||||
createDatabase({ url: "file:/nonexistent/path/to/db.sqlite" });
|
||||
}).toThrow(EmDashDatabaseError);
|
||||
});
|
||||
|
||||
it("should wrap underlying errors in EmDashDatabaseError", () => {
|
||||
try {
|
||||
createDatabase({ url: "file:/root/cannot-write-here.db" });
|
||||
} catch (error) {
|
||||
expect(error).toBeInstanceOf(EmDashDatabaseError);
|
||||
expect(error).toHaveProperty("cause");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatNativeModuleVersionError", () => {
|
||||
it("returns an actionable message for NODE_MODULE_VERSION mismatch", () => {
|
||||
const err = new Error(
|
||||
"The module '/path/better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 115. This version of Node.js requires NODE_MODULE_VERSION 127.",
|
||||
);
|
||||
const message = formatNativeModuleVersionError(err);
|
||||
expect(message).not.toBeNull();
|
||||
expect(message).toContain("better-sqlite3");
|
||||
expect(message).toMatch(/rebuild/i);
|
||||
});
|
||||
|
||||
it("returns null for unrelated errors", () => {
|
||||
expect(formatNativeModuleVersionError(new Error("disk full"))).toBeNull();
|
||||
expect(formatNativeModuleVersionError("some string")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("connection lifecycle", () => {
|
||||
it("should allow closing connection with destroy()", async () => {
|
||||
db = createDatabase({ url: ":memory:" });
|
||||
await expect(db.destroy()).resolves.not.toThrow();
|
||||
db = undefined;
|
||||
});
|
||||
|
||||
it("should return functional Kysely instance", () => {
|
||||
db = createDatabase({ url: ":memory:" });
|
||||
|
||||
// Check for Kysely methods
|
||||
expect(db.selectFrom).toBeInstanceOf(Function);
|
||||
expect(db.insertInto).toBeInstanceOf(Function);
|
||||
expect(db.updateTable).toBeInstanceOf(Function);
|
||||
expect(db.deleteFrom).toBeInstanceOf(Function);
|
||||
expect(db.schema).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user