Skip to content

Commit e968759

Browse files
Test handleRequestClosed is called when connection closes
Add verification that the handleRequestClosed sink method is properly called when HTTP connections close in incremental render tests. Changes: - Update createMockSink() to return handleRequestClosed mock - Update createBasicTestSetup() and createStreamingTestSetup() helpers - Add handleRequestClosed verification to 5 tests - Use waitFor() to handle async cleanup timing All 11 tests pass, confirming handleRequestClosed is called once per connection close across both mocked and streaming scenarios. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2b1aa98 commit e968759

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

react_on_rails_pro/packages/node-renderer/tests/incrementalRender.test.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ describe('incremental render NDJSON endpoint', () => {
6767

6868
const createMockSink = () => {
6969
const sinkAdd = jest.fn();
70+
const handleRequestClosed = jest.fn();
7071

7172
const sink: incremental.IncrementalRenderSink = {
7273
add: sinkAdd,
74+
handleRequestClosed,
7375
};
7476

75-
return { sink, sinkAdd };
77+
return { sink, sinkAdd, handleRequestClosed };
7678
};
7779

7880
const createMockResponse = (data = 'mock response'): ResponseResult => ({
@@ -124,7 +126,7 @@ describe('incremental render NDJSON endpoint', () => {
124126
const createBasicTestSetup = async () => {
125127
await createVmBundle(TEST_NAME);
126128

127-
const { sink, sinkAdd } = createMockSink();
129+
const { sink, sinkAdd, handleRequestClosed } = createMockSink();
128130
const mockResponse = createMockResponse();
129131
const mockResult = createMockResult(sink, mockResponse);
130132

@@ -137,6 +139,7 @@ describe('incremental render NDJSON endpoint', () => {
137139
return {
138140
sink,
139141
sinkAdd,
142+
handleRequestClosed,
140143
mockResponse,
141144
mockResult,
142145
handleSpy,
@@ -158,9 +161,11 @@ describe('incremental render NDJSON endpoint', () => {
158161
});
159162

160163
const sinkAdd = jest.fn();
164+
const handleRequestClosed = jest.fn();
161165

162166
const sink: incremental.IncrementalRenderSink = {
163167
add: sinkAdd,
168+
handleRequestClosed,
164169
};
165170

166171
const mockResponse: ResponseResult = {
@@ -183,6 +188,7 @@ describe('incremental render NDJSON endpoint', () => {
183188
return {
184189
responseStream,
185190
sinkAdd,
191+
handleRequestClosed,
186192
sink,
187193
mockResponse,
188194
mockResult,
@@ -256,7 +262,7 @@ describe('incremental render NDJSON endpoint', () => {
256262
});
257263

258264
test('calls handleIncrementalRenderRequest immediately after first chunk and processes each subsequent chunk immediately', async () => {
259-
const { sinkAdd, handleSpy, SERVER_BUNDLE_TIMESTAMP } = await createBasicTestSetup();
265+
const { sinkAdd, handleRequestClosed, handleSpy, SERVER_BUNDLE_TIMESTAMP } = await createBasicTestSetup();
260266

261267
// Create the HTTP request
262268
const req = createHttpRequest(SERVER_BUNDLE_TIMESTAMP);
@@ -304,6 +310,11 @@ describe('incremental render NDJSON endpoint', () => {
304310
// Final verification: all chunks were processed in the correct order
305311
expect(handleSpy).toHaveBeenCalledTimes(1);
306312
expect(sinkAdd.mock.calls).toEqual([[{ a: 1 }], [{ b: 2 }], [{ c: 3 }]]);
313+
314+
// Verify handleRequestClosed was called when connection closed
315+
await waitFor(() => {
316+
expect(handleRequestClosed).toHaveBeenCalledTimes(1);
317+
});
307318
});
308319

309320
test('returns 410 error when bundle is missing', async () => {
@@ -357,7 +368,7 @@ describe('incremental render NDJSON endpoint', () => {
357368
// Create a bundle for this test
358369
await createVmBundle(TEST_NAME);
359370

360-
const { sink, sinkAdd } = createMockSink();
371+
const { sink, sinkAdd, handleRequestClosed } = createMockSink();
361372

362373
const mockResponse: ResponseResult = createMockResponse();
363374

@@ -416,13 +427,16 @@ describe('incremental render NDJSON endpoint', () => {
416427
await waitFor(() => {
417428
expect(sinkAdd.mock.calls).toEqual([[{ a: 1 }], [{ d: 4 }]]);
418429
});
430+
431+
// Verify handleRequestClosed was called when connection closed
432+
expect(handleRequestClosed).toHaveBeenCalledTimes(1);
419433
});
420434

421435
test('handles empty lines gracefully in the stream', async () => {
422436
// Create a bundle for this test
423437
await createVmBundle(TEST_NAME);
424438

425-
const { sink, sinkAdd } = createMockSink();
439+
const { sink, sinkAdd, handleRequestClosed } = createMockSink();
426440

427441
const mockResponse: ResponseResult = createMockResponse();
428442

@@ -469,6 +483,11 @@ describe('incremental render NDJSON endpoint', () => {
469483
// Verify that only valid JSON objects were processed
470484
expect(handleSpy).toHaveBeenCalledTimes(1);
471485
expect(sinkAdd.mock.calls).toEqual([[{ a: 1 }], [{ b: 2 }], [{ c: 3 }]]);
486+
487+
// Verify handleRequestClosed was called when connection closed
488+
await waitFor(() => {
489+
expect(handleRequestClosed).toHaveBeenCalledTimes(1);
490+
});
472491
});
473492

474493
test('throws error when first chunk processing fails (e.g., authentication)', async () => {
@@ -515,7 +534,8 @@ describe('incremental render NDJSON endpoint', () => {
515534
'Goodbye from stream',
516535
];
517536

518-
const { responseStream, sinkAdd, handleSpy, SERVER_BUNDLE_TIMESTAMP } = await createStreamingTestSetup();
537+
const { responseStream, sinkAdd, handleRequestClosed, handleSpy, SERVER_BUNDLE_TIMESTAMP } =
538+
await createStreamingTestSetup();
519539

520540
// write the response chunks to the stream
521541
let sentChunkIndex = 0;
@@ -586,10 +606,14 @@ describe('incremental render NDJSON endpoint', () => {
586606

587607
// Verify that the mock was called correctly
588608
expect(handleSpy).toHaveBeenCalledTimes(1);
609+
610+
// Verify handleRequestClosed was called when connection closed
611+
expect(handleRequestClosed).toHaveBeenCalledTimes(1);
589612
});
590613

591614
test('echo server - processes each chunk and immediately streams it back', async () => {
592-
const { responseStream, sinkAdd, handleSpy, SERVER_BUNDLE_TIMESTAMP } = await createStreamingTestSetup();
615+
const { responseStream, sinkAdd, handleRequestClosed, handleSpy, SERVER_BUNDLE_TIMESTAMP } =
616+
await createStreamingTestSetup();
593617

594618
// Create the HTTP request
595619
const req = createHttpRequest(SERVER_BUNDLE_TIMESTAMP);
@@ -677,6 +701,9 @@ describe('incremental render NDJSON endpoint', () => {
677701

678702
// Verify that the mock was called correctly
679703
expect(handleSpy).toHaveBeenCalledTimes(1);
704+
705+
// Verify handleRequestClosed was called when connection closed
706+
expect(handleRequestClosed).toHaveBeenCalledTimes(1);
680707
});
681708

682709
describe('incremental render update chunk functionality', () => {

0 commit comments

Comments
 (0)