From ff2b056192e3ce2407faabd829e3a936fad2a439 Mon Sep 17 00:00:00 2001 From: Steven Tsang Date: Sat, 9 Nov 2024 20:13:33 +0000 Subject: [PATCH] add additional test for middleware changes --- tests/entities/foo.entity.ts | 3 +- tests/mikro-orm.middleware.test.ts | 87 +++++++++---- tests/mikro-orm.multiple-middleware.test.ts | 128 ++++++++++++++++++++ 3 files changed, 194 insertions(+), 24 deletions(-) create mode 100644 tests/mikro-orm.multiple-middleware.test.ts diff --git a/tests/entities/foo.entity.ts b/tests/entities/foo.entity.ts index b5aa3da..0e7b8fa 100644 --- a/tests/entities/foo.entity.ts +++ b/tests/entities/foo.entity.ts @@ -1,6 +1,7 @@ -import { PrimaryKey, Entity } from '@mikro-orm/core'; +import { PrimaryKey, Entity, Filter } from '@mikro-orm/core'; @Entity() +@Filter({ name: 'id', cond: args => ({ id: args.id }) }) export class Foo { @PrimaryKey() diff --git a/tests/mikro-orm.middleware.test.ts b/tests/mikro-orm.middleware.test.ts index df82fe2..c9d74e7 100644 --- a/tests/mikro-orm.middleware.test.ts +++ b/tests/mikro-orm.middleware.test.ts @@ -1,9 +1,17 @@ -import { MikroORM, type Options } from '@mikro-orm/core'; +import { EntityManager, MikroORM, type Options } from '@mikro-orm/core'; import { SqliteDriver } from '@mikro-orm/sqlite'; -import { Controller, Get, Module, type INestApplication } from '@nestjs/common'; +import { + Controller, + Get, + type INestApplication, + Injectable, + MiddlewareConsumer, + Module, type NestMiddleware, + NestModule, +} from '@nestjs/common'; import { Test, type TestingModule } from '@nestjs/testing'; import request from 'supertest'; -import { InjectMikroORM, MikroOrmModule, MultipleMikroOrmModule } from '../src'; +import { InjectEntityManager, InjectMikroORM, MikroOrmModule } from '../src'; import { Bar } from './entities/bar.entity'; import { Foo } from './entities/foo.entity'; @@ -14,45 +22,82 @@ const testOptions: Options = { entities: ['entities'], }; -@Controller() -class TestController { +@Controller('/foo') +export class FooController { - constructor( - @InjectMikroORM('database1') private database1: MikroORM, - @InjectMikroORM('database2') private database2: MikroORM, - ) {} + constructor(@InjectMikroORM('database-foo') private database1: MikroORM) {} - @Get('foo') + @Get() foo() { return this.database1.em !== this.database1.em.getContext(); } - @Get('bar') +} + +@Controller('/bar') +export class BarController { + + constructor(@InjectMikroORM('database-bar') private database2: MikroORM) {} + + @Get() bar() { return this.database2.em !== this.database2.em.getContext(); } } +@Injectable() +export class TestMiddleware implements NestMiddleware { + + constructor(@InjectEntityManager('database-foo') private readonly em: EntityManager) {} + + use(req: unknown, res: unknown, next: (...args: any[]) => void) { + // Throws error "Using global EntityManager instance methods for context specific actions is disallowed" + this.em.setFilterParams('id', { id: '1' }); + + return next(); + } + +} + +@Module({ + imports: [MikroOrmModule.forFeature([Foo], 'database-foo')], + controllers: [FooController], +}) +class FooModule implements NestModule { + + configure(consumer: MiddlewareConsumer): void { + consumer + .apply(TestMiddleware) + .forRoutes('/'); + } + +} + +@Module({ + imports: [MikroOrmModule.forFeature([Bar], 'database-bar')], + controllers: [BarController], +}) +class BarModule {} + @Module({ imports: [ MikroOrmModule.forRootAsync({ - contextName: 'database1', + contextName: 'database-foo', useFactory: () => ({ registerRequestContext: false, ...testOptions, }), }), MikroOrmModule.forRoot({ - contextName: 'database2', + contextName: 'database-bar', registerRequestContext: false, ...testOptions, }), - MultipleMikroOrmModule.forRoot(), - MikroOrmModule.forFeature([Foo], 'database1'), - MikroOrmModule.forFeature([Bar], 'database2'), + MikroOrmModule.forMiddleware(), + FooModule, + BarModule, ], - controllers: [TestController], }) class TestModule {} @@ -69,12 +114,8 @@ describe('Middleware executes request context for all MikroORM registered', () = await app.init(); }); - it(`forRoutes(/foo) should return 'true'`, () => { - return request(app.getHttpServer()).get('/foo').expect(200, 'true'); - }); - - it(`forRoutes(/bar) should return 'true'`, () => { - return request(app.getHttpServer()).get('/foo').expect(200, 'true'); + it(`forRoutes(/foo) should return error`, () => { + return request(app.getHttpServer()).get('/foo').expect(500); }); afterAll(async () => { diff --git a/tests/mikro-orm.multiple-middleware.test.ts b/tests/mikro-orm.multiple-middleware.test.ts new file mode 100644 index 0000000..331607a --- /dev/null +++ b/tests/mikro-orm.multiple-middleware.test.ts @@ -0,0 +1,128 @@ +import { EntityManager, MikroORM, type Options } from '@mikro-orm/core'; +import { SqliteDriver } from '@mikro-orm/sqlite'; +import { + Controller, + Get, + Module, + type INestApplication, + Injectable, + type NestMiddleware, + MiddlewareConsumer, + NestModule, +} from '@nestjs/common'; +import { Test, type TestingModule } from '@nestjs/testing'; +import request from 'supertest'; +import { InjectEntityManager, InjectMikroORM, MikroOrmModule, MultipleMikroOrmModule } from '../src'; +import { Bar } from './entities/bar.entity'; +import { Foo } from './entities/foo.entity'; + +const testOptions: Options = { + dbName: ':memory:', + driver: SqliteDriver, + baseDir: __dirname, + entities: ['entities'], +}; + +@Controller('/foo') +class FooController { + + constructor(@InjectMikroORM('database-multi-foo') private database1: MikroORM) {} + + @Get() + foo() { + return this.database1.em !== this.database1.em.getContext(); + } + +} + +@Controller('/bar') +class BarController { + + constructor(@InjectMikroORM('database-multi-bar') private database2: MikroORM) {} + + @Get() + bar() { + return this.database2.em !== this.database2.em.getContext(); + } + +} + +@Injectable() +export class TestMiddleware implements NestMiddleware { + + constructor(@InjectEntityManager('database-multi-foo') private readonly em: EntityManager) {} + + use(req: unknown, res: unknown, next: (...args: any[]) => void) { + this.em.setFilterParams('id', { id: '1' }); + + return next(); + } + +} + +@Module({ + imports: [MikroOrmModule.forFeature([Foo], 'database-multi-foo')], + controllers: [FooController], +}) +class FooModule implements NestModule { + + configure(consumer: MiddlewareConsumer): void { + consumer + .apply(TestMiddleware) + .forRoutes('/'); + } + +} + +@Module({ + imports: [MikroOrmModule.forFeature([Bar], 'database-multi-bar')], + controllers: [BarController], +}) +class BarModule {} + +@Module({ + imports: [ + MikroOrmModule.forRootAsync({ + contextName: 'database-multi-foo', + useFactory: () => ({ + registerRequestContext: false, + ...testOptions, + }), + }), + MikroOrmModule.forRoot({ + contextName: 'database-multi-bar', + registerRequestContext: false, + ...testOptions, + }), + MultipleMikroOrmModule.forRoot(), + FooModule, + BarModule, + ], +}) +class TestModule {} + +describe('Multiple Middleware executes request context for all MikroORM registered', () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [TestModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + + await app.init(); + }); + + it(`forRoutes(/foo) should return 'true'`, () => { + return request(app.getHttpServer()).get('/foo').expect(200, 'true'); + }); + + it(`forRoutes(/bar) should return 'true'`, () => { + return request(app.getHttpServer()).get('/bar').expect(200, 'true'); + }); + + afterAll(async () => { + await app.close(); + }); +});