Skip to content

Commit

Permalink
fix(ClientRequest): fix a custom agent context in createConnection (#…
Browse files Browse the repository at this point in the history
…636)

Co-authored-by: Artem Zakharchenko <kettanaito@gmail.com>
  • Loading branch information
tebriel and kettanaito authored Sep 14, 2024
1 parent 236f552 commit e3035f7
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/interceptors/ClientRequest/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ export class MockAgent extends http.Agent {

const socket = new MockHttpSocket({
connectionOptions: options,
createConnection: createConnection.bind(this, options, callback),
createConnection: createConnection.bind(
this.customAgent || this,
options,
callback
),
onRequest: this.onRequest.bind(this),
onResponse: this.onResponse.bind(this),
})
Expand Down Expand Up @@ -68,7 +72,11 @@ export class MockHttpsAgent extends https.Agent {

const socket = new MockHttpSocket({
connectionOptions: options,
createConnection: createConnection.bind(this, options, callback),
createConnection: createConnection.bind(
this.customAgent || this,
options,
callback
),
onRequest: this.onRequest.bind(this),
onResponse: this.onResponse.bind(this),
})
Expand Down
64 changes: 64 additions & 0 deletions test/modules/http/compliance/http-custom-agent.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// @vitest-environment node
import { vi, it, expect, beforeAll, afterAll, afterEach } from 'vitest'
import http from 'node:http'
import https from 'node:https'
import { HttpServer } from '@open-draft/test-server/http'
import { ClientRequestInterceptor } from '../../../../src/interceptors/ClientRequest/index'
import { waitForClientRequest } from '../../../../test/helpers'

const interceptor = new ClientRequestInterceptor()

const httpServer = new HttpServer((app) => {
app.get('/resource', (req, res) => res.send('hello world'))
})

beforeAll(async () => {
interceptor.apply()
await httpServer.listen()
})

afterEach(() => {
interceptor.removeAllListeners()
})

afterAll(async () => {
interceptor.dispose()
await httpServer.close()
})

it('preserves the context of the "createConnection" function in a custom http agent', async () => {
const createConnectionContextSpy = vi.fn()
class CustomHttpAgent extends http.Agent {
createConnection(options: any, callback: any) {
createConnectionContextSpy(this)
return super.createConnection(options, callback)
}
}
const agent = new CustomHttpAgent()

const request = http.get(httpServer.http.url('/resource'), { agent })
await waitForClientRequest(request)

const [context] = createConnectionContextSpy.mock.calls[0]
expect(context.constructor.name).toBe('CustomHttpAgent')
})

it('preserves the context of the "createConnection" function in a custom https agent', async () => {
const createConnectionContextSpy = vi.fn()
class CustomHttpsAgent extends https.Agent {
createConnection(options: any, callback: any) {
createConnectionContextSpy(this)
return super.createConnection(options, callback)
}
}
const agent = new CustomHttpsAgent()

const request = https.get(httpServer.https.url('/resource'), {
agent,
rejectUnauthorized: false,
})
await waitForClientRequest(request)

const [context] = createConnectionContextSpy.mock.calls[0]
expect(context.constructor.name).toBe('CustomHttpsAgent')
})

0 comments on commit e3035f7

Please sign in to comment.