Skip to content

Commit 55fabfd

Browse files
committed
namshi#67 Accept wildcards for parameters
1 parent 200ede1 commit 55fabfd

File tree

3 files changed

+89
-17
lines changed

3 files changed

+89
-17
lines changed

mockserver.js

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function parseStatus(header) {
2525
* Parses an HTTP header, splitting
2626
* by colon.
2727
*/
28-
const parseHeader = function (header, context, request) {
28+
const parseHeader = function(header, context, request) {
2929
header = header.split(': ');
3030

3131
return { key: normalizeHeader(header[0]), value: parseValue(header[1], context, request) };
@@ -283,27 +283,87 @@ function getBody(req, callback) {
283283
}
284284

285285
function getMockedContent(path, prefix, body, query) {
286-
const mockName = prefix + (getBodyOrQueryString(body, query) || '') + '.mock';
287-
const mockFile = join(mockserver.directory, path, mockName);
288-
let content;
286+
// Check for an exact match
287+
const exactName = prefix + (getBodyOrQueryString(body, query) || '') + '.mock';
288+
let content = handleMatch(path, exactName, fs.existsSync);
289289

290-
try {
291-
content = fs.readFileSync(mockFile, { encoding: 'utf8' });
292-
if (mockserver.verbose) {
293-
console.log(
294-
'Reading from ' + mockFile.yellow + ' file: ' + 'Matched'.green
295-
);
290+
// Compare params without regard to order
291+
if (!content && query && !body) {
292+
content = testForQuery(path, prefix, query, false);
293+
294+
// Compare params without regard to order and allow wildcards
295+
if (!content) {
296+
content = testForQuery(path, prefix, query, true);
296297
}
297-
} catch (err) {
298-
if (mockserver.verbose) {
299-
console.log(
300-
'Reading from ' + mockFile.yellow + ' file: ' + 'Not matched'.red
298+
}
299+
300+
// fallback option (e.g. GET.mock). ignores body and query
301+
if (!content) {
302+
const fallbackName = prefix + '.mock';
303+
content = handleMatch(path, fallbackName, fs.existsSync);
304+
}
305+
306+
return content;
307+
}
308+
309+
function testForQuery(path, prefix, query, allowWildcards) {
310+
// Find all files in the directory
311+
return fs
312+
.readdirSync(join(mockserver.directory, path))
313+
.filter(possibleFile => possibleFile.startsWith(prefix) && possibleFile.endsWith('.mock'))
314+
.filter(possibleFile => possibleFile.match(/--[\s\S]*__/))
315+
.reduce((prev, possibleFile) => {
316+
if (prev) {
317+
return prev;
318+
}
319+
320+
let isMatch = true;
321+
//get params from file
322+
const paramMap = queryStringToMap(query);
323+
const possibleFileParamMap = queryStringToMap(
324+
possibleFile.replace('.mock', '').split('--')[1]
301325
);
326+
327+
for (const key in paramMap) {
328+
if (!isMatch) {
329+
continue;
330+
}
331+
isMatch =
332+
possibleFileParamMap[key] === paramMap[key] ||
333+
(allowWildcards && possibleFileParamMap[key] === '__');
334+
}
335+
336+
return handleMatch(path, possibleFile, isMatch);
337+
}, undefined);
338+
}
339+
340+
function queryStringToMap(query) {
341+
const result = {};
342+
query.split('&').forEach(param => {
343+
const [key, val] = param.split('=');
344+
result[key] = val;
345+
});
346+
return result;
347+
}
348+
349+
function handleMatch(path, fileName, isMatchOrTest) {
350+
const mockFile = join(mockserver.directory, path, fileName);
351+
352+
let isMatch = isMatchOrTest;
353+
if (typeof isMatchOrTest === 'function') {
354+
isMatch = isMatchOrTest(mockFile);
355+
}
356+
357+
if (isMatch) {
358+
if (mockserver.verbose) {
359+
console.log('Reading from ' + mockFile.yellow + ' file: ' + 'Matched'.green);
302360
}
303-
content = (body || query) && getMockedContent(path, prefix);
361+
return fs.readFileSync(mockFile, { encoding: 'utf8' });
304362
}
305363

306-
return content;
364+
if (mockserver.verbose) {
365+
console.log('Reading from ' + mockFile.yellow + ' file: ' + 'Not matched'.red);
366+
}
307367
}
308368

309369
function getContentFromPermutations(path, method, body, query, permutations) {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
HTTP/1.1 200 OK
2+
3+
wildcard-params

test/mockserver.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ describe('mockserver', function() {
108108

109109
it('should combine the identical headers names', function() {
110110
processRequest('/multiple-headers-same-name/', 'GET');
111-
111+
112112
assert.equal(res.headers['Set-Cookie'].length, 3);
113113
})
114114

@@ -431,6 +431,15 @@ describe('mockserver', function() {
431431
assert.equal(res.status, 404);
432432
});
433433
});
434+
435+
describe("wildcard params", function() {
436+
it("matches a file with wildcards as query params", function() {
437+
processRequest("/wildcard-params?foo=bar&buz=baz", "GET");
438+
439+
assert.equal(res.status, 200);
440+
});
441+
});
442+
434443
describe('.getResponseDelay', function() {
435444
it('should return a value greater than zero when valid', function() {
436445
const ownValueHeaders = [

0 commit comments

Comments
 (0)