Skip to content

Commit

Permalink
fix(ClientRequest): support "http.request()" and "http.get()" without…
Browse files Browse the repository at this point in the history
… any arguments (#468)
  • Loading branch information
kettanaito authored Oct 7, 2023
1 parent 198533a commit 65b7ac1
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const logger = new Logger('http normalizeClientRequestArgs')
export type HttpRequestCallback = (response: IncomingMessage) => void

export type ClientRequestArgs =
// Request without any arguments is also possible.
| []
| [string | URL | LegacyURL, HttpRequestCallback?]
| [string | URL | LegacyURL, RequestOptions, HttpRequestCallback?]
| [RequestOptions, HttpRequestCallback?]
Expand Down Expand Up @@ -109,6 +111,14 @@ export function normalizeClientRequestArgs(
logger.info('arguments', args)
logger.info('using default protocol:', defaultProtocol)

// Support "http.request()" calls without any arguments.
// That call results in a "GET http://localhost" request.
if (args.length === 0) {
const url = new URL('http://localhost')
const options = resolveRequestOptions(args, url)
return [url, options]
}

// Convert a url string into a URL instance
// and derive request options from it.
if (typeof args[0] === 'string') {
Expand Down
102 changes: 102 additions & 0 deletions test/modules/http/compliance/http-request-without-options.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { vi, it, expect, beforeAll, afterAll } from 'vitest'
import http from 'http'
import { ClientRequestInterceptor } from '../../../../src/interceptors/ClientRequest'
import { waitForClientRequest } from '../../../helpers'

const interceptor = new ClientRequestInterceptor()

beforeAll(() => {
interceptor.apply()
})

afterAll(() => {
interceptor.dispose()
})

it('supports "http.request()" without any options', async () => {
const responseListener = vi.fn()
const errorListener = vi.fn()

const request = http
// @ts-ignore It's possible to make a request without any options.
// This will result in a "GET http://localhost" request in Node.js.
.request()
request.end()
request.on('response', responseListener)
request.on('error', errorListener)

expect(errorListener).not.toHaveBeenCalled()
expect(responseListener).not.toHaveBeenCalled()
expect(request.path).toBe('/')
expect(request.method).toBe('GET')
expect(request.protocol).toBe('http:')
expect(request.host).toBe('localhost')
})

it('responds with a mocked response for "http.request()" without any options', async () => {
interceptor.once('request', ({ request }) => {
if (request.url === 'http://localhost/') {
request.respondWith(new Response('Mocked'))
}
})

const request = http
// @ts-ignore It's possible to make a request without any options.
// This will result in a "GET http://localhost" request in Node.js.
.request()
request.end()

const errorListener = vi.fn()
request.on('error', errorListener)

const { res, text } = await waitForClientRequest(request)

expect(errorListener).not.toHaveBeenCalled()

expect(res.statusCode).toBe(200)
expect(await text()).toBe('Mocked')
})

it('supports "http.get()" without any argumenst', async () => {
const responseListener = vi.fn()
const errorListener = vi.fn()

const request = http
// @ts-ignore It's possible to make a request without any options.
// This will result in a "GET http://localhost" request in Node.js.
.get()
request.end()
request.on('response', responseListener)
request.on('error', errorListener)

expect(errorListener).not.toHaveBeenCalled()
expect(responseListener).not.toHaveBeenCalled()
expect(request.path).toBe('/')
expect(request.method).toBe('GET')
expect(request.protocol).toBe('http:')
expect(request.host).toBe('localhost')
})

it('responds with a mocked response for "http.get()" without any options', async () => {
interceptor.once('request', ({ request }) => {
if (request.url === 'http://localhost/') {
request.respondWith(new Response('Mocked'))
}
})

const request = http
// @ts-ignore It's possible to make a request without any options.
// This will result in a "GET http://localhost" request in Node.js.
.get()
request.end()

const errorListener = vi.fn()
request.on('error', errorListener)

const { res, text } = await waitForClientRequest(request)

expect(errorListener).not.toHaveBeenCalled()

expect(res.statusCode).toBe(200)
expect(await text()).toBe('Mocked')
})

0 comments on commit 65b7ac1

Please sign in to comment.