1
1
import zlib from 'zlib';
2
+
import type http from 'http';
2
3
3
4
import type { Server as Restify } from 'restify';
4
5
import connect from 'connect';
@@ -81,6 +82,12 @@ function urlString(urlParams?: { [param: string]: string }): string {
81
82
return string;
82
83
}
83
84
85
+
function sleep(ms = 1) {
86
+
return new Promise((r) => {
87
+
setTimeout(r, ms);
88
+
});
89
+
}
90
+
84
91
describe('GraphQL-HTTP tests for connect', () => {
85
92
runTests(() => {
86
93
const app = connect();
@@ -2389,9 +2396,7 @@ function runTests(server: Server) {
2389
2396
graphqlHTTP(() => ({
2390
2397
schema: TestSchema,
2391
2398
async *customExecuteFn() {
2392
-
await new Promise((r) => {
2393
-
setTimeout(r, 1);
2394
-
});
2399
+
await sleep();
2395
2400
yield {
2396
2401
data: {
2397
2402
test2: 'Modification',
@@ -2436,6 +2441,137 @@ function runTests(server: Server) {
2436
2441
].join('\r\n'),
2437
2442
);
2438
2443
});
2444
+
2445
+
it('calls return on underlying async iterable when connection is closed', async () => {
2446
+
const app = server();
2447
+
const fakeReturn = sinon.fake();
2448
+
2449
+
app.get(
2450
+
urlString(),
2451
+
graphqlHTTP(() => ({
2452
+
schema: TestSchema,
2453
+
// custom iterable keeps yielding until return is called
2454
+
customExecuteFn() {
2455
+
let returned = false;
2456
+
return {
2457
+
[Symbol.asyncIterator]: () => ({
2458
+
next: async () => {
2459
+
await sleep();
2460
+
if (returned) {
2461
+
return { value: undefined, done: true };
2462
+
}
2463
+
return {
2464
+
value: { data: { test: 'Hello, World' }, hasNext: true },
2465
+
done: false,
2466
+
};
2467
+
},
2468
+
return: () => {
2469
+
returned = true;
2470
+
fakeReturn();
2471
+
return Promise.resolve({ value: undefined, done: true });
2472
+
},
2473
+
}),
2474
+
};
2475
+
},
2476
+
})),
2477
+
);
2478
+
2479
+
let text = '';
2480
+
const request = app
2481
+
.request()
2482
+
.get(urlString({ query: '{test}' }))
2483
+
.parse((res, cb) => {
2484
+
res.on('data', (data) => {
2485
+
text = `${text}${data.toString('utf8') as string}`;
2486
+
((res as unknown) as http.IncomingMessage).destroy();
2487
+
cb(new Error('Aborted connection'), null);
2488
+
});
2489
+
});
2490
+
2491
+
try {
2492
+
await request;
2493
+
} catch (e: unknown) {
2494
+
// ignore aborted error
2495
+
}
2496
+
// sleep to allow time for return function to be called
2497
+
await sleep(2);
2498
+
expect(text).to.equal(
2499
+
[
2500
+
'',
2501
+
'---',
2502
+
'Content-Type: application/json; charset=utf-8',
2503
+
'Content-Length: 47',
2504
+
'',
2505
+
'{"data":{"test":"Hello, World"},"hasNext":true}',
2506
+
'',
2507
+
].join('\r\n'),
2508
+
);
2509
+
expect(fakeReturn.callCount).to.equal(1);
2510
+
});
2511
+
2512
+
it('handles return function on async iterable that throws', async () => {
2513
+
const app = server();
2514
+
2515
+
app.get(
2516
+
urlString(),
2517
+
graphqlHTTP(() => ({
2518
+
schema: TestSchema,
2519
+
// custom iterable keeps yielding until return is called
2520
+
customExecuteFn() {
2521
+
let returned = false;
2522
+
return {
2523
+
[Symbol.asyncIterator]: () => ({
2524
+
next: async () => {
2525
+
await sleep();
2526
+
if (returned) {
2527
+
return { value: undefined, done: true };
2528
+
}
2529
+
return {
2530
+
value: { data: { test: 'Hello, World' }, hasNext: true },
2531
+
done: false,
2532
+
};
2533
+
},
2534
+
return: () => {
2535
+
returned = true;
2536
+
return Promise.reject(new Error('Throws!'));
2537
+
},
2538
+
}),
2539
+
};
2540
+
},
2541
+
})),
2542
+
);
2543
+
2544
+
let text = '';
2545
+
const request = app
2546
+
.request()
2547
+
.get(urlString({ query: '{test}' }))
2548
+
.parse((res, cb) => {
2549
+
res.on('data', (data) => {
2550
+
text = `${text}${data.toString('utf8') as string}`;
2551
+
((res as unknown) as http.IncomingMessage).destroy();
2552
+
cb(new Error('Aborted connection'), null);
2553
+
});
2554
+
});
2555
+
2556
+
try {
2557
+
await request;
2558
+
} catch (e: unknown) {
2559
+
// ignore aborted error
2560
+
}
2561
+
// sleep to allow return function to be called
2562
+
await sleep(2);
2563
+
expect(text).to.equal(
2564
+
[
2565
+
'',
2566
+
'---',
2567
+
'Content-Type: application/json; charset=utf-8',
2568
+
'Content-Length: 47',
2569
+
'',
2570
+
'{"data":{"test":"Hello, World"},"hasNext":true}',
2571
+
'',
2572
+
].join('\r\n'),
2573
+
);
2574
+
});
2439
2575
});
2440
2576
2441
2577
describe('Custom parse function', () => {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4