From d6667f0e92ece7ecd52f23acd23f4ad3b69ff212 Mon Sep 17 00:00:00 2001 From: Daniel Mora <38921751+ww-daniel-mora@users.noreply.github.com> Date: Mon, 15 Apr 2019 12:31:02 -0400 Subject: [PATCH] fix: Fix `.matchHeader()` with `allowUnmocked` (#1480) - Move header checks into `match()`. - Rename internal method `matchIndependentOfBody()` to `matchAddress()` --- lib/intercept.js | 4 ++-- lib/interceptor.js | 40 ++++++++++++----------------------- tests/test_header_matching.js | 32 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/lib/intercept.js b/lib/intercept.js index 97bc9e63b..6baea5ef7 100644 --- a/lib/intercept.js +++ b/lib/intercept.js @@ -173,7 +173,7 @@ function interceptorsFor(options) { matchingInterceptor = [ { options: { allowUnmocked: true }, - matchIndependentOfBody: function() { + matchAddress() { return false }, }, @@ -412,7 +412,7 @@ function activate() { let allowUnmocked = false matches = !!_.find(interceptors, function(interceptor) { - return interceptor.matchIndependentOfBody(options) + return interceptor.matchAddress(options) }) allowUnmocked = !!_.find(interceptors, function(interceptor) { diff --git a/lib/interceptor.js b/lib/interceptor.js index edfbcc23b..63386a2f7 100644 --- a/lib/interceptor.js +++ b/lib/interceptor.js @@ -227,19 +227,18 @@ Interceptor.prototype.match = function match(options, body, hostNameOnly) { body = this.scope.transformRequestBodyFunction(body, this._requestBody) } - const checkHeaders = function(header) { - if (_.isFunction(header.value)) { - return header.value(options.getHeader(header.name)) + const requestMatchesFilter = ({ name, value: predicate }) => { + const headerValue = options.getHeader(name) + if (typeof predicate === 'function') { + return predicate(headerValue) + } else { + return common.matchStringOrRegexp(headerValue, predicate) } - return common.matchStringOrRegexp( - options.getHeader(header.name), - header.value - ) } if ( - !this.scope.matchHeaders.every(checkHeaders) || - !this.interceptorMatchHeaders.every(checkHeaders) + !this.scope.matchHeaders.every(requestMatchesFilter) || + !this.interceptorMatchHeaders.every(requestMatchesFilter) ) { this.scope.logger("headers don't match") return false @@ -375,9 +374,11 @@ Interceptor.prototype.match = function match(options, body, hostNameOnly) { return matches } -Interceptor.prototype.matchIndependentOfBody = function matchIndependentOfBody( - options -) { +/** + * Return true when the interceptor's method, protocol, host, port, and path + * match the provided options. + */ +Interceptor.prototype.matchAddress = function matchAddress(options) { const isRegex = _.isRegExp(this.path) const isRegexBasePath = _.isRegExp(this.scope.basePath) @@ -393,21 +394,6 @@ Interceptor.prototype.matchIndependentOfBody = function matchIndependentOfBody( if (this.scope.transformPathFunction) { path = this.scope.transformPathFunction(path) } - - const checkHeaders = function(header) { - return ( - options.getHeader && - common.matchStringOrRegexp(options.getHeader(header.name), header.value) - ) - } - - if ( - !this.scope.matchHeaders.every(checkHeaders) || - !this.interceptorMatchHeaders.every(checkHeaders) - ) { - return false - } - const comparisonKey = isRegex ? this.__nock_scopeKey : this._key const matchKey = `${method} ${proto}://${options.host}${path}` diff --git a/tests/test_header_matching.js b/tests/test_header_matching.js index 22d794e8b..dd122d945 100644 --- a/tests/test_header_matching.js +++ b/tests/test_header_matching.js @@ -118,6 +118,21 @@ test('match header on scope with function: matches when match accepted', async t scope.done() }) +test('match header on scope with function and allow unmocked: matches when match accepted', async t => { + const scope = nock('http://example.test', { allowUnmocked: true }) + .get('/') + .matchHeader('x-my-headers', val => true) + .reply(200, 'Hello World!') + + const { statusCode, body } = await got('http://example.test/', { + headers: { 'X-My-Headers': 456 }, + }) + + t.equal(statusCode, 200) + t.equal(body, 'Hello World!') + scope.done() +}) + test('match header on scope with function: does not match when match declined', async t => { nock('http://example.test') .get('/') @@ -192,6 +207,23 @@ test('match header on interceptor with function: matches when match accepted', a scope.done() }) +test('match header on interceptor with function: matches when match accepted', async t => { + const scope = nock('http://example.test', { allowUnmocked: true }) + .matchHeader('x-my-headers', val => true) + // `.matchHeader()` is called on the interceptor. It precedes the call to + // `.get()`. + .get('/') + .reply(200, 'Hello World!') + + const { statusCode, body } = await got('http://example.test/', { + headers: { 'X-My-Headers': 456 }, + }) + + t.equal(statusCode, 200) + t.equal(body, 'Hello World!') + scope.done() +}) + test('match header on interceptor with function: does not match when match declined', async t => { nock('http://example.test') .matchHeader('x-my-headers', val => false)