Skip to content

Commit

Permalink
fix: add "address()" on mock Socket (#549)
Browse files Browse the repository at this point in the history
Co-authored-by: Artem Zakharchenko <[email protected]>
  • Loading branch information
Michael Solomon and kettanaito authored Apr 16, 2024
1 parent b49a316 commit 66c6046
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/interceptors/ClientRequest/MockHttpSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export class MockHttpSocket extends MockSocket {
*/
public passthrough(): void {
const socket = this.createConnection()
this.address = socket.address.bind(socket)

// Flush the buffered "socket.write()" calls onto
// the original socket instance (i.e. write request body).
Expand Down Expand Up @@ -218,7 +219,9 @@ export class MockHttpSocket extends MockSocket {

httpHeaders.push(
Buffer.from(
`HTTP/1.1 ${response.status} ${response.statusText || STATUS_CODES[response.status]}\r\n`
`HTTP/1.1 ${response.status} ${
response.statusText || STATUS_CODES[response.status]
}\r\n`
)
)

Expand Down Expand Up @@ -298,7 +301,20 @@ export class MockHttpSocket extends MockSocket {
}

private mockConnect(): void {
this.emit('lookup', null, '::1', 6, this.connectionOptions.host)
const addressInfo = {
address: '127.0.0.1',
family: 'IPv4',
port: this.connectionOptions.port,
}
// Return fake address information for the socket.
this.address = () => addressInfo
this.emit(
'lookup',
null,
addressInfo.address,
addressInfo.family === 'IPv6' ? 6 : 4,
this.connectionOptions.host
)
this.emit('connect')
this.emit('ready')

Expand Down
42 changes: 42 additions & 0 deletions test/modules/http/compliance/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,45 @@ it('mocks response to a non-existing host', async () => {
expect(await text()).toBe('howdy, john')
expect(requestListener).toHaveBeenCalledTimes(1)
})

it('returns socket address for a mocked request', async () => {
interceptor.on('request', async ({ request }) => {
request.respondWith(new Response())
})

const addressPromise = new DeferredPromise<object>()
const request = http.get('http://example.com')
request.once('socket', (socket) => {
socket.once('connect', () => {
addressPromise.resolve(socket.address())
})
})

await expect(addressPromise).resolves.toEqual({
address: '127.0.0.1',
family: 'IPv4',
port: 80,
})
})

it('returns socket address for a bypassed request', async () => {
const addressPromise = new DeferredPromise<object>()
const request = http.get(httpServer.http.url('/user'))
request.once('socket', (socket) => {
socket.once('connect', () => {
addressPromise.resolve(socket.address())
})
})

await waitForClientRequest(request)

await expect(addressPromise).resolves.toEqual({
address: httpServer.http.address.host,
family: 'IPv4',
/**
* @fixme Looks like every "http" request has an agent set.
* That agent, for some reason, wants to connect to a different port.
*/
port: expect.any(Number),
})
})

0 comments on commit 66c6046

Please sign in to comment.