Skip to content

Commit

Permalink
fix: support Readable as request body (#527)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Solomon <[email protected]>
  • Loading branch information
kettanaito and mikicho authored Mar 21, 2024
1 parent 230c238 commit 2b1a5d7
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/interceptors/ClientRequest/MockHttpSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,14 @@ export class MockHttpSocket extends MockSocket {
// this ensures that each request gets its own stream.
// One Socket instance can only handle one request at a time.
if (canHaveBody) {
this.requestStream = new Readable()
this.requestStream = new Readable({
/**
* @note Provide the `read()` method so a `Readable` could be
* used as the actual request body (the stream calls "read()").
* We control the queue in the onRequestBody/End functions.
*/
read: () => {},
})
}

const requestId = randomUUID()
Expand Down
2 changes: 1 addition & 1 deletion src/interceptors/Socket/MockSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class MockSocket extends net.Socket {
public write(...args: Array<unknown>): boolean {
const [chunk, encoding, callback] = normalizeWriteArgs(args as WriteArgs)
this.options.write(chunk, encoding, callback)
return false
return true
}

public end(...args: Array<unknown>) {
Expand Down
28 changes: 27 additions & 1 deletion test/modules/http/compliance/http-req-write.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/**
* @vitest-environment node
*/
import { Readable } from 'node:stream'
import { vi, it, expect, beforeAll, afterEach, afterAll } from 'vitest'
import http from 'node:http'
import express from 'express'
import { HttpServer } from '@open-draft/test-server/http'
import { ClientRequestInterceptor } from '../../../../src/interceptors/ClientRequest'
import { waitForClientRequest } from '../../../helpers'
import { sleep, waitForClientRequest } from '../../../helpers'

const httpServer = new HttpServer((app) => {
app.post('/resource', express.text({ type: '*/*' }), (req, res) => {
Expand Down Expand Up @@ -93,6 +94,31 @@ it('writes Buffer request body', async () => {
expect(await text()).toEqual(expectedBody)
})

it('supports Readable as the request body', async () => {
const req = http.request(httpServer.http.url('/resource'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})

const input = ['hello', ' ', 'world', null]
const readable = new Readable({
read: async function() {
await sleep(10)
this.push(input.shift())
},
})

readable.pipe(req)

const { text } = await waitForClientRequest(req)
const expectedBody = 'hello world'

expect(interceptedRequestBody).toHaveBeenCalledWith(expectedBody)
expect(await text()).toEqual(expectedBody)
})

it('calls the callback when writing an empty string', async () => {
const request = http.request(httpServer.http.url('/resource'), {
method: 'POST',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ let requests: Array<Request> = []

const interceptor = new ClientRequestInterceptor()
interceptor.on('request', ({ request }) => {
console.log('REQUEST', request.method, request.url)

requests.push(request)
request.respondWith(new Response())
})
Expand Down

0 comments on commit 2b1a5d7

Please sign in to comment.