Add basic development environment for testing purposes

This commit is contained in:
Alice Gaudon 2020-11-11 18:59:38 +01:00
parent b8905ea02b
commit 24d83c73ad
7 changed files with 652 additions and 113 deletions

View File

@ -10,13 +10,16 @@
"registry": "https://registry.npmjs.com", "registry": "https://registry.npmjs.com",
"access": "public" "access": "public"
}, },
"main": "dist/index.js", "main": "dist/src/main.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"scripts": { "scripts": {
"test": "jest --verbose --runInBand", "test": "jest --verbose --runInBand",
"build": "(test ! -d dist || rm -r dist) && tsc && cp package.json dist/ && cp yarn.lock dist/ && cp -r config dist/ && cp -r views dist/ && mkdir dist/types && cp src/types/* dist/types/", "clean": "(test ! -d dist || rm -r dist)",
"release": "yarn lint && yarn test && yarn build && cd dist && yarn publish", "compile": "yarn clean && tsc",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx" "dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"maildev\"",
"build": "yarn compile && cp package.json dist/ && cp yarn.lock dist/ && cp -r config dist/ && cp -r views dist/ && mkdir dist/types && cp src/types/* dist/types/",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"release": "yarn lint && yarn test && yarn build && cd dist && yarn publish"
}, },
"devDependencies": { "devDependencies": {
"@types/compression": "^1.7.0", "@types/compression": "^1.7.0",
@ -42,10 +45,12 @@
"@types/ws": "^7.2.4", "@types/ws": "^7.2.4",
"@typescript-eslint/eslint-plugin": "^4.2.0", "@typescript-eslint/eslint-plugin": "^4.2.0",
"@typescript-eslint/parser": "^4.2.0", "@typescript-eslint/parser": "^4.2.0",
"concurrently": "^5.3.0",
"eslint": "^7.9.0", "eslint": "^7.9.0",
"jest": "^26.1.0", "jest": "^26.1.0",
"maildev": "^1.1.0", "maildev": "^1.1.0",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"nodemon": "^2.0.6",
"supertest": "^6.0.0", "supertest": "^6.0.0",
"ts-jest": "^26.1.1", "ts-jest": "^26.1.1",
"typescript": "^4.0.2" "typescript": "^4.0.2"

88
src/TestApp.ts Normal file
View File

@ -0,0 +1,88 @@
import Application from "../src/Application";
import Migration, {MigrationType} from "../src/db/Migration";
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 FormHelperComponent from "../src/components/FormHelperComponent";
import RedirectBackComponent from "../src/components/RedirectBackComponent";
import ServeStaticDirectoryComponent from "../src/components/ServeStaticDirectoryComponent";
import {Express} from "express";
import MagicLinkAuthMethod from "../src/auth/magic_link/MagicLinkAuthMethod";
import PasswordAuthMethod from "../src/auth/password/PasswordAuthMethod";
import {MAGIC_LINK_MAIL} from "./Mails";
import packageJson = require('../package.json');
import CreateMigrationsTable from "./migrations/CreateMigrationsTable";
import CreateUsersAndUserEmailsTable from "./auth/migrations/CreateUsersAndUserEmailsTable";
import CreateMagicLinksTableMigration from "./auth/magic_link/CreateMagicLinksTableMigration";
export const MIGRATIONS = [
CreateMigrationsTable,
CreateUsersAndUserEmailsTable,
CreateMagicLinksTableMigration,
];
export default 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(this, new MagicLinkAuthMethod(this, MAGIC_LINK_MAIL), new PasswordAuthMethod(this)));
// Utils
this.use(new FormHelperComponent());
}
protected registerWebSocketListeners?(): void;
protected registerControllers?(): void;
public getExpressApp(): Express {
return this.as(ExpressAppComponent).getExpressApp();
}
}

20
src/main.ts Normal file
View File

@ -0,0 +1,20 @@
import {delimiter} from "path";
// Load config from specified path or default + wms-core/config (default defaults)
process.env['NODE_CONFIG_DIR'] =
__dirname + '/../../node_modules/wms-core/config/'
+ delimiter
+ (process.env['NODE_CONFIG_DIR'] || __dirname + '/../../config/');
import {log} from "./Logger";
import TestApp from "./TestApp";
import config from "config";
(async () => {
log.debug('Config path:', process.env['NODE_CONFIG_DIR']);
const app = new TestApp(config.get<string>('listen_addr'), config.get<number>('port'));
await app.start();
})().catch(err => {
log.error(err);
});

View File

@ -1,10 +1,10 @@
import MysqlConnectionManager from "../src/db/MysqlConnectionManager"; import MysqlConnectionManager from "../src/db/MysqlConnectionManager";
import Model from "../src/db/Model"; import Model from "../src/db/Model";
import {MIGRATIONS} from "./_migrations";
import ModelFactory from "../src/db/ModelFactory"; import ModelFactory from "../src/db/ModelFactory";
import {ValidationBag} from "../src/db/Validator"; import {ValidationBag} from "../src/db/Validator";
import {log} from "../src/Logger"; import {log} from "../src/Logger";
import {ManyThroughModelRelation, OneModelRelation} from "../src/db/ModelRelation"; import {ManyThroughModelRelation, OneModelRelation} from "../src/db/ModelRelation";
import {MIGRATIONS} from "../src/TestApp";
class FakeDummyModel extends Model { class FakeDummyModel extends Model {
public id?: number = undefined; public id?: number = undefined;

View File

@ -1,22 +1,7 @@
import {setupMailServer, teardownMailServer} from "./_mail_server";
import Application from "../src/Application"; import Application from "../src/Application";
import Migration, {MigrationType} from "../src/db/Migration"; import {setupMailServer, teardownMailServer} from "./_mail_server";
import {MIGRATIONS} from "./_migrations"; import TestApp from "../src/TestApp";
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 { export default function useApp(appSupplier?: (addr: string, port: number) => TestApp): void {
let app: Application; let app: Application;
@ -48,68 +33,3 @@ export default function useApp(appSupplier?: (addr: string, port: number) => Tes
done(); 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']);
}
}(this)));
// Utils
this.use(new FormHelperComponent());
}
protected registerWebSocketListeners?(): void;
protected registerControllers?(): void;
public getExpressApp(): Express {
return this.as(ExpressAppComponent).getExpressApp();
}
}

View File

@ -1,9 +0,0 @@
import CreateMigrationsTable from "../src/migrations/CreateMigrationsTable";
import CreateUsersAndUserEmailsTable from "../src/auth/migrations/CreateUsersAndUserEmailsTable";
import CreateMagicLinksTable from "../src/auth/migrations/CreateMagicLinksTable";
export const MIGRATIONS = [
CreateMigrationsTable,
CreateUsersAndUserEmailsTable,
CreateMagicLinksTable,
];

547
yarn.lock

File diff suppressed because it is too large Load Diff