import tachijs , { ConfigSetter , controller , httpGet , inject , BaseController } from '../index' ; import request from 'supertest' ; import express , { ErrorRequestHandler } from 'express' ; describe ( 'tachijs' , ( ) => { it ( 'registers controllers and serves' , async ( ) => { @ controller ( '/' ) class HomeController { @ httpGet ( '/' ) index ( ) { return 'Hello' ; } } const app = tachijs ( { controllers : [ HomeController ] } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'Hello' } ) ; } ) ; it ( 'registers controllers from top to bottom' , async ( ) => { @ controller ( '/' ) class HomeController { @ httpGet ( '/' ) index ( ) { return 'Hello' ; } } @ controller ( '/' ) class SecondController { @ httpGet ( '/' ) index ( ) { return 'Hello Second' ; } } const app = tachijs ( { controllers : [ HomeController , SecondController ] } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'Hello' } ) ; } ) ; it ( 'throws an error if there is an invalid controller' , ( ) => { class HomeController { @ httpGet ( '/' ) index ( ) { return 'Hello' ; } } expect . assertions ( 1 ) ; try { tachijs ( { controllers : [ HomeController ] } ) ; } catch ( error ) { expect ( error ) . toMatchObject ( { message : 'Please apply @controller decorator to "HomeController".' } ) ; } } ) ; it ( 'accepts express app' , async ( ) => { const app = express ( ) ; app . use ( '*' , ( req , res ) => res . send ( 'Hello' ) ) ; tachijs ( { app } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'Hello' } ) ; } ) ; it ( 'registers before middleware' , async ( ) => { const before = expressApp => { expressApp . use ( '*' , ( req , res ) => res . send ( 'Hello' ) ) ; } ; const app = tachijs ( { before } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'Hello' } ) ; } ) ; it ( 'registers after middleware' , async ( ) => { const before = expressApp => { expressApp . use ( '*' , ( req , res , next ) => next ( new Error ( 'Error!' ) ) ) ; } ; const errorHandler = ( error , req , res , next ) => res . status ( 500 ) . send ( error . message ) ; const after = expressApp => { expressApp . use ( errorHandler ) ; } ; const app = tachijs ( { before , after } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 500 , text : 'Error!' } ) ; } ) ; it ( 'registers container' , async ( ) => { enum ServiceTypes { MyService = 'MyService' } class MyService { sayHello ( ) { return 'Hello' ; } } const container = { [ ServiceTypes . MyService ] : MyService } ; @ controller ( '/' ) class HomeController { constructor ( @ inject ( ServiceTypes . MyService ) private myService ) { } @ httpGet ( '/' ) index ( ) { return this . myService . sayHello ( ) ; } } const app = tachijs ( { controllers : [ HomeController ] , container } ) ; const response = await request ( app ) . get ( '/' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'Hello' } ) ; } ) ; it ( 'throws if correspond constructor does not exist in container' , async ( ) => { enum ServiceTypes { MyService = 'MyService' } class MyService { sayHello ( ) { return 'Hello' ; } } const container = { } ; @ controller ( '/' ) class HomeController { constructor ( @ inject ( ServiceTypes . MyService ) private myService ) { } @ httpGet ( '/' ) index ( ) { return this . myService . sayHello ( ) ; } } const after = expressApp => { const handler = ( error , req , res , next ) => { res . status ( 500 ) . json ( { message : error . message } ) ; } ; expressApp . use ( handler ) ; } ; const app = tachijs ( { after , controllers : [ HomeController ] , container } ) ; expect . assertions ( 1 ) ; const response = await request ( app ) . get ( '/?message=test' ) ; expect ( response ) . toMatchObject ( { status : 500 , text : JSON . stringify ( { message : 'No service is registered for "MyService" key. (While instantiating "HomeController")' } ) } ) ; } ) ; it ( 'exposes context if controller is extended from BaseController' , async ( ) => { @ controller ( '/' ) class HomeController extends BaseController { @ httpGet ( '/' ) index ( ) { return this . context ! . req . query . message ; } } const app = tachijs ( { controllers : [ HomeController ] } ) ; const response = await request ( app ) . get ( '/?message=test' ) ; expect ( response ) . toMatchObject ( { status : 200 , text : 'test' } ) ; } ) ; } ) ;