@@ -56,6 +56,8 @@ const QueryRootType = new GraphQLObjectType({
56
56
} ) ;
57
57
58
58
const TestSchema = new GraphQLSchema ( {
59
+ experimentalDefer : true ,
60
+ experimentalStream : true ,
59
61
query : QueryRootType ,
60
62
mutation : new GraphQLObjectType ( {
61
63
name : 'MutationRoot' ,
@@ -1027,6 +1029,54 @@ function runTests(server: Server) {
1027
1029
errors : [ { message : 'Must provide query string.' } ] ,
1028
1030
} ) ;
1029
1031
} ) ;
1032
+
1033
+ it ( 'allows for streaming results with @defer' , async ( ) => {
1034
+ const app = server ( ) ;
1035
+
1036
+ app . post (
1037
+ urlString ( ) ,
1038
+ graphqlHTTP ( {
1039
+ schema : TestSchema ,
1040
+ } ) ,
1041
+ ) ;
1042
+
1043
+ const req = app
1044
+ . request ( )
1045
+ . post ( urlString ( ) )
1046
+ . send ( {
1047
+ query :
1048
+ '{ ...frag @defer(label: "deferLabel") } fragment frag on QueryRoot { test(who: "World") }' ,
1049
+ } )
1050
+ . parse ( ( res , cb ) => {
1051
+ res . on ( 'data' , ( data ) => {
1052
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1053
+ } ) ;
1054
+ res . on ( 'end' , ( err ) => {
1055
+ cb ( err , null ) ;
1056
+ } ) ;
1057
+ } ) ;
1058
+
1059
+ const response = await req ;
1060
+ expect ( response . text ) . to . equal (
1061
+ [
1062
+ '' ,
1063
+ '---' ,
1064
+ 'Content-Type: application/json; charset=utf-8' ,
1065
+ 'Content-Length: 26' ,
1066
+ '' ,
1067
+ '{"data":{},"hasNext":true}' ,
1068
+ '' ,
1069
+ '---' ,
1070
+ 'Content-Type: application/json; charset=utf-8' ,
1071
+ 'Content-Length: 78' ,
1072
+ '' ,
1073
+ '{"data":{"test":"Hello World"},"path":[],"label":"deferLabel","hasNext":false}' ,
1074
+ '' ,
1075
+ '-----' ,
1076
+ '' ,
1077
+ ] . join ( '\r\n' ) ,
1078
+ ) ;
1079
+ } ) ;
1030
1080
} ) ;
1031
1081
1032
1082
describe ( 'Pretty printing' , ( ) => {
@@ -1109,6 +1159,62 @@ function runTests(server: Server) {
1109
1159
1110
1160
expect ( unprettyResponse . text ) . to . equal ( '{"data":{"test":"Hello World"}}' ) ;
1111
1161
} ) ;
1162
+ it ( 'supports pretty printing async iterable requests' , async ( ) => {
1163
+ const app = server ( ) ;
1164
+
1165
+ app . post (
1166
+ urlString ( ) ,
1167
+ graphqlHTTP ( {
1168
+ schema : TestSchema ,
1169
+ pretty : true ,
1170
+ } ) ,
1171
+ ) ;
1172
+
1173
+ const req = app
1174
+ . request ( )
1175
+ . post ( urlString ( ) )
1176
+ . send ( {
1177
+ query :
1178
+ '{ ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
1179
+ } )
1180
+ . parse ( ( res , cb ) => {
1181
+ res . on ( 'data' , ( data ) => {
1182
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1183
+ } ) ;
1184
+ res . on ( 'end' , ( err ) => {
1185
+ cb ( err , null ) ;
1186
+ } ) ;
1187
+ } ) ;
1188
+
1189
+ const response = await req ;
1190
+ expect ( response . text ) . to . equal (
1191
+ [
1192
+ '' ,
1193
+ '---' ,
1194
+ 'Content-Type: application/json; charset=utf-8' ,
1195
+ 'Content-Length: 35' ,
1196
+ '' ,
1197
+ [ '{' , ' "data": {},' , ' "hasNext": true' , '}' ] . join ( '\n' ) ,
1198
+ '' ,
1199
+ '---' ,
1200
+ 'Content-Type: application/json; charset=utf-8' ,
1201
+ 'Content-Length: 79' ,
1202
+ '' ,
1203
+ [
1204
+ '{' ,
1205
+ ' "data": {' ,
1206
+ ' "test": "Hello World"' ,
1207
+ ' },' ,
1208
+ ' "path": [],' ,
1209
+ ' "hasNext": false' ,
1210
+ '}' ,
1211
+ ] . join ( '\n' ) ,
1212
+ '' ,
1213
+ '-----' ,
1214
+ '' ,
1215
+ ] . join ( '\r\n' ) ,
1216
+ ) ;
1217
+ } ) ;
1112
1218
} ) ;
1113
1219
1114
1220
it ( 'will send request and response when using thunk' , async ( ) => {
@@ -1229,6 +1335,108 @@ function runTests(server: Server) {
1229
1335
} ) ;
1230
1336
} ) ;
1231
1337
1338
+ it ( 'allows for custom error formatting in initial payload of async iterator' , async ( ) => {
1339
+ const app = server ( ) ;
1340
+
1341
+ app . post (
1342
+ urlString ( ) ,
1343
+ graphqlHTTP ( {
1344
+ schema : TestSchema ,
1345
+ customFormatErrorFn ( error ) {
1346
+ return { message : 'Custom error format: ' + error . message } ;
1347
+ } ,
1348
+ } ) ,
1349
+ ) ;
1350
+
1351
+ const req = app
1352
+ . request ( )
1353
+ . post ( urlString ( ) )
1354
+ . send ( {
1355
+ query :
1356
+ '{ thrower, ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
1357
+ } )
1358
+ . parse ( ( res , cb ) => {
1359
+ res . on ( 'data' , ( data ) => {
1360
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1361
+ } ) ;
1362
+ res . on ( 'end' , ( err ) => {
1363
+ cb ( err , null ) ;
1364
+ } ) ;
1365
+ } ) ;
1366
+
1367
+ const response = await req ;
1368
+ expect ( response . text ) . to . equal (
1369
+ [
1370
+ '' ,
1371
+ '---' ,
1372
+ 'Content-Type: application/json; charset=utf-8' ,
1373
+ 'Content-Length: 94' ,
1374
+ '' ,
1375
+ '{"errors":[{"message":"Custom error format: Throws!"}],"data":{"thrower":null},"hasNext":true}' ,
1376
+ '' ,
1377
+ '---' ,
1378
+ 'Content-Type: application/json; charset=utf-8' ,
1379
+ 'Content-Length: 57' ,
1380
+ '' ,
1381
+ '{"data":{"test":"Hello World"},"path":[],"hasNext":false}' ,
1382
+ '' ,
1383
+ '-----' ,
1384
+ '' ,
1385
+ ] . join ( '\r\n' ) ,
1386
+ ) ;
1387
+ } ) ;
1388
+
1389
+ it ( 'allows for custom error formatting in subsequent payloads of async iterator' , async ( ) => {
1390
+ const app = server ( ) ;
1391
+
1392
+ app . post (
1393
+ urlString ( ) ,
1394
+ graphqlHTTP ( {
1395
+ schema : TestSchema ,
1396
+ customFormatErrorFn ( error ) {
1397
+ return { message : 'Custom error format: ' + error . message } ;
1398
+ } ,
1399
+ } ) ,
1400
+ ) ;
1401
+
1402
+ const req = app
1403
+ . request ( )
1404
+ . post ( urlString ( ) )
1405
+ . send ( {
1406
+ query :
1407
+ '{ test(who: "World"), ...frag @defer } fragment frag on QueryRoot { thrower }' ,
1408
+ } )
1409
+ . parse ( ( res , cb ) => {
1410
+ res . on ( 'data' , ( data ) => {
1411
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1412
+ } ) ;
1413
+ res . on ( 'end' , ( err ) => {
1414
+ cb ( err , null ) ;
1415
+ } ) ;
1416
+ } ) ;
1417
+
1418
+ const response = await req ;
1419
+ expect ( response . text ) . to . equal (
1420
+ [
1421
+ '' ,
1422
+ '---' ,
1423
+ 'Content-Type: application/json; charset=utf-8' ,
1424
+ 'Content-Length: 46' ,
1425
+ '' ,
1426
+ '{"data":{"test":"Hello World"},"hasNext":true}' ,
1427
+ '' ,
1428
+ '---' ,
1429
+ 'Content-Type: application/json; charset=utf-8' ,
1430
+ 'Content-Length: 105' ,
1431
+ '' ,
1432
+ '{"data":{"thrower":null},"path":[],"errors":[{"message":"Custom error format: Throws!"}],"hasNext":false}' ,
1433
+ '' ,
1434
+ '-----' ,
1435
+ '' ,
1436
+ ] . join ( '\r\n' ) ,
1437
+ ) ;
1438
+ } ) ;
1439
+
1232
1440
it ( 'allows for custom error formatting to elaborate' , async ( ) => {
1233
1441
const app = server ( ) ;
1234
1442
@@ -2220,6 +2428,57 @@ function runTests(server: Server) {
2220
2428
} ) ;
2221
2429
} ) ;
2222
2430
2431
+ it ( 'allows for custom extensions in initial and subsequent payloads of async iterator' , async ( ) => {
2432
+ const app = server ( ) ;
2433
+
2434
+ app . post (
2435
+ urlString ( ) ,
2436
+ graphqlHTTP ( {
2437
+ schema : TestSchema ,
2438
+ extensions ( { result } ) {
2439
+ return { preservedResult : { ...result } } ;
2440
+ } ,
2441
+ } ) ,
2442
+ ) ;
2443
+
2444
+ const req = app
2445
+ . request ( )
2446
+ . post ( urlString ( ) )
2447
+ . send ( {
2448
+ query :
2449
+ '{ hello: test(who: "Rob"), ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
2450
+ } )
2451
+ . parse ( ( res , cb ) => {
2452
+ res . on ( 'data' , ( data ) => {
2453
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
2454
+ } ) ;
2455
+ res . on ( 'end' , ( err ) => {
2456
+ cb ( err , null ) ;
2457
+ } ) ;
2458
+ } ) ;
2459
+
2460
+ const response = await req ;
2461
+ expect ( response . text ) . to . equal (
2462
+ [
2463
+ '' ,
2464
+ '---' ,
2465
+ 'Content-Type: application/json; charset=utf-8' ,
2466
+ 'Content-Length: 124' ,
2467
+ '' ,
2468
+ '{"data":{"hello":"Hello Rob"},"hasNext":true,"extensions":{"preservedResult":{"data":{"hello":"Hello Rob"},"hasNext":true}}}' ,
2469
+ '' ,
2470
+ '---' ,
2471
+ 'Content-Type: application/json; charset=utf-8' ,
2472
+ 'Content-Length: 148' ,
2473
+ '' ,
2474
+ '{"data":{"test":"Hello World"},"path":[],"hasNext":false,"extensions":{"preservedResult":{"data":{"test":"Hello World"},"path":[],"hasNext":false}}}' ,
2475
+ '' ,
2476
+ '-----' ,
2477
+ '' ,
2478
+ ] . join ( '\r\n' ) ,
2479
+ ) ;
2480
+ } ) ;
2481
+
2223
2482
it ( 'extension function may be async' , async ( ) => {
2224
2483
const app = server ( ) ;
2225
2484
@@ -2260,12 +2519,44 @@ function runTests(server: Server) {
2260
2519
2261
2520
const response = await app
2262
2521
. request ( )
2263
- . get ( urlString ( { query : '{test}' , raw : '' } ) )
2264
- . set ( 'Accept' , 'text/html' ) ;
2522
+ . get (
2523
+ urlString ( {
2524
+ query :
2525
+ '{ hello: test(who: "Rob"), ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
2526
+ raw : '' ,
2527
+ } ) ,
2528
+ )
2529
+ . set ( 'Accept' , 'text/html' )
2530
+ . parse ( ( res , cb ) => {
2531
+ res . on ( 'data' , ( data ) => {
2532
+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
2533
+ } ) ;
2534
+ res . on ( 'end' , ( err ) => {
2535
+ cb ( err , null ) ;
2536
+ } ) ;
2537
+ } ) ;
2265
2538
2266
2539
expect ( response . status ) . to . equal ( 200 ) ;
2267
- expect ( response . type ) . to . equal ( 'application/json' ) ;
2268
- expect ( response . text ) . to . equal ( '{"data":{"test":"Hello World"}}' ) ;
2540
+ expect ( response . type ) . to . equal ( 'multipart/mixed' ) ;
2541
+ expect ( response . text ) . to . equal (
2542
+ [
2543
+ '' ,
2544
+ '---' ,
2545
+ 'Content-Type: application/json; charset=utf-8' ,
2546
+ 'Content-Length: 45' ,
2547
+ '' ,
2548
+ '{"data":{"hello":"Hello Rob"},"hasNext":true}' ,
2549
+ '' ,
2550
+ '---' ,
2551
+ 'Content-Type: application/json; charset=utf-8' ,
2552
+ 'Content-Length: 57' ,
2553
+ '' ,
2554
+ '{"data":{"test":"Hello World"},"path":[],"hasNext":false}' ,
2555
+ '' ,
2556
+ '-----' ,
2557
+ '' ,
2558
+ ] . join ( '\r\n' ) ,
2559
+ ) ;
2269
2560
} ) ;
2270
2561
} ) ;
2271
2562
}
0 commit comments