Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mockyeah

Package Overview
Dependencies
Maintainers
2
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mockyeah - npm Package Compare versions

Comparing version 0.18.4 to 0.19.0

.nyc_output/6404b0c065e64dd284ca694e435e1f71.json

56

app/lib/helpers.js

@@ -8,2 +8,58 @@ const path = require('path');

const handleContentType = (body, headers) => {
const contentType = headers['content-type'];
// TODO: More spec-conformant detection of JSON content type.
if (contentType && contentType.includes('/json')) {
/* eslint-disable no-empty */
try {
const json = JSON.parse(body);
return {
json
};
} catch (err) {
// silence any errors, invalid JSON is ok
}
/* eslint-enable no-empty */
}
return {
raw: body
};
};
const replaceFixtureWithRequireInJson = (json, { relativePath }) =>
json.replace(
/"fixture"(\s*):(\s*)"([^"]+)\.json"/g,
`"json"$1:$2require("${relativePath}/$3.json")`
);
const getDataForRecordToFixtures = ({ responseOptions, name, index }) => {
const newResponseOptions = Object.assign({}, responseOptions);
const { raw, json } = responseOptions;
const fixtureName = `${name}/${index}`;
let body;
if (raw) {
newResponseOptions.fixture = `${fixtureName}.txt`;
body = raw;
delete newResponseOptions.raw;
} else if (json) {
newResponseOptions.fixture = `${fixtureName}.json`;
body = JSON.stringify(json, null, 2);
delete newResponseOptions.json;
}
return {
newResponseOptions,
body
};
};
exports.getDataForRecordToFixtures = getDataForRecordToFixtures;
exports.replaceFixtureWithRequireInJson = replaceFixtureWithRequireInJson;
exports.handleContentType = handleContentType;
exports.resolveFilePath = resolveFilePath;

2

app/lib/RouteManager.js

@@ -14,3 +14,3 @@ 'use strict';

register: function register(method, _path, response) {
app.log(['serve', 'mount', method], _path.path || _path);
app.log(['serve', 'mount', method], _path.path || _path.url || _path);
return routeResolver.register(method, _path, response);

@@ -17,0 +17,0 @@ },

const request = require('request');
const isAbsoluteUrl = require('is-absolute-url');
const { isEmpty } = require('lodash');
const { handleContentType } = require('./lib/helpers');

@@ -71,3 +72,3 @@ const now = () => new Date().getTime();

const { only } = recordMeta;
const { options: { headers: optionsHeaders, only, useHeaders, useLatency } = {} } = recordMeta;

@@ -94,4 +95,4 @@ if (only && !only(reqUrl)) return;

if (recordMeta.headers && Object.keys(recordMeta.headers).length > 0) {
match.headers = recordMeta.headers;
if (optionsHeaders && Object.keys(optionsHeaders).length > 0) {
match.headers = Object.assign({}, optionsHeaders);
}

@@ -109,11 +110,18 @@

recordMeta.set.push([
match,
const responseOptions = Object.assign(
{
headers,
status,
raw: _body, // TODO: Support JSON response deserialized
latency
}
]);
status
},
handleContentType(_body, headers)
);
if (useHeaders) {
responseOptions.headers = headers;
}
if (useLatency) {
responseOptions.latency = latency;
}
recordMeta.set.push([match, responseOptions]);
}).pipe(res);

@@ -120,0 +128,0 @@ };

