Skip to content

Commit

Permalink
normalizeHttpRequestParams: Clones request options to prevent mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Feb 4, 2021
1 parent e33af34 commit b624e70
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { parse } from 'url';
import { getUrlByRequestOptions } from '../../../utils/getUrlByRequestOptions';
import { parse } from 'url'
import { getUrlByRequestOptions } from '../../../utils/getUrlByRequestOptions'
import { normalizeHttpRequestParams } from './normalizeHttpRequestParams'

test('handles [string, callback] input', () => {
Expand Down Expand Up @@ -42,7 +42,7 @@ test('handles [string, RequestOptions, callback] input', () => {
expect(url.toJSON()).toEqual(new URL('https://mswjs.io/resource').toJSON())

// Request options must be preserved
expect(options).toEqual(initialOptions)
expect(options).toHaveProperty('headers', initialOptions.headers)

// Callback must be preserved
expect(callback).toHaveProperty('name', 'cb')
Expand Down Expand Up @@ -74,7 +74,11 @@ test('handles [Absolute Legacy URL, callback] input', () => {
)

// URL must be preserved
expect(url.toJSON()).toEqual(new URL('https://cherry:[email protected]:12345/resource?apple=banana').toJSON())
expect(url.toJSON()).toEqual(
new URL(
'https://cherry:[email protected]:12345/resource?apple=banana'
).toJSON()
)

// Request options must be derived from the URL instance
expect(options).toHaveProperty('method', 'GET')
Expand All @@ -91,12 +95,14 @@ test('handles [Absolute Legacy URL, callback] input', () => {
test('handles [Relative Legacy URL, RequestOptions without path set, callback] input', () => {
const [url, options, callback] = normalizeHttpRequestParams(
parse('/resource?apple=banana'),
{host: 'mswjs.io'},
{ host: 'mswjs.io' },
function cb() {}
)

// Correct WHATWG URL generated
expect(url.toJSON()).toEqual(new URL('http://mswjs.io/resource?apple=banana').toJSON())
expect(url.toJSON()).toEqual(
new URL('http://mswjs.io/resource?apple=banana').toJSON()
)

// No path in request options, so legacy url path is copied-in
expect(options).toHaveProperty('protocol', 'http:')
Expand All @@ -110,12 +116,14 @@ test('handles [Relative Legacy URL, RequestOptions without path set, callback] i
test('handles [Relative Legacy URL, RequestOptions with path set, callback] input', () => {
const [url, options, callback] = normalizeHttpRequestParams(
parse('/resource?apple=banana'),
{host: 'mswjs.io', path: '/other?cherry=durian'},
{ host: 'mswjs.io', path: '/other?cherry=durian' },
function cb() {}
)

// Correct WHATWG URL generated
expect(url.toJSON()).toEqual(new URL('http://mswjs.io/other?cherry=durian').toJSON())
expect(url.toJSON()).toEqual(
new URL('http://mswjs.io/other?cherry=durian').toJSON()
)

// Path in request options, so that path is preferred
expect(options).toHaveProperty('protocol', 'http:')
Expand All @@ -133,7 +141,9 @@ test('handles [Relative Legacy URL, callback] input', () => {
)

// Correct WHATWG URL generated
expect(url.toJSON()).toMatch(getUrlByRequestOptions({path: '/resource?apple=banana'}).toJSON())
expect(url.toJSON()).toMatch(
getUrlByRequestOptions({ path: '/resource?apple=banana' }).toJSON()
)

// Check path is in options
expect(options).toHaveProperty('protocol', 'http:')
Expand All @@ -149,7 +159,9 @@ test('handles [Relative Legacy URL] input', () => {
)

// Correct WHATWG URL generated
expect(url.toJSON()).toMatch(getUrlByRequestOptions({path: '/resource?apple=banana'}).toJSON())
expect(url.toJSON()).toMatch(
getUrlByRequestOptions({ path: '/resource?apple=banana' }).toJSON()
)

// Check path is in options
expect(options).toHaveProperty('protocol', 'http:')
Expand Down Expand Up @@ -211,10 +223,7 @@ test('handles [RequestOptions, callback] input', () => {
})

test('handles [Empty RequestOptions, callback] input', () => {
const [_, __, callback] = normalizeHttpRequestParams(
{},
function cb() {}
)
const [_, __, callback] = normalizeHttpRequestParams({}, function cb() {})

// Callback must be preserved
expect(callback).toHaveProperty('name', 'cb')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Url as LegacyURL } from 'url'
import { HttpRequestCallback, RequestSelf } from '../../../glossary'
import { getRequestOptionsByUrl } from '../../../utils/getRequestOptionsByUrl'
import { getUrlByRequestOptions } from '../../../utils/getUrlByRequestOptions'
import { cloneObject } from '../../../utils/cloneObject'
import { isObject } from '../../../utils/isObject'

const debug = require('debug')('http normalizeHttpRequestParams')
Expand All @@ -22,7 +23,12 @@ function resolveRequestOptions(
return getRequestOptionsByUrl(url)
}

return args[1] as RequestOptions
/**
* Clone the request options to lock their state
* at the moment they are provided to `ClientRequest.
* @see https://github.com/mswjs/node-request-interceptor/issues/86
*/
return args[1] ? cloneObject(args[1]) : ({} as RequestOptions)
}

function resolveCallback(
Expand Down

0 comments on commit b624e70

Please sign in to comment.