import { Resolver , schemaComposer , ObjectTypeComposer } from 'graphql-compose' ; import { UserModel , IUser } from '../../__mocks__/userModel' ; import { PostModel , IPost } from '../../__mocks__/postModel' ; import { mongoose } from '../../__mocks__/mongooseCommon' ; import { dataLoaderMany } from '../dataLoaderMany' ; import { convertModelToGraphQL } from '../../fieldsConverter' ; import { ExtendedResolveParams } from '..' ; import { GraphQLResolveInfo } from 'graphql' ; beforeAll ( ( ) => UserModel . base . createConnection ( ) ) ; afterAll ( ( ) => UserModel . base . disconnect ( ) ) ; const info = { fieldNodes : { } } as GraphQLResolveInfo ; describe ( 'dataLoaderMany() ->' , ( ) => { let UserTC ; let PostTypeComposer ; beforeEach ( ( ) => { schemaComposer . clear ( ) ; UserTC = convertModelToGraphQL ( UserModel , 'User' , schemaComposer ) ; PostTypeComposer = convertModelToGraphQL ( PostModel , 'Post' , schemaComposer ) ; } ) ; let user ; let user2 ; let post ; beforeEach ( async ( ) => { await UserModel . deleteMany ( { } ) ; user = new UserModel ( { name : 'nodkz' , contacts : { email : 'mail' } } ) ; await user . save ( ) ; user2 = new UserModel ( { name : 'user2' , contacts : { email : 'mail2' } } ) ; await user2 . save ( ) ; await PostModel . deleteMany ( { } ) ; post = new PostModel ( { _id : 1 , title : 'Post 1' } ) ; await post . save ( ) ; } ) ; it ( 'should return Resolver object' , ( ) => { const resolver = dataLoaderMany ( UserModel , UserTC ) ; expect ( resolver ) . toBeInstanceOf ( Resolver ) ; } ) ; describe ( 'Resolver.args' , ( ) => { it ( 'should have non-null `_id` arg' , ( ) => { const resolver = dataLoaderMany ( UserModel , UserTC ) ; expect ( resolver . getArgTypeName ( '_ids' ) ) . toBe ( '[MongoID!]!' ) ; } ) ; } ) ; describe ( 'Resolver.resolve():Promise' , ( ) => { it ( 'should be fulfilled promise' , async ( ) => { const result = dataLoaderMany ( UserModel , UserTC ) . resolve ( { } ) ; await expect ( result ) . resolves . toBeDefined ( ) ; } ) ; it ( 'should return Error if args.ids contains incorrect ObjectId' , async ( ) => { const result = await dataLoaderMany ( UserModel , UserTC ) . resolve ( { args : { _ids : [ 1 ] } , context : { } , info , } ) ; expect ( result [ 0 ] ) . toBeInstanceOf ( Error ) ; expect ( result [ 0 ] . message ) . toMatch ( 'Cast to ObjectId failed' ) ; } ) ; it ( 'should return null if args.ids is empty' , async ( ) => { const result = await dataLoaderMany ( UserModel , UserTC ) . resolve ( { } ) ; expect ( result ) . toEqual ( [ ] ) ; } ) ; it ( 'should return document if provided existed id' , async ( ) => { const result = await dataLoaderMany ( UserModel , UserTC ) . resolve ( { args : { _ids : [ user . _id ] } , context : { } , info , } ) ; expect ( result [ 0 ] . name ) . toBe ( user . name ) ; } ) ; it ( 'should return mongoose document' , async ( ) => { const result = await dataLoaderMany ( UserModel , UserTC ) . resolve ( { args : { _ids : [ user . _id ] } , context : { } , info , } ) ; expect ( result [ 0 ] ) . toBeInstanceOf ( UserModel ) ; } ) ; it ( 'should return lean objects from DB' , async ( ) => { const result = await dataLoaderMany ( UserModel , UserTC , { lean : true } ) . resolve ( { args : { _ids : [ user . _id ] } , context : { } , info , } ) ; expect ( result [ 0 ] ) . not . toBeInstanceOf ( UserModel ) ; } ) ; it ( 'should return mongoose Post document' , async ( ) => { const result = await dataLoaderMany ( PostModel , PostTypeComposer ) . resolve ( { args : { _ids : [ 1 ] } , context : { } , info , } ) ; expect ( result [ 0 ] ) . toBeInstanceOf ( PostModel ) ; } ) ; it ( 'should return lean Post object from DB' , async ( ) => { const result = await dataLoaderMany ( PostModel , PostTypeComposer , { lean : true } ) . resolve ( { args : { _ids : [ 1 ] } , context : { } , info , } ) ; expect ( result [ 0 ] ) . not . toBeInstanceOf ( PostModel ) ; } ) ; it ( 'should call `beforeQuery` method with non-executed `query` as arg' , async ( ) => { const result = await dataLoaderMany ( PostModel , PostTypeComposer ) . resolve ( { args : { _ids : [ 1 ] } , context : { } , info , beforeQuery : ( query , rp ) => { expect ( query ) . toHaveProperty ( 'exec' ) ; expect ( rp . model ) . toBe ( PostModel ) ; return [ { _id : 1 , overridden : true } ] ; } , } ) ; expect ( result ) . toEqual ( [ { _id : 1 , overridden : true } ] ) ; } ) ; } ) ; it ( 'check DataLoader batch logic' , async ( ) => { let conditions ; const resolveParams = { context : { } , info , beforeQuery : ( query ) => { conditions = query . _conditions ; } , } ; const resolver = dataLoaderMany ( UserModel , UserTC ) ; const resultPromise1 = resolver . resolve ( { args : { _ids : [ user2 . _id , user . _id ] } , ... resolveParams , } ) ; const resultPromise2 = resolver . resolve ( { args : { _ids : [ user . _id ] } , ... resolveParams , } ) ; const nonExistedId = new mongoose . Types . ObjectId ( '5cefda4616156200084e5170' ) ; const resultPromise3 = resolver . resolve ( { args : { _ids : [ user . _id , nonExistedId ] } , ... resolveParams , } ) ; expect ( ( await resultPromise1 ) . map ( ( o ) => o . name ) ) . toEqual ( [ 'user2' , 'nodkz' ] ) ; expect ( ( await resultPromise2 ) . map ( ( o ) => o . name ) ) . toEqual ( [ 'nodkz' ] ) ; expect ( ( await resultPromise3 ) . map ( ( o ) => o ?. name ) ) . toEqual ( [ 'nodkz' , undefined ] ) ; expect ( conditions ) . toEqual ( { _id : { $in : [ user2 . _id , user . _id , nonExistedId ] } , } ) ; } ) ; it ( 'check aliases for lean records' , async ( ) => { const resolver = dataLoaderMany ( UserModel , UserTC , { lean : true } ) ; const resultPromise1 = resolver . resolve ( { args : { _ids : [ user2 . _id , user . _id ] } , context : { } , info , } ) ; expect ( ( await resultPromise1 ) . map ( ( o ) => o . name ) ) . toEqual ( [ 'user2' , 'nodkz' ] ) ; } ) ; } ) ;