import {setupMailServer, teardownMailServer} from "./_mail_server"; import Application from "../src/Application"; import Migration, {MigrationType} from "../src/db/Migration"; import {MIGRATIONS} from "./_migrations"; import ExpressAppComponent from "../src/components/ExpressAppComponent"; import RedisComponent from "../src/components/RedisComponent"; import MysqlComponent from "../src/components/MysqlComponent"; import NunjucksComponent from "../src/components/NunjucksComponent"; import LogRequestsComponent from "../src/components/LogRequestsComponent"; import MailComponent from "../src/components/MailComponent"; import SessionComponent from "../src/components/SessionComponent"; import AuthComponent from "../src/auth/AuthComponent"; import AuthGuard from "../src/auth/AuthGuard"; import MagicLink from "../src/auth/models/MagicLink"; import FormHelperComponent from "../src/components/FormHelperComponent"; import RedirectBackComponent from "../src/components/RedirectBackComponent"; import ServeStaticDirectoryComponent from "../src/components/ServeStaticDirectoryComponent"; import {Express} from "express"; import packageJson = require('../package.json'); export default function useApp(appSupplier?: (addr: string, port: number) => TestApp): void { let app: Application; beforeAll(async (done) => { await setupMailServer(); app = appSupplier ? appSupplier('127.0.0.1', 8966) : new TestApp('127.0.0.1', 8966); await app.start(); done(); }); afterAll(async (done) => { const errors = []; try { await app.stop(); } catch (e) { errors.push(e); } try { await teardownMailServer(); } catch (e) { errors.push(e); } if (errors.length > 0) throw errors; done(); }); } export class TestApp extends Application { private readonly addr: string; private readonly port: number; private expressAppComponent?: ExpressAppComponent; public constructor(addr: string, port: number) { super(packageJson.version, true); this.addr = addr; this.port = port; } protected getMigrations(): MigrationType[] { return MIGRATIONS; } protected async init(): Promise { this.registerComponents(); this.registerWebSocketListeners?.(); this.registerControllers?.(); } protected registerComponents(): void { this.expressAppComponent = new ExpressAppComponent(this.addr, this.port); const redisComponent = new RedisComponent(); const mysqlComponent = new MysqlComponent(); // Base this.use(this.expressAppComponent); this.use(new LogRequestsComponent()); // Static files this.use(new ServeStaticDirectoryComponent('public')); // Dynamic views and routes this.use(new NunjucksComponent(['test/views', 'views'])); this.use(new RedirectBackComponent()); // Services this.use(mysqlComponent); this.use(new MailComponent()); // Session this.use(redisComponent); this.use(new SessionComponent(redisComponent)); // Auth this.use(new AuthComponent(new class extends AuthGuard { public async getProofForSession(session: Express.Session): Promise { return await MagicLink.bySessionId(session.id, ['login', 'register']); } }(this))); // Utils this.use(new FormHelperComponent()); } protected registerWebSocketListeners?(): void; protected registerControllers?(): void; public getExpressApp(): Express { return this.as(ExpressAppComponent).getExpressApp(); } }