Skip to content

Commit

Permalink
Document options
Browse files Browse the repository at this point in the history
  • Loading branch information
exogen committed Nov 15, 2017
1 parent 8c137fa commit 45e45bc
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 72 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,37 @@ You can control ava-nock’s behavior using the `NOCK_MODE` environment variable
that do not have a fixture will result in an error. This is the default
behavior. It is useful if you are done writing tests and want to verify that
they all pass. Use this mode in CI environments.

## Configuration

ava-nock can be configured using either an `ava-nock` field in your package.json
file, or by importing and calling `configure()`.

### Options

#### decodeResponse

When Nock outputs a response, it is normally minimally altered from how it
arrived. If the response is compressed, Nock will output an array of encoded
buffers. By default, ava-nock will instead attempt to decode responses encoded
with `gzip` and `deflate` so that fixtures are more easily inspectable. If
successful, the relevant `Content-Encoding` header will also be removed from the
saved fixture so that clients don’t attempt to decode it again.

Set this to `false` to leave responses encoded.

#### pathFilter

A function or array of arguments to pass to Nock’s `filteringPath` method on
each scope. The transformation will be applied to both incoming request paths
and outgoing fixture paths.

For example, the following value will cause any saved fixtures to have
`secretKey` query parameters replaced with `secretKey=*`, and will likewise
cause any requests with a `secretKey` value to match against it.

```js
{
pathFilter: ['([?&]secretKey=)([^&]*)', '$1*']
}
```
30 changes: 10 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
"author": "Brian Beck <[email protected]>",
"license": "MIT",
"main": "lib/index.js",
"files": [
"lib",
"yarn.lock"
],
"files": ["lib", "yarn.lock"],
"scripts": {
"build": "npm run build:lib",
"build:lib": "babel src --out-dir lib --ignore \"**/*.test.js\"",
Expand All @@ -40,27 +37,19 @@
"test:record": "NOCK_MODE=record ava"
},
"ava": {
"require": [
"babel-register"
],
"files": [
"src/**/*.test.js",
"test"
]
"require": ["babel-register"],
"files": ["src/**/*.test.js", "test"]
},
"ava-nock": {
"pathFilter": ["([?&]secretKey=)([^&]*)", "$1*"]
},
"prettier": {
"semi": false,
"singleQuote": true
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
],
"README.md": [
"prettier --write",
"git add"
]
"*.js": ["eslint --fix", "git add"],
"README.md": ["prettier --write", "git add"]
},
"peerDependencies": {
"ava": "^0.23.0"
Expand Down Expand Up @@ -95,6 +84,7 @@
"nyc": "^11.3.0",
"prettier": "^1.8.2",
"request": "^2.83.0",
"rimraf": "^2.6.2"
"rimraf": "^2.6.2",
"uuid": "^3.1.0"
}
}
102 changes: 73 additions & 29 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,44 @@ function getTestFile() {
return testModule.filename
}

function applyPathFilterToScope(scope) {
const { pathFilter } = config
if (typeof pathFilter === 'function') {
return scope.filteringPath(config.pathFilter)
} else if (Array.isArray(pathFilter)) {
const args = [...pathFilter]
if (typeof args[0] === 'string') {
args[0] = new RegExp(args[0], 'g')
}
return scope.filteringPath(...args)
} else if (pathFilter != null) {
throw new Error(`Unknown pathFilter type: ${pathFilter}`)
}
return scope
}

function applyPathFilterToCall(call) {
const { pathFilter } = config
if (typeof pathFilter === 'function') {
return {
...call,
path: pathFilter(call.path)
}
} else if (Array.isArray(pathFilter)) {
const args = [...pathFilter]
if (typeof args[0] === 'string') {
args[0] = new RegExp(args[0], 'g')
}
return {
...call,
path: call.path.replace(...args)
}
} else if (pathFilter != null) {
throw new Error(`Unknown pathFilter type: ${pathFilter}`)
}
return call
}

