diff --git a/.all-contributorsrc b/.all-contributorsrc
index a2511741c..4bd7f412b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -157,6 +157,17 @@
"code",
"test"
]
+ },
+ {
+ "login": "mikicho",
+ "name": "Michael Solomon",
+ "avatar_url": "https://avatars.githubusercontent.com/u/11459632?v=4",
+ "profile": "https://github.com/mikicho",
+ "contributions": [
+ "maintenance",
+ "code",
+ "doc"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml
index 45dcc8d08..c4c6fccfc 100644
--- a/.github/workflows/continuous-integration.yaml
+++ b/.github/workflows/continuous-integration.yaml
@@ -63,9 +63,27 @@ jobs:
- name: Lint
run: |
npm run lint:ts
- test:
- name: Test
+
+ # verify against ranges defined as supported in engines.node
+ test_matrix:
+ strategy:
+ fail-fast: false
+ matrix:
+ node-version:
+ - 10
+ - 12
+ - 14
+ - 16
+ - 18
+ - 20
+ os:
+ - macos-latest
+ - ubuntu-latest
+ - windows-latest
+
runs-on: ${{ matrix.os }}
+ timeout-minutes: 5
+
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -83,16 +101,18 @@ jobs:
- name: Test jest
run: npm run test:jest
if: matrix.node-version >= 14
- strategy:
- fail-fast: false
- matrix:
- node-version:
- - 10
- - 12
- - 14
- - 16
- - 18
- os:
- - macos-latest
- - ubuntu-latest
- - windows-latest
+
+ # separate job to set as required in branch protection,
+ # as the build names above change each time Node versions change
+ test:
+ runs-on: ubuntu-latest
+ needs:
+ - test_matrix
+ if: ${{ !cancelled() }}
+ steps:
+ - name: All matrix versions passed
+ if: ${{ !(contains(needs.*.result, 'failure')) }}
+ run: exit 0
+ - name: Some matrix version failed
+ if: ${{ contains(needs.*.result, 'failure') }}
+ run: exit 1
diff --git a/README.md b/README.md
index e26ecaf89..43f1eaaaf 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,13 @@
[npmjs]: https://www.npmjs.com/package/nock
[build]: https://travis-ci.org/nock/nock
-> **Warning**
-> nock is currently not compatible with Node's experimental native `fetch` implementation. See [#2397](https://github.com/nock/nock/issues/2397)
+> **Notice**
+>
+> We have introduced experimental support for fetch. Please share your feedback with us. You can install it by:
+>
+> ```
+> npm install --save-dev nock@beta
+> ```
HTTP server mocking and expectations library for Node.js
@@ -1698,6 +1703,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/all-contri
Saryev Rustam 💻 ⚠️ |
+ Michael Solomon 🚧 💻 📖 |
diff --git a/lib/intercept.js b/lib/intercept.js
index cf266d5a5..bcc1319ce 100644
--- a/lib/intercept.js
+++ b/lib/intercept.js
@@ -350,7 +350,8 @@ function interceptorScopes() {
const nestedInterceptors = Object.values(allInterceptors).map(
i => i.interceptors,
)
- return [].concat(...nestedInterceptors).map(i => i.scope)
+ const scopes = new Set([].concat(...nestedInterceptors).map(i => i.scope))
+ return [...scopes]
}
function isDone() {
diff --git a/lib/interceptor.js b/lib/interceptor.js
index 67ef8b946..aebbdad14 100644
--- a/lib/interceptor.js
+++ b/lib/interceptor.js
@@ -510,7 +510,7 @@ module.exports = class Interceptor {
strFormattingFn = common.percentDecode
}
- if (queries instanceof URLSearchParams) {
+ if (queries instanceof URLSearchParams || typeof queries === 'string') {
// Normalize the data into the shape that is matched against.
// Duplicate keys are handled by combining the values into an array.
queries = querystring.parse(queries.toString())
diff --git a/tests/got/test_nock_lifecycle.js b/tests/got/test_nock_lifecycle.js
index 92a07efe8..622f3076b 100644
--- a/tests/got/test_nock_lifecycle.js
+++ b/tests/got/test_nock_lifecycle.js
@@ -163,6 +163,22 @@ describe('Nock lifecycle functions', () => {
await got('http://example.test/')
expect(nock.activeMocks()).to.be.empty()
})
+
+ it("activeMocks doesn't return duplicate mocks", () => {
+ nock('http://example.test')
+ .get('/')
+ .reply()
+ .get('/second')
+ .reply()
+ .get('/third')
+ .reply()
+
+ expect(nock.activeMocks()).to.deep.equal([
+ 'GET http://example.test:80/',
+ 'GET http://example.test:80/second',
+ 'GET http://example.test:80/third',
+ ])
+ })
})
describe('resetting nock catastrophically while a request is in progress', () => {
diff --git a/tests/got/test_query.js b/tests/got/test_query.js
index 196b14783..336a8dbc9 100644
--- a/tests/got/test_query.js
+++ b/tests/got/test_query.js
@@ -19,6 +19,22 @@ describe('query params in path', () => {
})
describe('`query()`', () => {
+ describe('when called with a string', () => {
+ it('matches a url encoded query string of the same name=value', async () => {
+ const scope = nock('http://example.test')
+ .get('/')
+ .query('foo%5Bbar%5D%3Dhello%20world%21')
+ .reply()
+
+ const { statusCode } = await got(
+ 'http://example.test/?foo%5Bbar%5D%3Dhello%20world%21',
+ )
+
+ expect(statusCode).to.equal(200)
+ scope.done()
+ })
+ })
+
describe('when called with an object', () => {
it('matches a query string of the same name=value', async () => {
const scope = nock('http://example.test')
@@ -256,8 +272,8 @@ describe('`query()`', () => {
const interceptor = nock('http://example.test').get('/')
expect(() => {
- interceptor.query('foo=bar')
- }).to.throw(Error, 'Argument Error: foo=bar')
+ interceptor.query(1)
+ }).to.throw(Error, 'Argument Error: 1')
})
})