11package graphql
22
3-
43import graphql.schema.DataFetcher
54import org.awaitility.Awaitility
65import org.dataloader.BatchLoader
@@ -9,16 +8,20 @@ import org.dataloader.DataLoaderFactory
98import org.dataloader.DataLoaderRegistry
109import spock.lang.RepeatUntilFailure
1110import spock.lang.Specification
11+ import spock.lang.Unroll
1212
13+ import java.util.concurrent.ExecutionException
1314import java.util.concurrent.atomic.AtomicInteger
1415
1516import static graphql.ExecutionInput.newExecutionInput
1617import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.setEnableDataLoaderChaining
18+ import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.setEnableDataLoaderExhaustedDispatching
1719import static java.util.concurrent.CompletableFuture.supplyAsync
1820
1921class ChainedDataLoaderTest extends Specification {
2022
2123
24+ @Unroll
2225 def " chained data loaders" () {
2326 given :
2427 def sdl = '''
@@ -69,7 +72,7 @@ class ChainedDataLoaderTest extends Specification {
6972
7073 def query = " { dogName catName } "
7174 def ei = newExecutionInput(query). dataLoaderRegistry(dataLoaderRegistry). build()
72- setEnableDataLoaderChaining(ei. graphQLContext, true )
75+ chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei . graphQLContext, true ) : setEnableDataLoaderExhaustedDispatching (ei. graphQLContext, true )
7376
7477 when :
7578 def efCF = graphQL. executeAsync(ei)
@@ -78,8 +81,12 @@ class ChainedDataLoaderTest extends Specification {
7881 then :
7982 er. data == [dogName : " Luna" , catName : " Tiger" ]
8083 batchLoadCalls == 2
84+
85+ where :
86+ chainedDataLoaderOrExhaustedDispatcher << [true , false ]
8187 }
8288
89+ @Unroll
8390 @RepeatUntilFailure (maxAttempts = 20 , ignoreRest = false )
8491 def " parallel different data loaders" () {
8592 given :
@@ -161,7 +168,7 @@ class ChainedDataLoaderTest extends Specification {
161168
162169 def query = " { hello helloDelayed} "
163170 def ei = newExecutionInput(query). dataLoaderRegistry(dataLoaderRegistry). build()
164- setEnableDataLoaderChaining(ei. graphQLContext, true )
171+ chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei . graphQLContext, true ) : setEnableDataLoaderExhaustedDispatching (ei. graphQLContext, true )
165172
166173 when :
167174 def efCF = graphQL. executeAsync(ei)
@@ -171,9 +178,14 @@ class ChainedDataLoaderTest extends Specification {
171178 er. data == [hello : " friendsLunakey1Skipperkey2" , helloDelayed : " friendsLunakey1-delayedSkipperkey2-delayed" ]
172179 batchLoadCalls. get() == 6
173180
181+ where :
182+ chainedDataLoaderOrExhaustedDispatcher << [true , false ]
183+
184+
174185 }
175186
176187
188+ @Unroll
177189 def " more complicated chained data loader for one DF" () {
178190 given :
179191 def sdl = '''
@@ -251,7 +263,7 @@ class ChainedDataLoaderTest extends Specification {
251263
252264 def query = " { foo } "
253265 def ei = newExecutionInput(query). dataLoaderRegistry(dataLoaderRegistry). build()
254- setEnableDataLoaderChaining(ei. graphQLContext, true )
266+ chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei . graphQLContext, true ) : setEnableDataLoaderExhaustedDispatching (ei. graphQLContext, true )
255267
256268 when :
257269 def efCF = graphQL. executeAsync(ei)
@@ -261,9 +273,13 @@ class ChainedDataLoaderTest extends Specification {
261273 er. data == [foo : " start-batchloader1-otherCF1-otherCF2-start-batchloader1-batchloader2-apply" ]
262274 batchLoadCalls1 == 1
263275 batchLoadCalls2 == 1
276+ where :
277+ chainedDataLoaderOrExhaustedDispatcher << [true , false ]
278+
264279 }
265280
266281
282+ @Unroll
267283 def " chained data loaders with an delayed data loader" () {
268284 given :
269285 def sdl = '''
@@ -320,7 +336,7 @@ class ChainedDataLoaderTest extends Specification {
320336
321337 def query = " { dogName catName } "
322338 def ei = newExecutionInput(query). dataLoaderRegistry(dataLoaderRegistry). build()
323- setEnableDataLoaderChaining(ei. graphQLContext, true )
339+ chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei . graphQLContext, true ) : setEnableDataLoaderExhaustedDispatching (ei. graphQLContext, true )
324340
325341 when :
326342 def efCF = graphQL. executeAsync(ei)
@@ -329,8 +345,12 @@ class ChainedDataLoaderTest extends Specification {
329345 then :
330346 er. data == [dogName : " Luna2" , catName : " Tiger2" ]
331347 batchLoadCalls == 3
348+ where :
349+ chainedDataLoaderOrExhaustedDispatcher << [true , false ]
350+
332351 }
333352
353+ @Unroll
334354 def " chained data loaders with two delayed data loaders" () {
335355 given :
336356 def sdl = '''
@@ -382,7 +402,7 @@ class ChainedDataLoaderTest extends Specification {
382402
383403 def eiBuilder = ExecutionInput . newExecutionInput(query)
384404 def ei = eiBuilder. dataLoaderRegistry(dataLoaderRegistry). build()
385- setEnableDataLoaderChaining(ei. graphQLContext, true );
405+ chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei. graphQLContext, true ) : setEnableDataLoaderExhaustedDispatching(ei . graphQLContext, true )
386406
387407
388408 when :
@@ -392,6 +412,10 @@ class ChainedDataLoaderTest extends Specification {
392412 then :
393413 er. data == [foo : " fooFirstValue" , bar : " barFirstValue" ]
394414 batchLoadCalls. get() == 1 || batchLoadCalls. get() == 2 // depending on timing, it can be 1 or 2 calls
415+
416+ where :
417+ chainedDataLoaderOrExhaustedDispatcher << [true , false ]
418+
395419 }
396420
397421 def " handling of chained DataLoaders is disabled by default" () {
@@ -454,4 +478,31 @@ class ChainedDataLoaderTest extends Specification {
454478 }
455479
456480
481+ def " setting chained and exhausted at the same time caused error" () {
482+ given :
483+ def sdl = '''
484+
485+ type Query {
486+ echo:String
487+ }
488+ '''
489+ def schema = TestUtil . schema(sdl, [:])
490+ def graphQL = GraphQL . newGraphQL(schema). build()
491+
492+ def query = " {echo} "
493+ def ei = newExecutionInput(query). dataLoaderRegistry(new DataLoaderRegistry ()). build()
494+ setEnableDataLoaderChaining(ei. graphQLContext, true )
495+ setEnableDataLoaderExhaustedDispatching(ei. graphQLContext, true )
496+
497+
498+ when :
499+ def er = graphQL. executeAsync(ei)
500+ er. get()
501+
502+ then :
503+ def e = thrown(ExecutionException )
504+ e. getCause(). getMessage() == " enabling data loader chaining and exhausted dispatching at the same time ambiguous"
505+ }
506+
507+
457508}
0 commit comments