@@ -5,7 +5,7 @@ module.exports = app => (name, options = {}) => {

app.locals.recording = true;
if (!name) throw new Error('Must provide a recording name.');
app.log(['serve', 'record'], name);
if (options.only) {
if (options.only && typeof options.only === 'string') {
// if only is truthy, assume it is a regex pattern

@@ -17,7 +17,9 @@ const regex = new RegExp(options.only);

const enhancedOptions = Object.assign({}, options, {
only
});
app.locals.recordMeta = {
headers: options.headers,
name,
options,
only,
options: enhancedOptions,
set: []

@@ -24,0 +26,0 @@ };

const fs = require('fs');
const path = require('path');
const mkdirp = require('mkdirp');
const { resolveFilePath } = require('./lib/helpers');
const {
resolveFilePath,
getDataForRecordToFixtures,
replaceFixtureWithRequireInJson
} = require('./lib/helpers');

@@ -13,2 +17,4 @@ module.exports = app => cb => {

const { recordToFixtures, recordToFixturesMode } = app.config;
const {

@@ -20,3 +26,4 @@ recordMeta: { name, set }

const { capturesDir } = app.config;
const { capturesDir, fixturesDir } = app.config;
const capturePath = path.join(capturesDir, name);

@@ -28,10 +35,45 @@

set.forEach(capture => {
app.log(['serve', 'capture'], capture[0].url);
const newSet = set.map((capture, index) => {
const [match, responseOptions] = capture;
app.log(['serve', 'capture'], match.url || match.path || match);
if (recordToFixtures) {
const { newResponseOptions, body } = getDataForRecordToFixtures({
responseOptions,
name,
index
});
const { fixture } = newResponseOptions;
if (fixture) {
const fixturesPath = path.join(fixturesDir, fixture);
// TODO: Any easy way to coordinate this asynchronously?
// eslint-disable-next-line no-sync
mkdirp.sync(path.join(fixturesDir, name));
// TODO: Any easy way to coordinate this asynchronously?
// eslint-disable-next-line no-sync
fs.writeFileSync(fixturesPath, body);
}
return [match, newResponseOptions];
}
return [match, responseOptions];
});
const json = JSON.stringify(set, null, 2);
const js = `module.exports = ${json};`;
let js = JSON.stringify(newSet, null, 2);
fs.writeFile(filePath, js, err => {
if (recordToFixturesMode === 'require') {
js = replaceFixtureWithRequireInJson(js, {
relativePath: path.relative(capturePath, fixturesDir)
});
}
const jsModule = `module.exports = ${js};`;
fs.writeFile(filePath, jsModule, err => {
if (err) {

@@ -46,3 +88,3 @@ app.log(['record', 'response', 'error'], err);

set.forEach(capture => {
app.log(['record', 'response', 'saved'], capture[0].url);
app.log(['record', 'response', 'saved'], capture[0].path || capture[0].url || capture[0]);
});

@@ -49,0 +91,0 @@

@@ -20,3 +20,5 @@ 'use strict';

adminHost: 'localhost',
adminPort: 4777
adminPort: 4777,
recordToFixtures: true,
recordToFixturesMode: 'path'
};

@@ -23,0 +25,0 @@

{
"name": "mockyeah",
"version": "0.18.4",
"version": "0.19.0",
"description": "A powerful service mocking, recording, and playback utility.",

@@ -86,3 +86,3 @@ "main": "index.js",

"private": false,
"gitHead": "91aebe566a09d77e9a4299957bbe972b43f5f680"
"gitHead": "22fbf7bcd4f2e41d282cd9c324a150caf33ab7c2"
}

@@ -75,3 +75,3 @@ 'use strict';

const captureName = 'some-fancy-capture';
const captureName = 'test-some-fancy-admin-server-capture';

@@ -164,3 +164,3 @@ // Construct remote service urls

const captureName = 'some-fancy-capture-3';
const captureName = 'test-some-fancy-admin-server-capture-3';

@@ -254,3 +254,3 @@ // Construct remote service urls

const captureName = 'some-fancy-capture-all';
const captureName = 'test-some-fancy-admin-server-capture-all';

@@ -257,0 +257,0 @@ // Construct remote service urls

@@ -73,3 +73,3 @@ 'use strict';

const captureName = 'some-fancy-capture';
const captureName = 'test-some-fancy-capture';

@@ -86,3 +86,3 @@ // Construct remote service urls

remote.get('/some/service/one', { text: 'first' });
remote.get('/some/service/two', { text: 'second' });
remote.get('/some/service/two', { json: { second: true } });
remote.get('/some/service/three', { text: 'third', headers: {} });

@@ -109,3 +109,3 @@ remote.get('/some/service/four');

cb => proxyReq.get(path1).expect(200, 'first', cb),
cb => proxyReq.get(path2).expect(200, 'second', cb),
cb => proxyReq.get(path2).expect(200, '{"second":true}', cb),
cb => proxyReq.get(path3).expect(200, 'third', cb),

@@ -159,3 +159,3 @@ cb => proxyReq.get(path4).expect(200, cb),

cb => remoteReq.get(path1).expect(200, 'first', cb),
cb => remoteReq.get(path2).expect(200, 'second', cb),
cb => remoteReq.get(path2).expect(200, '{"second":true}', cb),
cb => remoteReq.get(path3).expect(200, 'third', cb),

@@ -172,3 +172,3 @@ cb => remoteReq.get(path4).expect(200, cb),

cb => proxyReq.get(path1).expect(200, 'first', cb),
cb => proxyReq.get(path2).expect(200, 'second', cb),
cb => proxyReq.get(path2).expect(200, '{\n "second": true\n}', cb),
cb => proxyReq.get(path3).expect(200, 'third', cb),

@@ -189,3 +189,3 @@ cb => proxyReq.get(path4).expect(200, cb),

const captureName = 'some-fancy-capture-2';
const captureName = 'test-some-fancy-capture-2';

@@ -201,3 +201,3 @@ // Construct remote service urls

remote.get('/some/service/one', { text: 'first' });
remote.get('/some/service/two', { text: 'second' });
remote.get('/some/service/two', { json: { second: true } });
remote.get('/some/service/three', { text: 'third' });

@@ -218,3 +218,3 @@ remote.get('/some/service/three/:id', { text: 'fourth' });

cb => proxyReq.get(path1).expect(200, 'first', cb),
cb => proxyReq.get(path2).expect(200, 'second', cb),
cb => proxyReq.get(path2).expect(200, '{"second":true}', cb),
cb => proxyReq.get(path3).expect(200, 'third', cb),

@@ -263,3 +263,3 @@ cb => proxyReq.get(path4).expect(200, 'fourth', cb),

cb => remoteReq.get(path1).expect(200, 'first', cb),
cb => remoteReq.get(path2).expect(200, 'second', cb),
cb => remoteReq.get(path2).expect(200, '{"second":true}', cb),
cb => remoteReq.get(path3).expect(200, 'third', cb),

@@ -282,3 +282,3 @@ cb => remoteReq.get(path4).expect(200, 'fourth', cb),

const captureName = 'some-fancy-capture-3';
const captureName = 'test-some-fancy-capture-3';

@@ -368,3 +368,3 @@ // Construct remote service urls

const captureName = 'some-fancy-capture-3';
const captureName = 'test-some-fancy-capture-3';

@@ -442,6 +442,131 @@ // Construct remote service urls

it('should record and playback call headers with `useHeaders` option', function(done) {
this.timeout = 10000;
const captureName = 'test-some-fancy-capture-using-headers';
// Construct remote service urls
// e.g. http://localhost:4041/http://example.com/some/service
const path1 = '/some/service/one';
// Mount remote service end points
remote.get('/some/service/one', {
headers: {
'x-my-header': 'My-Value'
}
});
// Initiate recording and playback series
async.series(
[
// Initiate recording
cb => {
proxy.record(captureName, {
useHeaders: true
});
cb();
},
// Invoke requests to remote services through proxy
// e.g. http://localhost:4041/http://example.com/some/service
cb => proxyReq.get(path1).expect('x-my-header', 'My-Value', cb),
// Stop recording
cb => {
proxy.recordStop(cb);
},
// Assert capture file exists
cb => {
fs.statSync(getCaptureFilePath(captureName));
cb();
},
// Reset proxy services and play captured capture
cb => {
proxy.reset();
cb();
},
cb => {
proxy.play(captureName);
cb();
},
// Test remote url paths and their sub paths route to the same services
// Assert remote url paths are routed the correct responses
// e.g. http://localhost:4041/http://example.com/some/service
cb => remoteReq.get(path1).expect('x-my-header', 'My-Value', cb),
// Assert paths are routed the correct responses
cb => proxyReq.get(path1).expect('x-my-header', 'My-Value', cb)
],
done
);
});
it('should record and playback call latency with `useLatency` option', function(done) {
this.timeout = 10000;
const captureName = 'test-some-fancy-capture-using-latency';
// Construct remote service urls
// e.g. http://localhost:4041/http://example.com/some/service
const path1 = '/some/service/one';
// Mount remote service end points
remote.get('/some/service/one', {
latency: 200
});
// Initiate recording and playback series
async.series(
[
// Initiate recording
cb => {
proxy.record(captureName, {
useLatency: true
});
cb();
},
// Invoke requests to remote services through proxy
// e.g. http://localhost:4041/http://example.com/some/service
cb => proxyReq.get(path1).expect(200, cb),
// Stop recording
cb => {
proxy.recordStop(cb);
},
// Assert capture file exists
cb => {
fs.statSync(getCaptureFilePath(captureName));
cb();
},
// Reset proxy services and play captured capture
cb => {
proxy.reset();
cb();
},
cb => {
proxy.play(captureName);
cb();
},
// Test remote url paths and their sub paths route to the same services
// Assert remote url paths are routed the correct responses
// e.g. http://localhost:4041/http://example.com/some/service
cb => remoteReq.get(path1).expect(200, cb)
],
done
);
});
it('should record and playback call with playAll', function(done) {
this.timeout = 10000;
const captureName = 'some-fancy-capture-all';
const captureName = 'test-some-fancy-capture-all';

@@ -458,3 +583,3 @@ // Construct remote service urls

remote.get('/some/service/one', { text: 'first' });
remote.get('/some/service/two', { text: 'second' });
remote.get('/some/service/two', { json: { second: true } });
remote.get('/some/service/three', { text: 'third' });

@@ -476,3 +601,3 @@ remote.get('/some/service/four', { text: 'fourth' });

cb => proxyReq.get(path1).expect(200, 'first', cb),
cb => proxyReq.get(path2).expect(200, 'second', cb),
cb => proxyReq.get(path2).expect(200, '{"second":true}', cb),
cb => proxyReq.get(path3).expect(200, 'third', cb),

@@ -522,3 +647,3 @@ cb => proxyReq.get(path4).expect(200, 'fourth', cb),

cb => remoteReq.get(path1).expect(200, 'first', cb),
cb => remoteReq.get(path2).expect(200, 'second', cb),
cb => remoteReq.get(path2).expect(200, '{"second":true}', cb),
cb => remoteReq.get(path3).expect(200, 'third', cb),

@@ -531,3 +656,3 @@ cb => remoteReq.get(path4).expect(200, 'fourth', cb),

cb => proxyReq.get(path1).expect(200, 'first', cb),
cb => proxyReq.get(path2).expect(200, 'second', cb),
cb => proxyReq.get(path2).expect(200, '{\n "second": true\n}', cb),
cb => proxyReq.get(path3).expect(200, 'third', cb),

@@ -534,0 +659,0 @@ cb => proxyReq.get(path4).expect(200, 'fourth', cb),

@@ -41,5 +41,8 @@ 'use strict';

record: false,
verbose: false
verbose: false,
recordToFixtures: true,
recordToFixturesMode: 'path'
});
});
it('should work and use defaults with empty config input', () => {

@@ -63,5 +66,7 @@ const config = prepareConfig({});

record: false,
verbose: false
verbose: false,
recordToFixtures: true,
recordToFixturesMode: 'path'
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc