92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { readdir } from 'node:fs/promises';
|
|
import { join } from 'node:path';
|
|
import { PostgreSqlContainer, type StartedPostgreSqlContainer } from '@testcontainers/postgresql';
|
|
import { Kysely, Migrator } from 'kysely';
|
|
import { createDatabaseDialect } from '../src/db/config.js';
|
|
import type { Database } from '../src/db/types.js';
|
|
|
|
let postgresContainer: StartedPostgreSqlContainer;
|
|
|
|
export async function setup() {
|
|
console.log('Starting PostgreSQL testcontainer...');
|
|
|
|
postgresContainer = await new PostgreSqlContainer('postgres:18')
|
|
.withExposedPorts(5432)
|
|
.withDatabase('test_db')
|
|
.withUsername('test_user')
|
|
.withPassword('test_password')
|
|
.start();
|
|
|
|
// Set environment variables for tests to use
|
|
process.env.DB_TYPE = 'postgres';
|
|
process.env.DB_HOST = postgresContainer.getHost();
|
|
process.env.DB_PORT = String(postgresContainer.getPort());
|
|
process.env.DB_USER = postgresContainer.getUsername();
|
|
process.env.DB_PASSWORD = postgresContainer.getPassword();
|
|
process.env.DB_NAME = postgresContainer.getDatabase();
|
|
|
|
console.log(`PostgreSQL container started at ${process.env.DB_HOST}:${process.env.DB_PORT}`);
|
|
|
|
// Run migrations once for all tests
|
|
console.log('Running database migrations...');
|
|
const db = new Kysely<Database>({
|
|
dialect: createDatabaseDialect({
|
|
type: 'postgres',
|
|
host: postgresContainer.getHost(),
|
|
port: postgresContainer.getPort(),
|
|
user: postgresContainer.getUsername(),
|
|
password: postgresContainer.getPassword(),
|
|
database: postgresContainer.getDatabase(),
|
|
}),
|
|
});
|
|
|
|
// Dynamically import all migration files from the migrations folder
|
|
const migrationsDir = join(process.cwd(), 'src/db/migrations');
|
|
const files = await readdir(migrationsDir);
|
|
const migrationFiles = files.filter((file) => file.endsWith('.ts'));
|
|
|
|
// biome-ignore lint/suspicious/noExplicitAny: We need to use any here for dynamic imports
|
|
const migrations: Record<string, any> = {};
|
|
for (const file of migrationFiles) {
|
|
const migrationName = file.replace('.ts', '');
|
|
const migrationPath = join(migrationsDir, file);
|
|
const module = await import(migrationPath);
|
|
migrations[migrationName] = module;
|
|
}
|
|
|
|
const migrator = new Migrator({
|
|
db,
|
|
provider: {
|
|
async getMigrations() {
|
|
return migrations;
|
|
},
|
|
},
|
|
});
|
|
|
|
const { error, results } = await migrator.migrateToLatest();
|
|
|
|
if (error) {
|
|
console.error('Migration failed:', error);
|
|
throw error;
|
|
}
|
|
|
|
if (results) {
|
|
for (const result of results) {
|
|
if (result.status === 'Success') {
|
|
console.log(`Migration "${result.migrationName}" executed successfully`);
|
|
} else if (result.status === 'Error') {
|
|
console.error(`Migration "${result.migrationName}" failed`);
|
|
}
|
|
}
|
|
}
|
|
|
|
await db.destroy();
|
|
console.log('Database migrations completed');
|
|
}
|
|
|
|
export async function teardown() {
|
|
console.log('Stopping PostgreSQL testcontainer...');
|
|
await postgresContainer?.stop();
|
|
console.log('PostgreSQL container stopped');
|
|
}
|