feat(tests): create database test helper and diagnose integration test issues

PROBLEM: 10/26 integration test suites hanging (API tests)
- Tests import app but don't connect required databases
- Tractatus uses TWO separate DB connections (native + Mongoose)
- Tests only connected one, causing hangs when routes accessed User model

INVESTIGATION:
- Created minimal.test.js - diagnostic test (passes)
- Identified root cause: dual database architecture
- Updated api.auth.test.js with both connections (still investigating hang)

CREATED:
- tests/helpers/db-test-helper.js - Unified database setup helper
  Exports setupDatabases() and cleanupDatabases()
  Connects both native MongoDB driver AND Mongoose
  Ready for use in all integration tests

PARTIAL FIX:
- tests/integration/api.auth.test.js - Updated to connect both DBs
- Still investigating why tests hang (likely response field mismatch)

NEXT SESSION:
1. Apply db-test-helper to all 7 API integration tests
2. Fix response field mismatches (accessToken vs token)
3. Verify all tests pass

IMPACT: Test helper provides pattern for fixing all integration tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
TheFlow 2025-10-21 15:39:27 +13:00
parent a20ee846b2
commit b9be0fb3b6
3 changed files with 99 additions and 10 deletions

View file

@ -0,0 +1,39 @@
/**
* Database Test Helper
* Provides unified database setup for integration tests
*
* USAGE:
* const { setupDatabases, cleanupDatabases } = require('../helpers/db-test-helper');
*
* beforeAll(async () => {
* await setupDatabases();
* });
*
* afterAll(async () => {
* await cleanupDatabases();
* });
*/
const mongoose = require('mongoose');
const { connect: connectDb, close: closeDb } = require('../../src/utils/db.util');
const config = require('../../src/config/app.config');
async function setupDatabases() {
// Connect native MongoDB driver (for User model and native queries)
await connectDb();
// Connect Mongoose (for Mongoose models)
if (mongoose.connection.readyState === 0) {
await mongoose.connect(config.mongodb.uri);
}
}
async function cleanupDatabases() {
await mongoose.disconnect();
await closeDb();
}
module.exports = {
setupDatabases,
cleanupDatabases
};

View file

@ -4,14 +4,14 @@
*/ */
const request = require('supertest'); const request = require('supertest');
const { MongoClient } = require('mongodb'); const mongoose = require('mongoose');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const app = require('../../src/server'); const app = require('../../src/server');
const config = require('../../src/config/app.config'); const config = require('../../src/config/app.config');
const { connect: connectDb, close: closeDb } = require('../../src/utils/db.util');
const User = require('../../src/models/User.model');
describe('Authentication API Integration Tests', () => { describe('Authentication API Integration Tests', () => {
let connection;
let db;
const testUser = { const testUser = {
email: 'test@tractatus.test', email: 'test@tractatus.test',
password: 'TestPassword123!', password: 'TestPassword123!',
@ -20,17 +20,20 @@ describe('Authentication API Integration Tests', () => {
// Connect to database and create test user // Connect to database and create test user
beforeAll(async () => { beforeAll(async () => {
connection = await MongoClient.connect(config.mongodb.uri); // Connect both database systems
db = connection.db(config.mongodb.db); await connectDb(); // Native MongoDB driver (for User model)
if (mongoose.connection.readyState === 0) {
await mongoose.connect(config.mongodb.uri); // Mongoose
}
// Clean up any existing test user first // Clean up any existing test user first
await db.collection('users').deleteOne({ email: testUser.email }); await User.deleteOne({ email: testUser.email });
// Create test user with hashed password // Create test user with hashed password
const passwordHash = await bcrypt.hash(testUser.password, 10); const passwordHash = await bcrypt.hash(testUser.password, 10);
await db.collection('users').insertOne({ await User.create({
email: testUser.email, email: testUser.email,
password: passwordHash, // Field name is 'password', not 'passwordHash' password: passwordHash,
name: 'Test User', name: 'Test User',
role: testUser.role, role: testUser.role,
created_at: new Date(), created_at: new Date(),
@ -41,8 +44,9 @@ describe('Authentication API Integration Tests', () => {
// Clean up test data // Clean up test data
afterAll(async () => { afterAll(async () => {
await db.collection('users').deleteOne({ email: testUser.email }); await User.deleteOne({ email: testUser.email });
await connection.close(); await mongoose.disconnect();
await closeDb();
}); });
describe('POST /api/auth/login', () => { describe('POST /api/auth/login', () => {

View file

@ -0,0 +1,46 @@
/**
* Minimal Integration Test - Diagnostic
*/
const request = require('supertest');
const mongoose = require('mongoose');
const config = require('../../src/config/app.config');
console.log('1. Test file loading...');
describe('Minimal Test', () => {
beforeAll(async () => {
console.log('2. beforeAll starting...');
if (mongoose.connection.readyState === 0) {
console.log('3. Connecting to MongoDB...', config.mongodb.uri);
await mongoose.connect(config.mongodb.uri);
console.log('4. MongoDB connected');
}
});
afterAll(async () => {
console.log('5. afterAll - disconnecting...');
await mongoose.disconnect();
console.log('6. Disconnected');
});
test('should connect to database', () => {
console.log('7. Running test...');
expect(mongoose.connection.readyState).toBe(1);
console.log('8. Test complete');
});
test('should make a simple request', async () => {
console.log('9. Importing app...');
const app = require('../../src/server');
console.log('10. App imported');
console.log('11. Making request...');
const response = await request(app)
.get('/api/health')
.timeout(5000);
console.log('12. Response received:', response.status);
expect(response.status).toBe(404);
});
});