Skip to content

Commit

Permalink
feat: add support for WHATWG URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Wheale committed Jan 4, 2023
1 parent c9cff34 commit b842a4e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 11 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,20 @@ If you don’t want interceptors to be removed as they are used, you can use the

### Specifying hostname

The request hostname can be a string or a RegExp.
The request hostname can be a string, URL, or a RegExp.

```js
const scope = nock('http://www.example.com')
.get('/resource')
.reply(200, 'domain matched')
```

```js
const scope = nock(new URL('http://www.example.com'))
.get('/resource')
.reply(200, 'domain matched')
```

```js
const scope = nock(/example\.com/)
.get('/resource')
Expand Down
48 changes: 44 additions & 4 deletions lib/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const debug = require('debug')('nock.scope')
const { EventEmitter } = require('events')
const Interceptor = require('./interceptor')

const { URL, Url: LegacyUrl } = url
let fs

try {
Expand All @@ -20,7 +21,42 @@ try {
}

/**
* @param {string|RegExp|url.url} basePath
* Normalizes the passed url for consistent internal processing
* @param {string|LegacyUrl|URL} u
*/
function normalizeUrl(u) {
if (!(u instanceof URL)) {
if (typeof u === 'string') {
return normalizeUrl(new URL(u))
}
if (u instanceof LegacyUrl) {
return normalizeUrl(new URL(url.format(u)))
}
throw new Error('Unrecognized URL')
}

return {
href: u.href,
origin: u.origin,
protocol: u.protocol,
username: u.username,
password: u.password,
host: u.host,
hostname:
// strip brackets from IPv6
typeof u.hostname === 'string' && u.hostname.startsWith('[')
? u.hostname.slice(1, -1)
: u.hostname,
port: u.port || (u.protocol === 'http:' ? 80 : 443),
pathname: u.pathname,
search: u.search,
searchParams: u.searchParams,
hash: u.hash,
}
}

/**
* @param {string|RegExp|LegacyUrl|URL} basePath
* @param {Object} options
* @param {boolean} options.allowUnmocked
* @param {string[]} options.badheaders
Expand Down Expand Up @@ -52,9 +88,13 @@ class Scope extends EventEmitter {
let logNamespace = String(basePath)

if (!(basePath instanceof RegExp)) {
this.urlParts = url.parse(basePath)
this.port =
this.urlParts.port || (this.urlParts.protocol === 'http:' ? 80 : 443)
this.urlParts = normalizeUrl(basePath)
if (!/https?:/.test(this.urlParts.protocol)) {
throw new TypeError(
`Protocol '${this.urlParts.protocol}' not recognized. This commonly occurs when a hostname and port are included without a protocol, producing a URL that is valid but confusing, and probably not what you want.`
)
}
this.port = this.urlParts.port
this.basePathname = this.urlParts.pathname.replace(/\/$/, '')
this.basePath = `${this.urlParts.protocol}//${this.urlParts.hostname}:${this.port}`
logNamespace = this.urlParts.host
Expand Down
11 changes: 5 additions & 6 deletions tests/test_scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,18 @@ describe('`Scope#constructor`', () => {
scope.done()
})

// TODO: https://github.com/nock/nock/pull/1879
it.skip('accepts a WHATWG URL instance', async () => {
it('accepts a WHATWG URL instance', async () => {
const scope = nock(new url.URL('http://example.test')).get('/').reply()

const { statusCode } = await got('http://example.test')
expect(statusCode).to.equal(200)
scope.done()
})

it('fails when provided a WHATWG URL instance', () => {
// This test just proves the lack of current support. When this feature is added,
// this test should be removed and the test above un-skipped.
expect(() => nock(new url.URL('http://example.test'))).to.throw()
it('throws on invalid or omitted protocol', async () => {
expect(() => nock('ws://example.test')).to.throw()
expect(() => nock('localhost/foo')).to.throw()
expect(() => nock('foo.com:1234')).to.throw()
})
})

Expand Down

0 comments on commit b842a4e

Please sign in to comment.