Files
dc-recorder/tests/database.test.ts
2026-05-14 14:59:37 +07:00

141 lines
4.1 KiB
TypeScript

import process from "node:process";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
const originalEnv = process.env;
describe("PostgreSQL Connection", () => {
let skipPostgresTests = false;
let config: any;
let postgres: any;
let logger: any;
beforeAll(async () => {
// Set up environment for config loading
process.env = {
...originalEnv,
DISCORD_TOKEN: "test-token",
NODE_ENV: "test",
DATABASE_TYPE: originalEnv.DATABASE_TYPE || "sqlite",
};
// Reset modules to pick up new environment
vi.resetModules();
// Import after environment is set
const configModule = await import("../src/config");
const postgresModule = await import("../src/database/postgres");
const loggerModule = await import("../src/logger");
config = configModule.config;
postgres = postgresModule;
logger = loggerModule.createChildLogger("database.test");
if (config.DATABASE_TYPE !== "postgres") {
skipPostgresTests = true;
logger.info("Skipping PostgreSQL tests (DATABASE_TYPE != postgres)");
}
});
afterAll(async () => {
if (config && config.DATABASE_TYPE === "postgres") {
try {
await postgres.closePool();
} catch (error) {
if (logger) {
logger.error(
{ error: error instanceof Error ? error.message : String(error) },
"Error closing pool in afterAll",
);
}
}
}
process.env = originalEnv;
});
it("should initialize connection pool", async () => {
if (skipPostgresTests) {
logger.info("Skipping test: DATABASE_TYPE is not postgres");
return;
}
const pool = postgres.getPool();
expect(pool).toBeDefined();
expect(pool).toHaveProperty("connect");
expect(pool).toHaveProperty("query");
expect(pool).toHaveProperty("end");
});
it("should execute query", async () => {
if (skipPostgresTests) {
logger.info("Skipping test: DATABASE_TYPE is not postgres");
return;
}
const result = await postgres.query("SELECT 1 as num");
expect(result).toBeDefined();
expect(result.rows).toBeDefined();
expect(result.rows.length).toBeGreaterThan(0);
expect(result.rows[0]).toHaveProperty("num");
expect(result.rows[0].num).toBe(1);
});
it("should handle connection errors gracefully", async () => {
if (skipPostgresTests) {
logger.info("Skipping test: DATABASE_TYPE is not postgres");
return;
}
// Test that invalid queries throw errors appropriately
try {
await postgres.query("SELECT * FROM nonexistent_table_xyz");
// If we get here, the test should fail
expect.fail("Expected query to throw an error");
} catch (error) {
// Expected behavior: query should throw an error for invalid table
expect(error).toBeDefined();
expect(error instanceof Error).toBe(true);
}
});
it("should acquire and release client from pool", async () => {
if (skipPostgresTests) {
logger.info("Skipping test: DATABASE_TYPE is not postgres");
return;
}
const client = await postgres.getClient();
expect(client).toBeDefined();
expect(client).toHaveProperty("query");
expect(client).toHaveProperty("release");
// Execute a simple query with the client
const result = await client.query("SELECT 1 as num");
expect(result.rows[0].num).toBe(1);
// Release the client back to the pool
client.release();
});
it("should build config from DATABASE_URL", () => {
if (skipPostgresTests) {
logger.info("Skipping test: DATABASE_TYPE is not postgres");
return;
}
// Test buildConfig function with a sample DATABASE_URL
const pgConfig = postgres.buildConfig();
expect(pgConfig).toBeDefined();
expect(pgConfig).toHaveProperty("host");
expect(pgConfig).toHaveProperty("port");
expect(pgConfig).toHaveProperty("min");
expect(pgConfig).toHaveProperty("max");
expect(pgConfig.port).toBeGreaterThan(0);
expect(pgConfig.min).toBeGreaterThan(0);
expect(pgConfig.max).toBeGreaterThanOrEqual(pgConfig.min);
});
});