tests cannot connect to db
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 1m3s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 1m3s
This commit is contained in:
12
server.ts
12
server.ts
@@ -1,5 +1,6 @@
|
||||
import express, { Request, Response, NextFunction } from 'express';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import { getPool } from './src/services/db/connection';
|
||||
|
||||
import passport from './src/routes/passport';
|
||||
import { logger } from './src/services/logger';
|
||||
@@ -23,6 +24,17 @@ logger.info(` Host: ${process.env.DB_HOST}`);
|
||||
logger.info(` Port: ${process.env.DB_PORT}`);
|
||||
logger.info(` User: ${process.env.DB_USER}`);
|
||||
logger.info(` Database: ${process.env.DB_DATABASE}`);
|
||||
|
||||
// Query the users table to see what the server process sees on startup.
|
||||
getPool().query('SELECT id, email, role FROM public.users u JOIN public.profiles p ON u.id = p.id')
|
||||
.then(res => {
|
||||
logger.debug('[SERVER PROCESS] Users found in DB on startup:');
|
||||
console.table(res.rows);
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error('[SERVER PROCESS] Could not query users table on startup.', { err });
|
||||
});
|
||||
|
||||
logger.info('-----------------------------------------------\n');
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -177,6 +177,12 @@ async function main() {
|
||||
}
|
||||
logger.info(`Seeded shopping list "Weekly Groceries" with ${shoppingListItems.length} items for Test User.`);
|
||||
|
||||
// --- SEED SCRIPT DEBUG LOGGING ---
|
||||
const allUsersInDb = await client.query('SELECT id, email, role FROM public.users u JOIN public.profiles p ON u.id = p.id');
|
||||
logger.debug('[SEED SCRIPT] Final state of users table after seeding:');
|
||||
console.table(allUsersInDb.rows);
|
||||
// --- END DEBUG LOGGING ---
|
||||
|
||||
await client.query('COMMIT');
|
||||
logger.info('✅ Database seeding completed successfully!');
|
||||
|
||||
|
||||
@@ -92,7 +92,21 @@ router.post('/register', async (req: Request, res: Response, next: NextFunction)
|
||||
|
||||
// Login Route
|
||||
router.post('/login', (req: Request, res: Response, next: NextFunction) => {
|
||||
passport.authenticate('local', { session: false }, (err: Error, user: Express.User | false, info: { message: string }) => {
|
||||
passport.authenticate('local', { session: false }, async (err: Error, user: Express.User | false, info: { message: string }) => {
|
||||
// --- LOGIN ROUTE DEBUG LOGGING ---
|
||||
logger.debug(`[API /login] Received login request for email: ${req.body.email}`);
|
||||
if (err) logger.error('[API /login] Passport reported an error.', { err });
|
||||
if (!user) logger.warn('[API /login] Passport reported NO USER found.', { info });
|
||||
if (user) logger.info('[API /login] Passport reported USER FOUND.', { user });
|
||||
|
||||
try {
|
||||
const allUsersInDb = await db.getPool().query('SELECT id, email, role FROM public.users u JOIN public.profiles p ON u.id = p.id');
|
||||
logger.debug('[API /login] Current users in DB from SERVER perspective:');
|
||||
console.table(allUsersInDb.rows);
|
||||
} catch (dbError) {
|
||||
logger.error('[API /login] Could not query users table for debugging.', { dbError });
|
||||
}
|
||||
// --- END DEBUG LOGGING ---
|
||||
const { rememberMe } = req.body;
|
||||
if (err) {
|
||||
logger.error('Login authentication error in /login route:', { error: err });
|
||||
@@ -133,8 +147,11 @@ router.post('/forgot-password', forgotPasswordLimiter, async (req: Request, res:
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug(`[API /forgot-password] Received request for email: ${email}`);
|
||||
const user = await db.findUserByEmail(email);
|
||||
let token: string | undefined;
|
||||
logger.debug(`[API /forgot-password] Database search result for ${email}:`, { user: user ? { id: user.id, email: user.email } : 'NOT FOUND' });
|
||||
|
||||
if (user) {
|
||||
token = crypto.randomBytes(32).toString('hex');
|
||||
const saltRounds = 10;
|
||||
|
||||
@@ -155,11 +155,15 @@ router.delete('/users/account', async (req: Request, res: Response) => {
|
||||
return res.status(400).json({ message: 'Password is required for account deletion.' });
|
||||
}
|
||||
|
||||
logger.info(`Account deletion requested for user ID: ${authenticatedUser.id}`);
|
||||
logger.info(`[API /users/account] Account deletion requested for user ID: ${authenticatedUser.id}`);
|
||||
|
||||
try {
|
||||
const userWithHash = await db.findUserWithPasswordHashById(authenticatedUser.id);
|
||||
|
||||
// --- DELETE ACCOUNT DEBUG LOGGING ---
|
||||
logger.debug(`[API /users/account] DB search result for user ID ${authenticatedUser.id}:`, { user: userWithHash ? 'FOUND' : 'NOT FOUND' });
|
||||
// --- END DEBUG LOGGING ---
|
||||
|
||||
if (!userWithHash || !userWithHash.password_hash) {
|
||||
return res.status(404).json({ message: 'User not found or is an OAuth user.' });
|
||||
}
|
||||
|
||||
@@ -115,6 +115,13 @@ export const apiFetch = async (url: string, options: RequestInit = {}, tokenOver
|
||||
}
|
||||
}
|
||||
|
||||
// --- DEBUG LOGGING for failed requests ---
|
||||
if (!response.ok) {
|
||||
const responseText = await response.clone().text();
|
||||
logger.error(`apiFetch: Request to ${fullUrl} failed with status ${response.status}. Response body:`, responseText);
|
||||
}
|
||||
// --- END DEBUG LOGGING ---
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ import { logger } from '../logger';
|
||||
let poolInstance: Pool | undefined;
|
||||
|
||||
const createPool = (): Pool => {
|
||||
// Add a unique ID to each pool instance for definitive tracking in logs.
|
||||
const poolId = Math.random().toString(36).substring(2, 8);
|
||||
|
||||
// --- START DEBUG LOGGING ---
|
||||
// Log the database connection details being used by the server process.
|
||||
// This helps confirm it's using the correct .env file for the environment.
|
||||
@@ -17,6 +20,7 @@ const createPool = (): Pool => {
|
||||
logger.info(` Port: ${process.env.DB_PORT}`);
|
||||
logger.info(` User: ${process.env.DB_USER}`);
|
||||
logger.info(` Database: ${process.env.DB_DATABASE}`);
|
||||
logger.info(` Pool Instance ID: ${poolId}`);
|
||||
logger.info('----------------------------------------------------');
|
||||
|
||||
const newPool = new Pool({
|
||||
|
||||
@@ -14,9 +14,10 @@ type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'DEBUG';
|
||||
* methods. Using `unknown[]` is more type-safe than `any[]` and satisfies the linter.
|
||||
*/
|
||||
const log = <T extends unknown[]>(level: LogLevel, message: string, ...args: T) => {
|
||||
const pid = process.pid;
|
||||
const timestamp = getTimestamp();
|
||||
// We construct the log message with a timestamp and level for better context.
|
||||
const logMessage = `[${timestamp}] [${level}] ${message}`;
|
||||
// We construct the log message with a timestamp, PID, and level for better context.
|
||||
const logMessage = `[${timestamp}] [PID:${pid}] [${level}] ${message}`;
|
||||
|
||||
switch (level) {
|
||||
case 'INFO':
|
||||
|
||||
@@ -6,20 +6,20 @@ import { execSync } from 'child_process';
|
||||
let serverProcess: ChildProcess;
|
||||
|
||||
export async function setup() {
|
||||
console.log('\n--- Running Integration Test Setup ---');
|
||||
console.log(`\n--- [PID:${process.pid}] Running Integration Test GLOBAL Setup ---`);
|
||||
|
||||
// The integration setup is now the single source of truth for preparing the test DB.
|
||||
// It runs the same seed script that `npm run db:reset:test` used.
|
||||
try {
|
||||
console.log('Resetting and seeding test database...');
|
||||
console.log(`\n[PID:${process.pid}] Running database seed script...`);
|
||||
execSync('npm run db:reset:test', { stdio: 'inherit' });
|
||||
console.log('✅ Test database is ready.');
|
||||
console.log(`✅ [PID:${process.pid}] Database seed script finished.`);
|
||||
} catch (error) {
|
||||
console.error('🔴 Failed to reset and seed the test database. Aborting tests.', error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Starting backend server for integration tests...');
|
||||
console.log(`\n[PID:${process.pid}] Starting backend server as a separate process...`);
|
||||
|
||||
// Use the dedicated test server script, which correctly uses the .env.test file.
|
||||
serverProcess = exec('npm run start:test');
|
||||
@@ -27,7 +27,7 @@ export async function setup() {
|
||||
// --- NEW LOGGING START ---
|
||||
// Listen for premature exit to debug crashes immediately
|
||||
serverProcess.on('exit', (code, signal) => {
|
||||
if (code !== null && code !== 0) {
|
||||
if (code !== 0 && signal !== 'SIGTERM') {
|
||||
console.error(`\n[SERVER EXIT]: Backend server process exited prematurely with code ${code} and signal ${signal}`);
|
||||
console.error('Check [SERVER STDERR] logs above for details.\n');
|
||||
}
|
||||
@@ -68,7 +68,7 @@ export async function setup() {
|
||||
throw new Error(`Server process exited with code ${serverProcess.exitCode}`);
|
||||
}
|
||||
|
||||
if (await pingTestBackend()) {
|
||||
if (await pingTestBackend().catch(() => false)) {
|
||||
console.log('✅ Backend server is running and responsive.');
|
||||
return;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ export async function setup() {
|
||||
if (serverProcess.exitCode !== null) throw e;
|
||||
logger.debug('Ping failed while waiting for server, this is expected.', { error: e });
|
||||
}
|
||||
console.log(`Waiting for backend server... (attempt ${i + 1}/${maxRetries})`);
|
||||
console.log(`[PID:${process.pid}] Waiting for backend server... (attempt ${i + 1}/${maxRetries})`);
|
||||
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ export async function setup() {
|
||||
}
|
||||
|
||||
export async function teardown() {
|
||||
console.log('--- Integration Test Teardown ---');
|
||||
console.log(`\n--- [PID:${process.pid}] Running Integration Test GLOBAL Teardown ---`);
|
||||
// Close the database connection pool after all integration tests have run.
|
||||
// This is the correct place to ensure all connections are closed gracefully.
|
||||
const pool = getPool();
|
||||
|
||||
0
src/tests/setup/server-test-helper.ts
Normal file
0
src/tests/setup/server-test-helper.ts
Normal file
Reference in New Issue
Block a user