You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.7 KiB
TypeScript

import { Database } from 'bun:sqlite';
import { initializeDatabase } from '../../src/db';
import { describe, test, expect, beforeEach, afterAll, beforeAll } from 'bun:test';
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(() => {
// Reset database schema between tests by dropping tables and re-initializing
testDb.exec('DROP TABLE IF EXISTS tasks');
testDb.exec('DROP TABLE IF EXISTS task_assignments');
testDb.exec('DROP TABLE IF EXISTS users');
testDb.exec('DROP TABLE IF EXISTS groups');
// Initialize schema on the test database instance
initializeDatabase(testDb);
});
describe('Table Creation', () => {
test('should create all required tables', () => {
const tables = testDb
.query("SELECT name FROM sqlite_master WHERE type='table'")
.all()
.map((t: any) => t.name);
const expectedTables = ['groups', 'task_assignments', 'tasks', 'users'];
const userTables = tables.filter(t => !t.startsWith('sqlite_'));
expect(userTables.sort()).toEqual(expectedTables.sort());
});
});
describe('Table Schemas', () => {
test('users table should have correct columns', () => {
const columns = testDb
.query("PRAGMA table_info(users)")
.all()
.map((c: any) => c.name);
expect(columns).toEqual(['id', 'first_seen', 'last_seen']);
});
test('tasks table should have required columns', () => {
const columns = testDb
.query("PRAGMA table_info(tasks)")
.all()
.map((c: any) => c.name);
expect(columns).toContain('description');
expect(columns).toContain('due_date');
expect(columns).toContain('group_id');
expect(columns).toContain('created_by');
});
test('groups table should have active flag default to true', () => {
testDb.exec(`
INSERT INTO groups (id, community_id, name)
VALUES ('test-group', 'test-community', 'Test Group')
`);
const group = testDb.query("SELECT active FROM groups WHERE id = 'test-group'").get();
expect(group.active).toBe(1); // SQLite uses 1 for TRUE
});
});
describe('Foreign Keys', () => {
test('task_assignments should reference tasks', () => {
const fkInfo = testDb
.query("PRAGMA foreign_key_list(task_assignments)")
.all();
expect(fkInfo.length).toBe(1);
expect(fkInfo[0].from).toBe('task_id');
expect(fkInfo[0].to).toBe('id');
expect(fkInfo[0].table).toBe('tasks');
});
test('tasks should reference users via created_by', () => {
const fkInfo = testDb
.query("PRAGMA foreign_key_list(tasks)")
.all();
expect(fkInfo.length).toBe(1);
expect(fkInfo[0].from).toBe('created_by');
expect(fkInfo[0].to).toBe('id');
expect(fkInfo[0].table).toBe('users');
});
});
describe('User Operations', () => {
test('should reject duplicate user IDs', () => {
// First insert should succeed
const firstInsert = testDb.prepare(`
INSERT INTO users (id) VALUES ('34650112233')
`).run();
expect(firstInsert.changes).toBe(1);
// Second insert with same ID should fail due to PRIMARY KEY constraint
expect(() => {
testDb.prepare(`
INSERT INTO users (id) VALUES ('34650112233')
`).run();
}).toThrow(); // Bun's SQLite driver throws an error on constraint violation
// Verify only one record exists
const countResult = testDb.prepare(`
SELECT COUNT(*) as count FROM users WHERE id = '34650112233'
`).get();
expect(countResult.count).toBe(1);
});
});
describe('Data Operations', () => {
beforeEach(() => {
// Seed necessary data for these tests into the test database
testDb.exec(`
INSERT INTO users (id) VALUES ('34650112233');
INSERT INTO groups (id, community_id, name)
VALUES ('test-group', 'test-community', 'Test Group')
`);
});
test('should allow inserting group tasks', () => {
const result = testDb.prepare(`
INSERT INTO tasks (description, created_by, group_id)
VALUES ('Test task', '34650112233', 'test-group')
`).run();
expect(result.changes).toBe(1);
});
test('should allow inserting private tasks', () => {
const result = testDb.prepare(`
INSERT INTO tasks (description, created_by)
VALUES ('Private task', '34650112233')
`).run();
expect(result.changes).toBe(1);
});
});
});