46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
|
|
// Builds an Express app with the production middleware stack pointed at a
|
||
|
|
// test pool, listens on an ephemeral port, returns { baseUrl, server, pool, cleanup }.
|
||
|
|
// Tests use fetch() against baseUrl — no supertest dep needed.
|
||
|
|
import express from 'express';
|
||
|
|
import cors from 'cors';
|
||
|
|
import session from 'express-session';
|
||
|
|
import connectPgSimple from 'connect-pg-simple';
|
||
|
|
import { setupTestDb } from './setup-db.js';
|
||
|
|
|
||
|
|
const PgStore = connectPgSimple(session);
|
||
|
|
|
||
|
|
export async function createTestApp({ authEnabled = true } = {}) {
|
||
|
|
const pool = await setupTestDb();
|
||
|
|
process.env.AUTH_ENABLED = authEnabled ? 'true' : 'false';
|
||
|
|
process.env.SESSION_SECRET = process.env.SESSION_SECRET || 'test-secret-' + Math.random();
|
||
|
|
|
||
|
|
const app = express();
|
||
|
|
app.use(cors({ origin: true, credentials: true }));
|
||
|
|
app.use(express.json({ limit: '5mb' }));
|
||
|
|
app.use(session({
|
||
|
|
store: new PgStore({ pool, tableName: 'sessions' }),
|
||
|
|
secret: process.env.SESSION_SECRET,
|
||
|
|
name: 'dragonflight.sid',
|
||
|
|
cookie: { httpOnly: true, sameSite: 'lax', secure: false, path: '/', maxAge: 8 * 3600 * 1000 },
|
||
|
|
rolling: false,
|
||
|
|
resave: false,
|
||
|
|
saveUninitialized: false,
|
||
|
|
}));
|
||
|
|
|
||
|
|
app.get('/health', (_req, res) => res.json({ status: 'ok' }));
|
||
|
|
|
||
|
|
// Tests that need additional routes mount them on the returned `app`
|
||
|
|
// before calling listen.
|
||
|
|
return new Promise(resolve => {
|
||
|
|
const server = app.listen(0, '127.0.0.1', () => {
|
||
|
|
const port = server.address().port;
|
||
|
|
const baseUrl = `http://127.0.0.1:${port}`;
|
||
|
|
const cleanup = async () => {
|
||
|
|
await new Promise(r => server.close(r));
|
||
|
|
await pool.end();
|
||
|
|
};
|
||
|
|
resolve({ app, server, pool, baseUrl, cleanup });
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|