Skip to content

Adding nock.cleanAll()  #13

@edvinasbartkus

Description

@edvinasbartkus

I have recently opened a PR adding cleanAll to a stop function in mockJWKS. Let me explain.

When we create a nock scope we are able to hit the request once and receive the mocked response.
However, if I hit the request second time, I get an error:

const scope = nock('https://google.com').get('/.well-known/jwks.json').reply(201)

// First request
const r1 = await request('https://google.com/.well-known/jwks.json')
expect(r1.statusCode).to.equal(201) // This will pass

// Second
const r2 = await request('https://google.com/.well-known/jwks.json')
expect(r2.statusCode).to.equal(404)

/*
Nock: No match for request {
  "method": "GET",
  "url": "https://google.com/.well-known/jwks.json"
}
*/

The way nock works is that it sets the scope for the base URL. Each base URL can have multiple interceptors.
When it receives the request to a base URL it tries to match the request with the right interceptor.
The second request is not matched because the first request removed the interceptor (by default interceptor is for a single hit) but left the base URL matching.

The same problem happens using mock-jwks. Once mocked the jwksOrigin + jwksPath with the persist, we remove the interceptor but jwksOrigin stays as a base URL for nock and it matches the requests. Meaning, that all the tests are written and run after the use of mock-jwks can't be nocked again since it will be failing at mock-jwks/nock matchers before reaching the other nock.

I have created an example repo demonstrating how it affects the tests that are being run after mock-jwks. 3.test.js tries to nock again the same jwksOrigin but the tests are hitting the first initiated nock from mock-jwks:
https://github.com/edvinasbartkus/mock-jwks-example

Just by running different sequence of tests it fails and it passes:

    "test:fails": "lab ./test/1.test.js ./test/2.test.js ./test/3.test.js",
    "test:works": "lab ./test/1.test.js ./test/3.test.js ./test/2.test.js"

In order to remove the matching of base URL nock.cleanAll() should be called.

Since mock-jwks is using nested nock version it should be free to call nock.cleanAll() and affect only it's used nock version. The same way calling nock.cleanAll() from the project tests we are not able to reach mock-jwks/node_modules/nock.

There is an alternative. https://github.com/Levino/mock-jwks/blob/master/index.ts#L25 can be replaced with:

-     jwksUrlNock = nock(jwksOrigin)
+     jwksUrlNock = nock(jwksOrigin, {allowUnmocked: true})

This would result that once interceptor is removed, the base URL will not be matched for the future request.

Hopefully, I have managed to explain the scenario well :)
Let me know if the alternative approach could be right?

@levino

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions