test: use in-memory database for tests

main
borja (aider) 2 months ago
parent 0ecd0a6f8e
commit dd32a3dd11

@ -1,9 +1,16 @@
import { Database } from 'bun:sqlite'; import { Database } from 'bun:sqlite';
export const db = new Database('tasks.db'); // Function to get a database instance. Defaults to 'tasks.db'
export function getDb(filename: string = 'tasks.db'): Database {
return new Database(filename);
}
// Default export for the main application database
export const db = getDb();
export function initializeDatabase() { // Initialize function now accepts a database instance
db.exec(` export function initializeDatabase(instance: Database) {
instance.exec(`
CREATE TABLE IF NOT EXISTS tasks ( CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL, description TEXT NOT NULL,

@ -1,19 +1,33 @@
import { db, initializeDatabase } from '../../src/db'; import { Database } from 'bun:sqlite';
import { describe, test, expect, beforeEach } from 'bun:test'; import { initializeDatabase } from '../../src/db';
import { describe, test, expect, beforeEach, afterAll, beforeAll } from 'bun:test';
describe('Database', () => { describe('Database', () => {
let testDb: Database;
// Create an in-memory database before any tests run
beforeAll(() => {
testDb = new Database(':memory:');
});
// Close the database connection after all tests have run
afterAll(() => {
testDb.close();
});
beforeEach(() => { beforeEach(() => {
// Reset database between tests // Reset database schema between tests by dropping tables and re-initializing
db.exec('DROP TABLE IF EXISTS tasks'); testDb.exec('DROP TABLE IF EXISTS tasks');
db.exec('DROP TABLE IF EXISTS task_assignments'); testDb.exec('DROP TABLE IF EXISTS task_assignments');
db.exec('DROP TABLE IF EXISTS users'); testDb.exec('DROP TABLE IF EXISTS users');
db.exec('DROP TABLE IF EXISTS groups'); testDb.exec('DROP TABLE IF EXISTS groups');
initializeDatabase(); // Initialize schema on the test database instance
initializeDatabase(testDb);
}); });
describe('Table Creation', () => { describe('Table Creation', () => {
test('should create all required tables', () => { test('should create all required tables', () => {
const tables = db const tables = testDb
.query("SELECT name FROM sqlite_master WHERE type='table'") .query("SELECT name FROM sqlite_master WHERE type='table'")
.all() .all()
.map((t: any) => t.name); .map((t: any) => t.name);
@ -26,7 +40,7 @@ describe('Database', () => {
describe('Table Schemas', () => { describe('Table Schemas', () => {
test('users table should have correct columns', () => { test('users table should have correct columns', () => {
const columns = db const columns = testDb
.query("PRAGMA table_info(users)") .query("PRAGMA table_info(users)")
.all() .all()
.map((c: any) => c.name); .map((c: any) => c.name);
@ -34,7 +48,7 @@ describe('Database', () => {
}); });
test('tasks table should have required columns', () => { test('tasks table should have required columns', () => {
const columns = db const columns = testDb
.query("PRAGMA table_info(tasks)") .query("PRAGMA table_info(tasks)")
.all() .all()
.map((c: any) => c.name); .map((c: any) => c.name);
@ -45,18 +59,18 @@ describe('Database', () => {
}); });
test('groups table should have active flag default to true', () => { test('groups table should have active flag default to true', () => {
db.exec(` testDb.exec(`
INSERT INTO groups (id, community_id, name) INSERT INTO groups (id, community_id, name)
VALUES ('test-group', 'test-community', 'Test Group') VALUES ('test-group', 'test-community', 'Test Group')
`); `);
const group = db.query("SELECT active FROM groups WHERE id = 'test-group'").get(); const group = testDb.query("SELECT active FROM groups WHERE id = 'test-group'").get();
expect(group.active).toBe(1); expect(group.active).toBe(1); // SQLite uses 1 for TRUE
}); });
}); });
describe('Foreign Keys', () => { describe('Foreign Keys', () => {
test('task_assignments should reference tasks', () => { test('task_assignments should reference tasks', () => {
const fkInfo = db const fkInfo = testDb
.query("PRAGMA foreign_key_list(task_assignments)") .query("PRAGMA foreign_key_list(task_assignments)")
.all(); .all();
expect(fkInfo.length).toBe(1); expect(fkInfo.length).toBe(1);
@ -66,7 +80,7 @@ describe('Database', () => {
}); });
test('tasks should reference users via created_by', () => { test('tasks should reference users via created_by', () => {
const fkInfo = db const fkInfo = testDb
.query("PRAGMA foreign_key_list(tasks)") .query("PRAGMA foreign_key_list(tasks)")
.all(); .all();
expect(fkInfo.length).toBe(1); expect(fkInfo.length).toBe(1);
@ -79,29 +93,30 @@ describe('Database', () => {
describe('User Operations', () => { describe('User Operations', () => {
test('should reject duplicate user IDs', () => { test('should reject duplicate user IDs', () => {
// First insert should succeed // First insert should succeed
const firstInsert = db.prepare(` const firstInsert = testDb.prepare(`
INSERT INTO users (id) VALUES ('34650112233') INSERT INTO users (id) VALUES ('34650112233')
`).run(); `).run();
expect(firstInsert.changes).toBe(1); expect(firstInsert.changes).toBe(1);
// Second insert with same ID should fail // Second insert with same ID should fail due to PRIMARY KEY constraint
expect(() => { expect(() => {
db.prepare(` testDb.prepare(`
INSERT INTO users (id) VALUES ('34650112233') INSERT INTO users (id) VALUES ('34650112233')
`).run(); `).run();
}).toThrow(); }).toThrow(); // Bun's SQLite driver throws an error on constraint violation
// Verify only one record exists // Verify only one record exists
const count = db.prepare(` const countResult = testDb.prepare(`
SELECT COUNT(*) as count FROM users WHERE id = '34650112233' SELECT COUNT(*) as count FROM users WHERE id = '34650112233'
`).get(); `).get();
expect(count.count).toBe(1); expect(countResult.count).toBe(1);
}); });
}); });
describe('Data Operations', () => { describe('Data Operations', () => {
beforeEach(() => { beforeEach(() => {
db.exec(` // Seed necessary data for these tests into the test database
testDb.exec(`
INSERT INTO users (id) VALUES ('34650112233'); INSERT INTO users (id) VALUES ('34650112233');
INSERT INTO groups (id, community_id, name) INSERT INTO groups (id, community_id, name)
VALUES ('test-group', 'test-community', 'Test Group') VALUES ('test-group', 'test-community', 'Test Group')
@ -109,7 +124,7 @@ describe('Database', () => {
}); });
test('should allow inserting group tasks', () => { test('should allow inserting group tasks', () => {
const result = db.prepare(` const result = testDb.prepare(`
INSERT INTO tasks (description, created_by, group_id) INSERT INTO tasks (description, created_by, group_id)
VALUES ('Test task', '34650112233', 'test-group') VALUES ('Test task', '34650112233', 'test-group')
`).run(); `).run();
@ -117,7 +132,7 @@ describe('Database', () => {
}); });
test('should allow inserting private tasks', () => { test('should allow inserting private tasks', () => {
const result = db.prepare(` const result = testDb.prepare(`
INSERT INTO tasks (description, created_by) INSERT INTO tasks (description, created_by)
VALUES ('Private task', '34650112233') VALUES ('Private task', '34650112233')
`).run(); `).run();

Loading…
Cancel
Save