function loadFixtures(t) {
if (fixtureData) {
return Promise.resolve(fixtureData)
Expand Down Expand Up @@ -50,33 +88,37 @@ function saveFixture(t) {
if (!context.recordedCalls) {
return Promise.resolve()
}
const prepare = config.decodeResponse
? Promise.all(context.recordedCalls.map(decodeResponse)).then(
decodedCalls => {
context.recordedCalls = decodedCalls
}
)
: Promise.resolve()
return prepare.then(() => loadFixtures(t)).then(fixtures => {
if (
!context.savedCalls ||
objectHash(context.recordedCalls) !== objectHash(context.savedCalls)
) {
fixtures.set(context.title, context.recordedCalls)
const outputData = Array.from(fixtures)
// Sort fixtures so they don't move around when re-recording.
outputData.sort((a, b) => {
if (a[0] < b[0]) {
return -1
} else if (a[0] > b[0]) {
return 1
} else {
return 0
}
})
return writeFixture(fixturePath, outputData, { overwrite: true })
let outputCalls = Promise.resolve(context.recordedCalls)
if (config.decodeResponse) {
outputCalls = outputCalls.then(calls =>
Promise.all(calls.map(decodeResponse))
)
}
if (config.pathFilter) {
outputCalls = outputCalls.then(calls => calls.map(applyPathFilterToCall))
}
return Promise.all([loadFixtures(t), outputCalls]).then(
([fixtures, outputCalls]) => {
if (
!context.inputCalls ||
objectHash(outputCalls) !== objectHash(context.inputCalls)
) {
fixtures.set(context.title, outputCalls)
const outputData = Array.from(fixtures)
// Sort fixtures so they don't move around when re-recording.
outputData.sort((a, b) => {
if (a[0] < b[0]) {
return -1
} else if (a[0] > b[0]) {
return 1
} else {
return 0
}
})
return writeFixture(fixturePath, outputData, { overwrite: true })
}
}
})
)
}

function beforeEach(t) {
Expand All @@ -93,9 +135,11 @@ function beforeEach(t) {
} else if (permissions.write) {
nockManager.startRecording({ requestHeaders: true })
}
context.savedCalls = fixture
context.inputCalls = fixture
if (fixture && fixture.length) {
context.scopes = nockManager.loadCalls(fixture)
context.scopes = nockManager
.loadCalls(fixture)
.map(applyPathFilterToScope)
} else {
context.scopes = []
}
Expand All @@ -110,7 +154,7 @@ function afterEach(t) {
context.recordedCalls = nockManager.getRecordedCalls()
}
nockManager.disable()
if (context.savedCalls) {
if (context.inputCalls) {
debug('Checking that expected requests were made.')
context.scopes.forEach(scope => {
if (!scope.isDone()) {
Expand Down
19 changes: 19 additions & 0 deletions test/axios.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import test from 'ava'
import axios from 'axios'
import uuid from 'uuid'
import { setupTests } from '../src'

setupTests()
Expand Down Expand Up @@ -33,3 +34,21 @@ test('using axios to get XML', t => {
})
)
})

test('making a request with a filtered secret key', t => {
const secretKey = uuid()
return new Promise((resolve, reject) => {
setTimeout(resolve, 1000)
}).then(() =>
axios
.get(
`https://musicbrainz.org/ws/2/artist/c8da2e40-bd28-4d4e-813a-bd2f51958ba8?secretKey=${
secretKey
}`
)
.then(response => response.data)
.then(data => {
t.is(data.name, 'Lures')
})
)
})
91 changes: 82 additions & 9 deletions test/axios.test.js.nock
Original file line number Diff line number Diff line change
@@ -1,4 +1,77 @@
[
[
"making a request with a filtered secret key",
[
{
"body": "",
"method": "get",
"path": "/ws/2/artist/c8da2e40-bd28-4d4e-813a-bd2f51958ba8?secretKey=*",
"rawHeaders": [
"Date",
"Wed, 15 Nov 2017 05:14:02 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Content-Length",
"543",
"Connection",
"close",
"Vary",
"Accept-Encoding",
"X-RateLimit-Limit",
"1200",
"X-RateLimit-Remaining",
"977",
"X-RateLimit-Reset",
"1510722843",
"Server",
"Plack::Handler::Starlet",
"ETag",
"\"9de386ef7b673bb50e5e89cc71228721\"",
"Access-Control-Allow-Origin",
"*"
],
"reqheaders": {
"accept": "application/json, text/plain, */*",
"host": "musicbrainz.org"
},
"response": {
"area": {
"disambiguation": "",
"id": "10adc6b5-63bf-4b4e-993e-ed83b05c22fc",
"name": "Seattle",
"sort-name": "Seattle"
},
"begin_area": {
"disambiguation": "",
"id": "10adc6b5-63bf-4b4e-993e-ed83b05c22fc",
"name": "Seattle",
"sort-name": "Seattle"
},
"country": null,
"disambiguation": "Seattle trio",
"end_area": null,
"gender": null,
"gender-id": null,
"id": "c8da2e40-bd28-4d4e-813a-bd2f51958ba8",
"ipis": [
],
"isnis": [
],
"life-span": {
"begin": "2013",
"end": null,
"ended": false
},
"name": "Lures",
"sort-name": "Lures",
"type": "Group",
"type-id": "e431f5f6-b5d2-343d-8b36-72607fffb74b"
},
"scope": "https://musicbrainz.org:443",
"status": 200
}
]
],
[
"using axios",
[
Expand All @@ -8,7 +81,7 @@
"path": "/ws/2/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da?fmt=json",
"rawHeaders": [
"Date",
"Tue, 14 Nov 2017 22:43:00 GMT",
"Wed, 15 Nov 2017 05:13:59 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Content-Length",
Expand All @@ -20,13 +93,13 @@
"X-RateLimit-Limit",
"1200",
"X-RateLimit-Remaining",
"936",
"775",
"X-RateLimit-Reset",
"1510699381",
"1510722839",
"Server",
"Plack::Handler::Starlet",
"ETag",
"\"659eb936a5e87d3eeab9ebb20c96a89d\"",
"\"e9a6ecc6f0f6d9cd0a3919a8059e5e64\"",
"Access-Control-Allow-Origin",
"*"
],
Expand Down Expand Up @@ -85,7 +158,7 @@
"path": "/ws/2/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da?fmt=xml",
"rawHeaders": [
"Date",
"Tue, 14 Nov 2017 22:43:02 GMT",
"Wed, 15 Nov 2017 05:14:01 GMT",
"Content-Type",
"application/xml; charset=utf-8",
"Content-Length",
Expand All @@ -97,21 +170,21 @@
"X-RateLimit-Limit",
"1200",
"X-RateLimit-Remaining",
"1039",
"875",
"X-RateLimit-Reset",
"1510699383",
"1510722841",
"Server",
"Plack::Handler::Starlet",
"ETag",
"\"38f45b3b95490f830f2350bc2b294cbd\"",
"\"56835d8780972b12afe798073a089984\"",
"Access-Control-Allow-Origin",
"*"
],
"reqheaders": {
"accept": "application/json, text/plain, */*",
"host": "musicbrainz.org"
},
"response": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><metadata xmlns=\"http://musicbrainz.org/ns/mmd-2.0#\"><artist id=\"5b11f4ce-a62d-471e-81fc-a69a8278c7da\" type-id=\"e431f5f6-b5d2-343d-8b36-72607fffb74b\" type=\"Group\"><name>Nirvana</name><sort-name>Nirvana</sort-name><disambiguation>90s US grunge band</disambiguation><isni-list><isni>0000000123486830</isni></isni-list><country>US</country><area id=\"489ce91b-6658-3307-9877-795b68554c98\"><name>United States</name><sort-name>United States</sort-name><iso-3166-1-code-list><iso-3166-1-code>US</iso-3166-1-code></iso-3166-1-code-list></area><begin-area id=\"a640b45c-c173-49b1-8030-973603e895b5\"><name>Aberdeen</name><sort-name>Aberdeen</sort-name></begin-area><life-span><begin>1988-01</begin><end>1994-04-05</end><ended>true</ended></life-span></artist></metadata>",
"response": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><metadata xmlns=\"http://musicbrainz.org/ns/mmd-2.0#\"><artist type=\"Group\" type-id=\"e431f5f6-b5d2-343d-8b36-72607fffb74b\" id=\"5b11f4ce-a62d-471e-81fc-a69a8278c7da\"><name>Nirvana</name><sort-name>Nirvana</sort-name><disambiguation>90s US grunge band</disambiguation><isni-list><isni>0000000123486830</isni></isni-list><country>US</country><area id=\"489ce91b-6658-3307-9877-795b68554c98\"><name>United States</name><sort-name>United States</sort-name><iso-3166-1-code-list><iso-3166-1-code>US</iso-3166-1-code></iso-3166-1-code-list></area><begin-area id=\"a640b45c-c173-49b1-8030-973603e895b5\"><name>Aberdeen</name><sort-name>Aberdeen</sort-name></begin-area><life-span><begin>1988-01</begin><end>1994-04-05</end><ended>true</ended></life-span></artist></metadata>",
"scope": "https://musicbrainz.org:443",
"status": 200
}
Expand Down
Loading

0 comments on commit 45e45bc

Please sign in to comment.