@@ -143,7 +143,7 @@ const PetType = new GraphQLUnionType({
143143    if  ( value  instanceof  Cat )  { 
144144      return  CatType . name ; 
145145    } 
146-      /* c8 ignore next 3 */ 
146+ 
147147    // Not reachable, all possible types have been considered. 
148148    expect . fail ( 'Not reachable' ) ; 
149149  } , 
@@ -191,6 +191,70 @@ const john = new Person(
191191  [ garfield ,  fern ] , 
192192) ; 
193193
194+ const  SearchableInterface  =  new  GraphQLInterfaceType ( { 
195+   name : 'Searchable' , 
196+   fields : { 
197+     id : {  type : GraphQLString  } , 
198+   } , 
199+ } ) ; 
200+ 
201+ const  TypeA  =  new  GraphQLObjectType ( { 
202+   name : 'TypeA' , 
203+   interfaces : [ SearchableInterface ] , 
204+   fields : ( )  =>  ( { 
205+     id : {  type : GraphQLString  } , 
206+     nameA : {  type : GraphQLString  } , 
207+   } ) , 
208+   isTypeOf : ( _value ,  _context ,  _info )  => 
209+     new  Promise ( ( _resolve ,  reject )  => 
210+       setTimeout ( ( )  =>  reject ( new  Error ( 'TypeA_isTypeOf_rejected' ) ) ,  10 ) , 
211+     ) , 
212+ } ) ; 
213+ 
214+ const  TypeB  =  new  GraphQLObjectType ( { 
215+   name : 'TypeB' , 
216+   interfaces : [ SearchableInterface ] , 
217+   fields : ( )  =>  ( { 
218+     id : {  type : GraphQLString  } , 
219+     nameB : {  type : GraphQLString  } , 
220+   } ) , 
221+   isTypeOf : ( value : any ,  _context ,  _info )  =>  value . id  ===  'b' , 
222+ } ) ; 
223+ 
224+ const  queryTypeWithSearchable  =  new  GraphQLObjectType ( { 
225+   name : 'Query' , 
226+   fields : { 
227+     person : { 
228+       type : PersonType , 
229+       resolve : ( )  =>  john , 
230+     } , 
231+     search : { 
232+       type : SearchableInterface , 
233+       args : {  id : {  type : GraphQLString  }  } , 
234+       resolve : ( _source ,  {  id } )  =>  { 
235+         if  ( id  ===  'a' )  { 
236+           return  {  id : 'a' ,  nameA : 'Object A'  } ; 
237+         }  else  if  ( id  ===  'b' )  { 
238+           return  {  id : 'b' ,  nameB : 'Object B'  } ; 
239+         } 
240+       } , 
241+     } , 
242+   } , 
243+ } ) ; 
244+ 
245+ const  schemaWithSearchable  =  new  GraphQLSchema ( { 
246+   query : queryTypeWithSearchable , 
247+   types : [ 
248+     PetType , 
249+     TypeA , 
250+     TypeB , 
251+     SearchableInterface , 
252+     PersonType , 
253+     DogType , 
254+     CatType , 
255+   ] , 
256+ } ) ; 
257+ 
194258describe ( 'Execute: Union and intersection types' ,  ( )  =>  { 
195259  it ( 'can introspect on union and intersection types' ,  ( )  =>  { 
196260    const  document  =  parse ( ` 
@@ -633,4 +697,51 @@ describe('Execute: Union and intersection types', () => {
633697      } , 
634698    } ) ; 
635699  } ) ; 
700+ 
701+   it ( 'handles promises from isTypeOf correctly when a later type matches synchronously' ,  async  ( )  =>  { 
702+     const  document  =  parse ( ` 
703+       query TestSearch { 
704+         search(id: "b") { 
705+           __typename 
706+           id 
707+           ... on TypeA { 
708+             nameA 
709+           } 
710+           ... on TypeB { 
711+             nameB 
712+           } 
713+         } 
714+       } 
715+     ` ) ; 
716+ 
717+     let  unhandledRejection : any  =  null ; 
718+     const  unhandledRejectionListener  =  ( reason : any )  =>  { 
719+       unhandledRejection  =  reason ; 
720+     } ; 
721+     // eslint-disable-next-line 
722+     process . on ( 'unhandledRejection' ,  unhandledRejectionListener ) ; 
723+ 
724+     const  result  =  await  execute ( { 
725+       schema : schemaWithSearchable , 
726+       document, 
727+     } ) ; 
728+ 
729+     expect ( result . errors ) . to . equal ( undefined ) ; 
730+     expect ( result . data ) . to . deep . equal ( { 
731+       search : { 
732+         __typename : 'TypeB' , 
733+         id : 'b' , 
734+         nameB : 'Object B' , 
735+       } , 
736+     } ) ; 
737+ 
738+     // Give the TypeA promise a chance to reject and the listener to fire 
739+ 
740+     await  new  Promise ( ( resolve )  =>  setTimeout ( resolve ,  20 ) ) ; 
741+ 
742+     // eslint-disable-next-line 
743+     process . removeListener ( 'unhandledRejection' ,  unhandledRejectionListener ) ; 
744+ 
745+     expect ( unhandledRejection ) . to . equal ( null ) ; 
746+   } ) ; 
636747} ) ; 
0 commit comments