Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(scope): add filtering when loading definitions #2186

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -1411,6 +1411,9 @@ As an optional second parameter you can pass the following options
- `after`: a postprocessing function, gets called after nock.define
- `afterRecord`: a postprocessing function, gets called after recording. Is passed the array of scopes recorded and should return the intact array, a modified version of the array, or if custom formatting is desired, a stringified version of the array to save to the fixture
- `recorder`: custom options to pass to the recorder
- `filter`: an option filtering object
- `filter.id`: an id on which a filtering will be applied
- `filter.goup`: a group name on which a filtering will be applied

##### Example

Expand Down
5 changes: 4 additions & 1 deletion lib/back.js
Expand Up @@ -42,6 +42,9 @@ try {
* @param {function} afterRecord - a postprocessing function, gets called after recording. Is passed the array
* of scopes recorded and should return the array scopes to save to the fixture
* @param {function} recorder - custom options to pass to the recorder
* @param {object} filter - an option filtering object
* @param {string} filter.group - an id on which a filtering will be applied
* @param {string} filter.id - a group name on which a filtering will be applied
*
*/
function Back(fixtureName, options, nockedFn) {
Expand Down Expand Up @@ -202,7 +205,7 @@ function load(fixture, options) {
}

if (fixture && fixtureExists(fixture)) {
let scopes = loadDefs(fixture)
let scopes = loadDefs(fixture, options)
applyHook(scopes, options.before)

scopes = define(scopes)
Expand Down
18 changes: 16 additions & 2 deletions lib/scope.js
Expand Up @@ -249,13 +249,23 @@ class Scope extends EventEmitter {
}
}

function loadDefs(path) {
function loadDefs(path, options) {
if (!fs) {
throw new Error('No fs')
}

const contents = fs.readFileSync(path)
return JSON.parse(contents)
const defsArray = JSON.parse(contents)
if (options && options.filter && options.filter.id) {
const defFound = defsArray.find(object => object.id === options.filter.id)
return defFound ? [defFound] : []
}

if (options && options.filter && options.filter.group) {
return defsArray.filter(def => def.group === options.filter.group)
}

return defsArray
}

function load(path) {
Expand Down Expand Up @@ -359,6 +369,10 @@ function define(nockDefs) {
.intercept(npath, method, nockDef.body)
.reply(status, response, rawHeaders)

if (nockDef.persist) {
scope.persist()
}

scopes.push(scope)
})

Expand Down
49 changes: 49 additions & 0 deletions tests/fixtures/filtered_by_id_requests.json
@@ -0,0 +1,49 @@
[
{
"id": "435544",
"group": "345666",
"scope": "http://www.example.test:80",
"method": "GET",
"path": "/",
"body": "",
"status": 200,
"response": "",
"headers": {
"cache-control": "private, max-age=0",
"content-type": "text/html; charset=ISO-8859-1",
"set-cookie": [
"PREF=ID=61e37f09ab4c9630:FF=0:TM=1412829102:LM=1412829102:S=n4CvWIEl9Nh9pgAq; expires=Sat, 08-Oct-2016 04:31:42 GMT; path=/; domain=.google.com",
"NID=67=EeZ2zt5Y7FEID_Mmw7unRUwQWdAjS_2ZwixURIotpGpjBIYLTf6DdhnNWwlVBozGq8Xhsz3LljeqvNZ6dlLOE2s2DH0fpAc-UmOB210Z_SAEOtEQPzbRlPDY_No1MjHr; expires=Fri, 10-Apr-2015 04:31:42 GMT; path=/; domain=.google.com; HttpOnly"
],
"p3p": "CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"",
"server": "gws",
"x-xss-protection": "1; mode=block",
"x-frame-options": "SAMEORIGIN",
"alternate-protocol": "80:quic,p=0.01",
"transfer-encoding": "chunked"
}
},
{
"group": "345666",
"scope": "http://www.example.test:80",
"method": "GET",
"path": "/",
"body": "",
"status": 200,
"response": "",
"headers": {
"cache-control": "private, max-age=0",
"content-type": "text/html; charset=ISO-8859-1",
"set-cookie": [
"PREF=ID=61e37f09ab4c9630:FF=0:TM=1412829102:LM=1412829102:S=n4CvWIEl9Nh9pgAq; expires=Sat, 08-Oct-2016 04:31:42 GMT; path=/; domain=.google.com",
"NID=67=EeZ2zt5Y7FEID_Mmw7unRUwQWdAjS_2ZwixURIotpGpjBIYLTf6DdhnNWwlVBozGq8Xhsz3LljeqvNZ6dlLOE2s2DH0fpAc-UmOB210Z_SAEOtEQPzbRlPDY_No1MjHr; expires=Fri, 10-Apr-2015 04:31:42 GMT; path=/; domain=.google.com; HttpOnly"
],
"p3p": "CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"",
"server": "gws",
"x-xss-protection": "1; mode=block",
"x-frame-options": "SAMEORIGIN",
"alternate-protocol": "80:quic,p=0.01",
"transfer-encoding": "chunked"
}
}
]
1 change: 1 addition & 0 deletions tests/fixtures/good_request.json

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions tests/test_scope.js
Expand Up @@ -25,6 +25,38 @@ it('scope exposes interceptors', () => {
})
})

describe('`Scope#loadDefs`', () => {
it('should load only the request matching id', () => {
const scopes = nock.loadDefs(
path.join(__dirname, 'fixtures', 'filtered_by_id_requests.json'),
{ filter: { id: '435544' } }
)

expect(scopes).to.be.an.instanceOf(Array)
expect(scopes).to.have.lengthOf.at.least(1)
})

it('should load no request given the id does not match definition', () => {
const scopes = nock.loadDefs(
path.join(__dirname, 'fixtures', 'filtered_by_id_requests.json'),
{ filter: { id: 'no-match' } }
)

expect(scopes).to.be.an.instanceOf(Array)
expect(scopes).to.have.lengthOf.at.least(0)
})

it('should load only requests matching group', () => {
const scopes = nock.loadDefs(
path.join(__dirname, 'fixtures', 'filtered_by_id_requests.json'),
{ filter: { group: '345666' } }
)

expect(scopes).to.be.an.instanceOf(Array)
expect(scopes).to.have.lengthOf.at.least(2)
})
})

describe('`Scope#constructor`', () => {
it('accepts the output of url.parse', async () => {
const scope = nock(url.parse('http://example.test')).get('/').reply()
Expand Down
6 changes: 5 additions & 1 deletion types/index.d.ts
Expand Up @@ -25,7 +25,7 @@ declare namespace nock {
matcher?: string | RegExp | ((host: string) => boolean)
): void
function load(path: string): Scope[]
function loadDefs(path: string): Definition[]
function loadDefs(path: string, options?: OptionsDefs): Definition[]
function define(defs: Definition[]): Scope[]
function restore(): void
function abortPendingRequests(): void
Expand All @@ -34,6 +34,9 @@ declare namespace nock {
let emitter: NodeJS.EventEmitter
let recorder: Recorder

type OptionsDefs = {
filter?: { id?: string; group?: string }
}
type InterceptFunction = (
uri: string | RegExp | { (uri: string): boolean },
requestBody?: RequestBodyMatcher,
Expand Down Expand Up @@ -270,6 +273,7 @@ declare namespace nock {
after?: (scope: Scope) => void
afterRecord?: (defs: Definition[]) => Definition[]
recorder?: RecorderOptions
filter?: OptionsDefs
}
}

Expand Down