swaf/test/_app.ts

116 lines
3.7 KiB
TypeScript
Raw Permalink Normal View History

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<Migration>[] {
return MIGRATIONS;
}
protected async init(): Promise<void> {
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<MagicLink> {
public async getProofForSession(session: Express.Session): Promise<MagicLink | null> {
return await MagicLink.bySessionId(session.id, ['login', 'register']);
}
}));
// Utils
this.use(new FormHelperComponent());
}
protected registerWebSocketListeners?(): void;
protected registerControllers?(): void;
public getExpressApp(): Express {
return this.as(ExpressAppComponent).getExpressApp();
}
}