11import { expect } from 'chai' ;
22import { describe , it } from 'mocha' ;
33
4+ import { expectJSON } from '../../__testUtils__/expectJSON.js' ;
5+
46import { parse } from '../../language/parser.js' ;
57
68import {
@@ -12,7 +14,7 @@ import {
1214import { GraphQLBoolean , GraphQLString } from '../../type/scalars.js' ;
1315import { GraphQLSchema } from '../../type/schema.js' ;
1416
15- import { executeSync } from '../execute.js' ;
17+ import { execute , executeSync } from '../execute.js' ;
1618
1719class Dog {
1820 name : string ;
@@ -42,19 +44,30 @@ class Cat {
4244 }
4345}
4446
47+ class Plant {
48+ name : string ;
49+
50+ constructor ( name : string ) {
51+ this . name = name ;
52+ }
53+ }
54+
4555class Person {
4656 name : string ;
4757 pets : ReadonlyArray < Dog | Cat > | undefined ;
4858 friends : ReadonlyArray < Dog | Cat | Person > | undefined ;
59+ responsibilities : ReadonlyArray < Dog | Cat | Plant > | undefined ;
4960
5061 constructor (
5162 name : string ,
5263 pets ?: ReadonlyArray < Dog | Cat > ,
5364 friends ?: ReadonlyArray < Dog | Cat | Person > ,
65+ responsibilities ?: ReadonlyArray < Dog | Cat | Plant > ,
5466 ) {
5567 this . name = name ;
5668 this . pets = pets ;
5769 this . friends = friends ;
70+ this . responsibilities = responsibilities ;
5871 }
5972}
6073
@@ -108,6 +121,18 @@ const CatType: GraphQLObjectType = new GraphQLObjectType({
108121 isTypeOf : ( value ) => value instanceof Cat ,
109122} ) ;
110123
124+ const PlantType : GraphQLObjectType = new GraphQLObjectType ( {
125+ name : 'Plant' ,
126+ interfaces : [ NamedType ] ,
127+ fields : ( ) => ( {
128+ name : { type : GraphQLString } ,
129+ } ) ,
130+ // eslint-disable-next-line @typescript-eslint/require-await
131+ isTypeOf : async ( ) => {
132+ throw new Error ( 'Not sure if this is a plant' ) ;
133+ } ,
134+ } ) ;
135+
111136const PetType = new GraphQLUnionType ( {
112137 name : 'Pet' ,
113138 types : [ DogType , CatType ] ,
@@ -124,13 +149,19 @@ const PetType = new GraphQLUnionType({
124149 } ,
125150} ) ;
126151
152+ const PetOrPlantType = new GraphQLUnionType ( {
153+ name : 'PetOrPlantType' ,
154+ types : [ PlantType , DogType , CatType ] ,
155+ } ) ;
156+
127157const PersonType : GraphQLObjectType = new GraphQLObjectType ( {
128158 name : 'Person' ,
129159 interfaces : [ NamedType , MammalType , LifeType ] ,
130160 fields : ( ) => ( {
131161 name : { type : GraphQLString } ,
132162 pets : { type : new GraphQLList ( PetType ) } ,
133163 friends : { type : new GraphQLList ( NamedType ) } ,
164+ responsibilities : { type : new GraphQLList ( PetOrPlantType ) } ,
134165 progeny : { type : new GraphQLList ( PersonType ) } ,
135166 mother : { type : PersonType } ,
136167 father : { type : PersonType } ,
@@ -151,8 +182,14 @@ const odie = new Dog('Odie', true);
151182odie . mother = new Dog ( "Odie's Mom" , true ) ;
152183odie . mother . progeny = [ odie ] ;
153184
185+ const fern = new Plant ( 'Fern' ) ;
154186const liz = new Person ( 'Liz' ) ;
155- const john = new Person ( 'John' , [ garfield , odie ] , [ liz , odie ] ) ;
187+ const john = new Person (
188+ 'John' ,
189+ [ garfield , odie ] ,
190+ [ liz , odie ] ,
191+ [ garfield , fern ] ,
192+ ) ;
156193
157194describe ( 'Execute: Union and intersection types' , ( ) => {
158195 it ( 'can introspect on union and intersection types' , ( ) => {
@@ -195,7 +232,12 @@ describe('Execute: Union and intersection types', () => {
195232 name : 'Named' ,
196233 fields : [ { name : 'name' } ] ,
197234 interfaces : [ ] ,
198- possibleTypes : [ { name : 'Dog' } , { name : 'Cat' } , { name : 'Person' } ] ,
235+ possibleTypes : [
236+ { name : 'Dog' } ,
237+ { name : 'Cat' } ,
238+ { name : 'Person' } ,
239+ { name : 'Plant' } ,
240+ ] ,
199241 enumValues : null ,
200242 inputFields : null ,
201243 } ,
@@ -545,4 +587,50 @@ describe('Execute: Union and intersection types', () => {
545587 expect ( encounteredRootValue ) . to . equal ( rootValue ) ;
546588 expect ( encounteredContext ) . to . equal ( contextValue ) ;
547589 } ) ;
590+
591+ it ( 'it handles rejections from isTypeOf after after an isTypeOf returns true' , async ( ) => {
592+ const document = parse ( `
593+ {
594+ responsibilities {
595+ __typename
596+ ... on Dog {
597+ name
598+ barks
599+ }
600+ ... on Cat {
601+ name
602+ meows
603+ }
604+ }
605+ }
606+ ` ) ;
607+
608+ const rootValue = new Person ( 'John' , [ ] , [ liz ] , [ garfield ] ) ;
609+ const contextValue = { authToken : '123abc' } ;
610+
611+ /* c8 ignore next 4 */
612+ // eslint-disable-next-line no-undef
613+ process . on ( 'unhandledRejection' , ( ) => {
614+ expect . fail ( 'Unhandled rejection' ) ;
615+ } ) ;
616+
617+ const result = await execute ( {
618+ schema,
619+ document,
620+ rootValue,
621+ contextValue,
622+ } ) ;
623+
624+ expectJSON ( result ) . toDeepEqual ( {
625+ data : {
626+ responsibilities : [
627+ {
628+ __typename : 'Cat' ,
629+ meows : false ,
630+ name : 'Garfield' ,
631+ } ,
632+ ] ,
633+ } ,
634+ } ) ;
635+ } ) ;
548636} ) ;
0 commit comments