← back to Jill Website

src/__tests__/setup.ts

117 lines

import { Pool } from 'pg';
import * as dotenv from 'dotenv';

dotenv.config();

// Test database configuration
export const testDbConfig = {
  host: process.env.TEST_DB_HOST || process.env.DB_HOST || 'localhost',
  port: parseInt(process.env.TEST_DB_PORT || process.env.DB_PORT || '5432'),
  database: process.env.TEST_DB_NAME || 'jill_website_test',
  user: process.env.TEST_DB_USER || process.env.DB_USER || 'postgres',
  password: process.env.TEST_DB_PASSWORD || process.env.DB_PASSWORD || '',
};

let testPool: Pool | null = null;

/**
 * Get or create test database pool
 */
export const getTestPool = (): Pool => {
  if (!testPool) {
    testPool = new Pool(testDbConfig);
  }
  return testPool;
};

/**
 * Setup test database - create tables
 */
export const setupTestDatabase = async (): Promise<void> => {
  const pool = getTestPool();

  // Create properties table
  await pool.query(`
    CREATE TABLE IF NOT EXISTS properties (
      id SERIAL PRIMARY KEY,
      name VARCHAR(255) NOT NULL,
      description TEXT NOT NULL,
      amenities JSONB NOT NULL,
      images JSONB NOT NULL,
      airbnb_url VARCHAR(500) NOT NULL,
      capacity INTEGER,
      bedrooms INTEGER,
      bathrooms INTEGER,
      size_sqm DECIMAL(10, 2),
      price_per_night DECIMAL(10, 2),
      created_at TIMESTAMP DEFAULT NOW(),
      updated_at TIMESTAMP DEFAULT NOW()
    )
  `);

  // Create inquiries table
  await pool.query(`
    CREATE TABLE IF NOT EXISTS inquiries (
      id SERIAL PRIMARY KEY,
      name VARCHAR(255) NOT NULL,
      email VARCHAR(255) NOT NULL,
      phone VARCHAR(50) NOT NULL,
      check_in_date DATE NOT NULL,
      check_out_date DATE NOT NULL,
      guest_count INTEGER NOT NULL,
      message TEXT NOT NULL,
      created_at TIMESTAMP DEFAULT NOW(),
      updated_at TIMESTAMP DEFAULT NOW()
    )
  `);
};

/**
 * Clear all data from test tables
 */
export const clearTestData = async (): Promise<void> => {
  const pool = getTestPool();
  try {
    await pool.query('TRUNCATE TABLE inquiries RESTART IDENTITY CASCADE');
    await pool.query('TRUNCATE TABLE properties RESTART IDENTITY CASCADE');
  } catch (error) {
    // Tables might not exist yet on first run, that's okay
    console.log('Warning: Could not clear test data, tables may not exist yet');
  }
};

/**
 * Teardown test database - drop tables
 */
export const teardownTestDatabase = async (): Promise<void> => {
  const pool = getTestPool();
  await pool.query('DROP TABLE IF EXISTS inquiries CASCADE');
  await pool.query('DROP TABLE IF EXISTS properties CASCADE');
};

/**
 * Close test database connection
 */
export const closeTestDatabase = async (): Promise<void> => {
  if (testPool) {
    await testPool.end();
    testPool = null;
  }
};

// Setup before all tests
beforeAll(async () => {
  await setupTestDatabase();
});

// Clear data before each test
beforeEach(async () => {
  await clearTestData();
});

// Teardown after all tests
afterAll(async () => {
  await teardownTestDatabase();
  await closeTestDatabase();
});