import { Binding , Context , createBindingFromClass , inject , service , } from '@loopback/core' ; import { expect } from '@loopback/testlab' ; import { GraphQLResolveInfo } from 'graphql' ; import { Arg , Field , FieldResolver , ID , Int , ObjectType , Query , Resolver , ResolverData , Root , } from 'type-graphql' ; import { GraphQLTags , LoopBackContainer } from '../..' ; describe ( 'LoopBack container for type-graphql' , ( ) => { let parentCtx ; let container ; const resolverData = { root : '' , args : { } , context : { } , info : { } as unknown as GraphQLResolveInfo , } ; beforeEach ( givenContainer ) ; it ( 'resolves from parent context' , ( ) => { parentCtx . add ( createBindingFromClass ( BookService ) ) ; parentCtx . bind ( 'graphql.resolvers.BookResolver' ) . toClass ( BookResolver ) ; const resolver = container . get ( BookResolver , resolverData ) ; expect ( resolver ) . to . be . instanceof ( BookResolver ) ; } ) ; it ( 'resolves from parent context by key' , ( ) => { parentCtx . add ( createBindingFromClass ( BookService ) ) ; parentCtx . bind ( 'graphql.resolvers.BookResolver' ) . toClass ( BookResolver ) ; parentCtx . bind ( 'graphql.resolvers.AnotherBookResolver' ) . toClass ( BookResolver ) ; const resolver = container . get ( BookResolver , resolverData ) as BookResolver ; expect ( resolver . binding . key ) . to . eql ( 'graphql.resolvers.BookResolver' ) ; } ) ; it ( 'resolves from parent context with the first binding' , ( ) => { parentCtx . add ( createBindingFromClass ( BookService ) ) ; parentCtx . bind ( 'graphql.resolvers.BookResolver1' ) . toClass ( BookResolver ) . tag ( GraphQLTags . RESOLVER ) ; parentCtx . bind ( 'graphql.resolvers.BookResolver2' ) . toClass ( BookResolver ) . tag ( GraphQLTags . RESOLVER ) ; const resolver = container . get ( BookResolver , resolverData ) as BookResolver ; expect ( resolver . binding . key ) . to . eql ( 'graphql.resolvers.BookResolver1' ) ; } ) ; it ( 'resolves from child context' , ( ) => { parentCtx . add ( createBindingFromClass ( BookService ) ) ; const resolver = container . get ( BookResolver , resolverData ) ; expect ( resolver ) . to . be . instanceof ( BookResolver ) ; expect ( parentCtx . isBound ( 'graphql.resolvers.BookResolver' ) ) . to . be . false ( ) ; } ) ; it ( 'resolves from middleware context' , ( ) => { const middlewareCtx = new Context ( 'request' ) ; middlewareCtx . bind ( 'graphql.resolvers.BookResolver' ) . toClass ( BookResolver ) ; parentCtx . add ( createBindingFromClass ( BookService ) ) ; const MIDDLEWARE_CONTEXT = Symbol . for ( 'loopback.middleware.context' ) ; const resolverDataWithMiddlewareContext = { root : '' , args : { } , context : { request : { [ MIDDLEWARE_CONTEXT ] : middlewareCtx , } , } , info : { } as unknown as GraphQLResolveInfo , } ; const resolver = container . get ( BookResolver , resolverDataWithMiddlewareContext ) ; expect ( resolver ) . to . be . instanceof ( BookResolver ) ; expect ( parentCtx . isBound ( 'graphql.resolvers.BookResolver' ) ) . to . be . false ( ) ; } ) ; @ ObjectType ( { description : 'Book' } ) class Book { @ Field ( type => ID ) id : string ; @ Field ( ) title : string ; @ Field ( type => Int ) protected numberInCollection : number ; } class BookService { static books : Record < string , Book > = { '1' : new Book ( ) , } ; getOne ( id ) { return BookService . books [ id ] ; } } @ Resolver ( of => Book ) class BookResolver { @ inject . binding ( ) readonly binding : Binding ; constructor ( @ service ( ) private readonly bookService ) { } @ Query ( returns => Book , { nullable : true } ) async book ( @ Arg ( 'bookId' ) bookId ) { return this . bookService . getOne ( bookId ) ; } @ FieldResolver ( ) numberInCollection ( @ Root ( ) book ) { return 1 ; } } function givenContainer ( ) { parentCtx = new Context ( ) ; container = new LoopBackContainer ( parentCtx ) ; } } ) ;