How to use mocker method in apimocker

Best JavaScript code snippet using apimocker

apimocker.js

Source:apimocker.js Github

copy

Full Screen

1/* eslint-disable no-prototype-builtins, comma-dangle */2const express = require('express');3const _ = require('underscore');4const path = require('path');5const fs = require('fs');6const bodyParser = require('body-parser');7const xmlparser = require('express-xml-bodyparser');8const jp = require('jsonpath');9const untildify = require('untildify');10const util = require('util');11const proxy = require('express-http-proxy');12const multer = require('multer');13const crypto = require('crypto');14const { createLogger, createMiddleware } = require('./logger');15const apiMocker = {};16apiMocker.defaults = {17 port: '8888',18 mockDirectory: './mocks/',19 allowedDomains: ['*'],20 allowedHeaders: ['Content-Type'],21 logRequestHeaders: false,22 allowAvoidPreFlight: false,23 useUploadFieldname: false,24 webServices: {}25};26apiMocker.createServer = (options = {}) => {27 apiMocker.options = Object.assign({}, apiMocker.defaults, options);28 const { quiet } = apiMocker.options;29 const logger = createLogger({ quiet });30 const loggerMiddleware = createMiddleware({ quiet });31 apiMocker.express = express();32 apiMocker.middlewares = [];33 apiMocker.middlewares.push(loggerMiddleware);34 if (options.uploadRoot) {35 apiMocker.middlewares.push(36 multer({37 storage: multer.diskStorage({38 destination: untildify(options.uploadRoot),39 filename: options.useUploadFieldname40 ? (req, filename, cb) => {41 cb(null, filename.fieldname);42 }43 : (req, filename, cb) => {44 cb(null, filename.originalname);45 }46 })47 }).any()48 );49 }50 let saveBody;51 if (options.proxyURL || options.allowAvoidPreFlight) {52 saveBody = (req, res, buf) => {53 req.rawBody = buf;54 };55 }56 apiMocker.middlewares.push(57 bodyParser.urlencoded({58 extended: true,59 verify: saveBody60 })61 );62 if (options.allowAvoidPreFlight) {63 apiMocker.middlewares.push(64 bodyParser.json({65 strict: false,66 verify: saveBody,67 type: '*/*'68 })69 );70 } else {71 apiMocker.middlewares.push(72 bodyParser.json({73 verify: saveBody74 })75 );76 }77 apiMocker.middlewares.push(xmlparser());78 apiMocker.middlewares.push(apiMocker.corsMiddleware);79 // new in Express 4, we use a Router now.80 apiMocker.router = express.Router();81 apiMocker.middlewares.push(apiMocker.router);82 if (options.proxyURL) {83 logger.info(`Proxying to ${options.proxyURL}`);84 const proxyOptions = {85 proxyReqPathResolver(req) {86 logger.info(`Forwarding request: ${req.originalUrl}`);87 return req.originalUrl;88 }89 };90 if (options.proxyIntercept) {91 const interceptPath = path.join(process.cwd(), options.proxyIntercept);92 logger.info(`Loading proxy intercept from ${interceptPath}`);93 // eslint-disable-next-line global-require, import/no-dynamic-require94 proxyOptions.intercept = require(interceptPath);95 }96 apiMocker.middlewares.push((req, res, next) => {97 if (req.rawBody) {98 req.body = req.rawBody;99 }100 next();101 });102 apiMocker.middlewares.push(proxy(options.proxyURL, proxyOptions));103 }104 apiMocker.logger = logger;105 return apiMocker;106};107apiMocker.setConfigFile = (file) => {108 if (!file) {109 return apiMocker;110 }111 if (!file.startsWith(path.sep)) {112 // relative path from command line113 apiMocker.configFilePath = path.resolve(process.cwd(), file);114 } else {115 apiMocker.configFilePath = file;116 }117 return apiMocker;118};119apiMocker.loadConfigFile = () => {120 if (!apiMocker.configFilePath) {121 apiMocker.logger.warn('No config file path set.');122 return;123 }124 apiMocker.logger.info(`Loading config file: ${apiMocker.configFilePath}`);125 let newOptions = _.clone(apiMocker.defaults);126 // eslint-disable-next-line global-require, import/no-dynamic-require127 const exportedValue = require(apiMocker.configFilePath);128 const config = typeof exportedValue === 'function' ? exportedValue() : exportedValue;129 if (process.env.VCAP_APP_PORT) {130 // we're running in cloudfoundry, and we need to use the VCAP port.131 config.port = process.env.VCAP_APP_PORT;132 }133 newOptions = _.extend(newOptions, apiMocker.options, config);134 newOptions.mockDirectory = untildify(newOptions.mockDirectory);135 if (newOptions.mockDirectory === '/file/system/path/to/apimocker/samplemocks/') {136 newOptions.mockDirectory = path.join(__dirname, '/../samplemocks');137 apiMocker.logger.info('Set mockDirectory to: ', newOptions.mockDirectory);138 }139 apiMocker.options = newOptions;140 _.each(apiMocker.options.webServices, (svc) => {141 _.each(svc.alternatePaths, (altPath) => {142 const altSvc = _.clone(svc);143 apiMocker.options.webServices[altPath] = altSvc;144 });145 });146 apiMocker.setRoutes(apiMocker.options.webServices);147};148apiMocker.createAdminServices = () => {149 apiMocker.router.all('/admin/reload', (req, res) => {150 apiMocker.stop();151 apiMocker.createServer(apiMocker.options).start();152 res.writeHead(200, { 'Content-Type': 'application/json' });153 res.end(`{"configFilePath": "${apiMocker.configFilePath}", "reloaded": "true"}`);154 });155 apiMocker.router.all('/admin/setMock', (req, res) => {156 let newRoute = {};157 if (req.body.serviceUrl && req.body.verb && req.body.mockFile) {158 apiMocker.logger.info(`Received JSON request: ${JSON.stringify(req.body)}`);159 newRoute = req.body;160 newRoute.verb = newRoute.verb.toLowerCase();161 newRoute.httpStatus = req.body.httpStatus;162 } else {163 newRoute.verb = req.param('verb').toLowerCase();164 newRoute.serviceUrl = req.param('serviceUrl');165 newRoute.mockFile = req.param('mockFile');166 newRoute.latency = req.param('latency');167 newRoute.contentType = req.param('contentType');168 newRoute.httpStatus = req.param('httpStatus');169 }170 // also need to save in our webServices object.171 delete apiMocker.options.webServices[newRoute.serviceUrl];172 apiMocker.options.webServices[newRoute.serviceUrl] = newRoute;173 apiMocker.setRoute(newRoute);174 res.writeHead(200, { 'Content-Type': 'application/json' });175 res.end(JSON.stringify(newRoute));176 });177};178apiMocker.setRoutes = (webServices) => {179 const topLevelKeys = _.keys(webServices);180 _.each(topLevelKeys, (key) => {181 const svc = _.clone(webServices[key]);182 // apiMocker.logger.info('about to add a new service: ' + JSON.stringify(svc));183 _.each(svc.verbs, (v) => {184 apiMocker.setRoute(apiMocker.getServiceRoute(key, v));185 });186 });187};188apiMocker.getServiceRoute = (routePath, verb) => {189 let finalSvc = _.clone(apiMocker.options.webServices[routePath]);190 finalSvc.verb = verb.toLowerCase();191 finalSvc.serviceUrl = routePath;192 if (finalSvc.responses) {193 finalSvc = _.extend(finalSvc, finalSvc.responses[verb]);194 }195 if (typeof finalSvc.latency === 'undefined') {196 finalSvc.latency = apiMocker.options.latency ? apiMocker.options.latency : 0;197 }198 delete finalSvc.responses;199 delete finalSvc.verbs;200 return finalSvc;201};202// Fills in templated Values.203apiMocker.fillTemplate = (data, req) => {204 let filled = data.toString();205 Object.keys(req.params).forEach((key) => {206 // Handle unquoted numbers first207 // Search for '"@@key"' in JSON template,208 // replace with value (no double quotes around final value)209 filled = filled.replace(new RegExp(`"@@${key}"`, 'g'), req.params[key]);210 // Handle quoted values second211 // Search for '@key' in JSON template, replace with value212 filled = filled.replace(new RegExp(`@${key}`, 'g'), req.params[key]);213 });214 return filled;215};216apiMocker.fillTemplateSwitch = (options, data) => {217 const switches = options.templateSwitch;218 let filled = data.toString();219 switches.forEach((s) => {220 let key;221 let value;222 if (!(s instanceof Object)) {223 ({ key, value } = switches[s]);224 } else {225 ({ key, value } = s);226 }227 if (value !== null) {228 // Handle unquoted numbers first229 // Search for '"@@key"' in JSON template,230 // replace with value (no double quotes around final value)231 apiMocker.logger.info(`fillTemplateSwitch -> search for "@@${key}" replace with ${value}`);232 filled = filled.replace(new RegExp(`"@@${key}"`, 'g'), value);233 // Handle quoted values second234 // Search for '@key' in JSON template, replace with value235 apiMocker.logger.info(`fillTemplateSwitch -> search for @${key} replace with ${value}`);236 filled = filled.replace(new RegExp(`@${key}`, 'g'), value);237 } else {238 apiMocker.logger.info(`fillTemplateSwitch -> skipping search for @${key} with no value.`);239 }240 });241 return filled;242};243apiMocker.processTemplateData = (data, options, req, res) => {244 let templatedData;245 if (options.templateSwitch) {246 templatedData = apiMocker.fillTemplateSwitch(options, data, req);247 }248 if (options.enableTemplate === true) {249 templatedData = apiMocker.fillTemplate(data, req);250 }251 const buff = Buffer.from(templatedData || data, 'utf8');252 res.status(options.httpStatus || 200).send(buff);253};254apiMocker.sendResponse = (req, res, serviceKeys) => {255 let originalOptions;256 let mockPath;257 // we want to look up the service info from our in-memory 'webServices' every time.258 let options = apiMocker.getServiceRoute(serviceKeys.serviceUrl, serviceKeys.verb);259 setTimeout(() => {260 if (options.httpStatus === 204 || options.httpStatus === 304) {261 // express handles these two differently - it strips out body, content-type,262 // and content-length headers.263 // There's no body or content-length, so we just send the status code.264 res.sendStatus(options.httpStatus);265 return;266 }267 // Filter whether the raw body is what we're expecting, if such filter is provided.268 if (!!options.bodies && !!options.bodies[req.method.toLowerCase()]) {269 if (270 // eslint-disable-next-line max-len271 !_.find(options.bodies[req.method.toLowerCase()], filterDef => apiMocker.compareHashed(filterDef, req.rawBody || JSON.stringify(req.body)))272 ) {273 res.status(404).send();274 return;275 }276 }277 if (options.switch && !options.jsonPathSwitchResponse) {278 options = _.clone(options);279 originalOptions = _.clone(options);280 apiMocker.setSwitchOptions(options, req);281 mockPath = path.join(apiMocker.options.mockDirectory, options.mockFile || '');282 if (!fs.existsSync(mockPath)) {283 apiMocker.logger.warn(284 `No file found: ${options.mockFile} attempting base file: ${originalOptions.mockFile}`285 );286 options.mockFile = originalOptions.mockFile;287 }288 }289 if (options.templateSwitch) {290 apiMocker.setTemplateSwitchOptions(options, req);291 }292 if (apiMocker.options.logRequestHeaders || options.logRequestHeaders) {293 apiMocker.logger.info('Request headers:');294 apiMocker.logger.info(req.headers);295 }296 if (options.headers) {297 res.set(options.headers);298 }299 if (options.mockBody) {300 if (options.contentType) {301 res.set('Content-Type', options.contentType);302 }303 apiMocker.processTemplateData(options.mockBody, options, req, res);304 return;305 }306 if (!options.mockFile) {307 const status = options.httpStatus || 404;308 res.status(status).send();309 return;310 }311 // Add mockFile name for logging312 res.locals.mockFile = options.mockFile;313 if (options.switch && options.jsonPathSwitchResponse) {314 let jpath = options.jsonPathSwitchResponse.jsonpath;315 const fpath = path.join(316 apiMocker.options.mockDirectory,317 options.jsonPathSwitchResponse.mockFile318 );319 const forceFirstObject = options.jsonPathSwitchResponse.forceFirstObject || false;320 _.each(_.keys(req.params), (key) => {321 const param = '#key#'.replace('key', key);322 jpath = jpath.replace(param, req.params[key]);323 });324 try {325 const mockFile = fs.readFileSync(fpath, { encoding: 'utf8' });326 const allElems = jp.query(JSON.parse(mockFile), jpath);327 res.status(options.httpStatus || 200).send(forceFirstObject ? allElems[0] : allElems);328 } catch (err) {329 apiMocker.logger.error(err);330 res.sendStatus(options.httpStatus || 404);331 }332 return;333 }334 mockPath = path.join(apiMocker.options.mockDirectory, options.mockFile);335 fs.exists(mockPath, (exists) => {336 if (exists) {337 if (options.contentType) {338 res.set('Content-Type', options.contentType);339 fs.readFile(mockPath, { encoding: 'utf8' }, (err, data) => {340 if (err) {341 throw err;342 }343 apiMocker.processTemplateData(data.toString(), options, req, res);344 });345 } else {346 res347 .status(options.httpStatus || 200)348 .sendFile(options.mockFile, { root: apiMocker.options.mockDirectory });349 }350 } else {351 res.sendStatus(options.httpStatus || 404);352 }353 });354 }, options.latency);355};356// Utility function to get a key's value from json body, route param, querystring, or header.357const getRequestParam = (req, key) => {358 const rawParamValue = req.body[key] || req.params[key] || req.query[key] || req.header(key);359 return rawParamValue;360};361// only used when there is a switch configured362apiMocker.setSwitchOptions = (options, req) => {363 let switchFilePrefix = '';364 let switchParamValue;365 let mockFileParts;366 let mockFilePrefix = '';367 let mockFileBaseName;368 let switches = options.switch;369 if (!(switches instanceof Array)) {370 switches = [switches];371 }372 switches.forEach((s) => {373 switchParamValue = null;374 let switchObject = s;375 let specific = true;376 if (!(s instanceof Object)) {377 // The user didn't configure a switch object. Make one.378 switchObject = {379 key: s,380 switch: s,381 type: 'default'382 };383 if (s.match(/\/(.+)\//)) {384 switchObject.type = 'regexp';385 } else if (s.indexOf('$') === 0) {386 switchObject.type = 'jsonpath';387 }388 // As we had no switch object, we have to test default-type first to389 // mimic the old behaviour.390 specific = false;391 }392 if (!switchObject.hasOwnProperty('key')) {393 // Add key if the user was too lazy394 switchObject.key = switchObject.switch;395 }396 // Sanity check the switchobject397 if (398 !switchObject.hasOwnProperty('switch')399 || !switchObject.hasOwnProperty('type')400 || !switchObject.hasOwnProperty('key')401 ) {402 return;403 }404 if (!specific || switchObject.type === 'default') {405 const rawParamValue = getRequestParam(req, switchObject.switch);406 if (rawParamValue) {407 switchParamValue = encodeURIComponent(rawParamValue);408 }409 }410 if (!switchParamValue) {411 if (switchObject.type === 'regexp') {412 const regexpTest = switchObject.switch.match(/\/(.+)\//);413 if (regexpTest) {414 // A regexp switch415 let searchBody = req.body;416 if (typeof req.body !== 'string') {417 // We don't have a body string, parse it in JSON418 searchBody = JSON.stringify(req.body);419 }420 const regexpSwitch = new RegExp(regexpTest[1]).exec(searchBody);421 if (regexpSwitch) {422 // Value is the first group423 switchParamValue = encodeURIComponent(regexpSwitch[1]);424 }425 }426 } else {427 // use JsonPath - use first value found if multiple occurances exist428 const allElems = jp.query(req.body, switchObject.switch);429 if (allElems.length > 0) {430 switchParamValue = encodeURIComponent(allElems[0]);431 }432 }433 }434 if (switchParamValue) {435 switchFilePrefix = switchFilePrefix + switchObject.key + switchParamValue;436 }437 });438 if (!switchFilePrefix) {439 return;440 }441 if (options.switchResponses && options.switchResponses[switchFilePrefix]) {442 _.extend(options, options.switchResponses[switchFilePrefix]);443 if (options.switchResponses[switchFilePrefix].mockFile) {444 return;445 }446 }447 if (options.mockFile) {448 mockFileParts = options.mockFile.split('/');449 mockFileBaseName = mockFileParts.pop();450 if (mockFileParts.length > 0) {451 mockFilePrefix = `${mockFileParts.join('/')}/`;452 }453 // eslint-disable-next-line no-param-reassign454 options.mockFile = `${mockFilePrefix + switchFilePrefix}.${mockFileBaseName}`;455 }456};457// only used when there is a templateSwitch configured458apiMocker.setTemplateSwitchOptions = (options, req) => {459 let switchParamValue;460 let switches = options.templateSwitch;461 if (!(switches instanceof Array)) {462 switches = [switches];463 }464 switches.forEach((s) => {465 switchParamValue = null;466 let switchObject = s;467 let specific = true;468 if (!(s instanceof Object)) {469 // The user didn't configure a switch object. Make one.470 switchObject = {471 key: s,472 switch: s,473 type: 'default',474 value: null475 };476 if (s.match(/\/(.+)\//)) {477 switchObject.type = 'regexp';478 } else if (s.indexOf('$') === 0) {479 switchObject.type = 'jsonpath';480 }481 // As we had no switch object, we have to test default-type first to482 // mimic the old behaviour.483 specific = false;484 }485 if (!switchObject.hasOwnProperty('key')) {486 // Add key if the user was too lazy487 switchObject.key = switchObject.switch;488 }489 // Sanity check the switchobject490 if (491 !switchObject.hasOwnProperty('switch')492 || !switchObject.hasOwnProperty('type')493 || !switchObject.hasOwnProperty('key')494 ) {495 apiMocker.logger.info(496 'templateSwitch invalid config: missing switch, type or key property. Aborting templateSwitch for this request.'497 );498 return;499 }500 if (!specific || switchObject.type === 'default') {501 const rawParamValue = getRequestParam(req, switchObject.switch);502 if (rawParamValue) {503 switchParamValue = encodeURIComponent(rawParamValue);504 }505 }506 if (!switchParamValue) {507 if (switchObject.type === 'regexp') {508 const regexpTest = switchObject.switch.match(/\/(.+)\//);509 if (regexpTest) {510 // A regexp switch511 let searchBody = req.body;512 if (typeof req.body !== 'string') {513 // We don't have a body string, parse it in JSON514 searchBody = JSON.stringify(req.body);515 }516 const regexpSwitch = new RegExp(regexpTest[1]).exec(searchBody);517 if (regexpSwitch) {518 // Value is the first group519 switchParamValue = encodeURIComponent(regexpSwitch[1]);520 }521 }522 } else {523 // use JsonPath - use first value found if multiple occurances exist524 const allElems = jp.query(req.body, switchObject.switch);525 if (allElems.length > 0) {526 switchParamValue = encodeURIComponent(allElems[0]);527 }528 }529 }530 if (switchParamValue) {531 switchObject.value = switchParamValue;532 // eslint-disable-next-line no-param-reassign533 options.templateSwitch[s] = switchObject;534 } else {535 apiMocker.logger.warn(`templateSwitch[${switchObject.switch}] value NOT FOUND`);536 }537 });538};539// Sets the route for express, in case it was not set yet.540apiMocker.setRoute = (options) => {541 const displayFile = options.mockFile || '<no mockFile>';542 const displayLatency = options.latency ? `${options.latency} ms` : '';543 apiMocker.router[options.verb](`/${options.serviceUrl}`, (req, res) => {544 apiMocker.sendResponse(req, res, options);545 });546 apiMocker.logger.info(547 `Set route: ${options.verb.toUpperCase()} ${548 options.serviceUrl549 } : ${displayFile} ${displayLatency}`550 );551 if (options.switch) {552 let switchDescription = options.switch;553 if (options.switch instanceof Array || options.switch instanceof Object) {554 switchDescription = util.inspect(options.switch);555 }556 apiMocker.logger.info(` with switch on param: ${switchDescription}`);557 }558};559// CORS middleware560apiMocker.corsMiddleware = (req, res, next) => {561 const allowedHeaders = apiMocker.options.allowedHeaders.join(',');562 const credentials = apiMocker.options.corsCredentials || '';563 res.set('Access-Control-Allow-Origin', apiMocker.options.allowedDomains);564 res.set('Access-Control-Allow-Methods', 'GET,PUT,POST,PATCH,DELETE');565 res.set('Access-Control-Allow-Headers', allowedHeaders);566 res.set('Access-Control-Allow-Credentials', credentials);567 next();568};569apiMocker.compareHashed = (filterDef, body) => {570 if (!(filterDef instanceof Object)) {571 // eslint-disable-next-line eqeqeq572 return filterDef == body;573 }574 const algo = _.keys(filterDef)[0];575 const hasher = crypto.createHash(algo);576 hasher.update(body);577 const digest = hasher.digest('hex');578 apiMocker.logger.warn(`Body hash ${algo}: ${digest}`);579 // eslint-disable-next-line eqeqeq580 return digest.toLowerCase() == filterDef[algo].toLowerCase();581};582apiMocker.start = (serverPort, callback) => {583 apiMocker.createAdminServices();584 apiMocker.loadConfigFile();585 apiMocker.middlewares.forEach((mw) => {586 if (mw === apiMocker.router && apiMocker.options.basepath) {587 apiMocker.logger.info('Using basepath: ', apiMocker.options.basepath);588 apiMocker.express.use(apiMocker.options.basepath, mw);589 } else {590 apiMocker.express.use(mw);591 }592 });593 const port = serverPort || apiMocker.options.port;594 if (apiMocker.options.staticDirectory && apiMocker.options.staticPath) {595 apiMocker.express.use(596 apiMocker.options.staticPath,597 express.static(apiMocker.options.staticDirectory)598 );599 }600 apiMocker.expressInstance = apiMocker.express.listen(port, callback);601 apiMocker.logger.info(`Mock server listening on port ${port}`);602 return apiMocker;603};604apiMocker.stop = (callback) => {605 // Invalidate cached config between uses to allow it to be reconstructed.606 delete require.cache[require.resolve(apiMocker.configFilePath)];607 if (apiMocker.expressInstance) {608 apiMocker.logger.info('Stopping mock server.');609 apiMocker.expressInstance.close(callback);610 }611 return apiMocker;612};613// expose all the 'public' methods.614exports.createServer = apiMocker.createServer;615exports.start = apiMocker.start;616exports.setConfigFile = apiMocker.setConfigFile;617exports.stop = apiMocker.stop;...

Full Screen

Full Screen

test.js

Source:test.js Github

copy

Full Screen

1// run "grunt test", or run "mocha" in this test directory to execute.2const path = require('path');3// better assertions than node offers.4const chai = require('chai');5const sinon = require('sinon');6const mockRequire = require('mock-require');7const untildify = require('untildify');8const apiMocker = require('../lib/apimocker.js');9const { assert, expect } = chai;10describe('unit tests: ', () => {11 chai.config.includeStack = true;12 describe('createServer: ', () => {13 it('sets defaults when no options are passed in', () => {14 const mocker = apiMocker.createServer();15 expect(mocker.options.port).to.equal('8888');16 expect(mocker.options.mockDirectory).to.equal('./mocks/');17 expect(mocker.options.allowedDomains.length).to.equal(1);18 expect(mocker.options.allowedDomains[0]).to.equal('*');19 expect(mocker.options.allowedHeaders[0]).to.equal('Content-Type');20 expect(mocker.options.quiet).to.equal(undefined);21 expect(mocker.options.logRequestHeaders).to.equal(false);22 });23 it('overrides defaults with command line args', () => {24 const mocker = apiMocker.createServer({ port: 1234, quiet: true, foo: 'bar' });25 expect(mocker.options.port).to.equal(1234);26 expect(mocker.options.mockDirectory).to.equal('./mocks/');27 expect(mocker.options.allowedDomains[0]).to.equal('*');28 expect(mocker.options.quiet).to.equal(true);29 expect(mocker.options.foo).to.equal('bar');30 });31 });32 describe('setConfigFile: ', () => {33 const mocker = apiMocker.createServer();34 beforeEach(() => {35 delete mocker.configFilePath;36 });37 after(() => {38 delete mocker.configFilePath;39 });40 it('should set a relative path correctly using node path resolver', () => {41 assert.equal(42 path.resolve('../config.json'),43 mocker.setConfigFile('../config.json').configFilePath44 );45 });46 it('should set an absolute path correctly', () => {47 const absolutePath = path.normalize('/foo/bar/config.json');48 expect(mocker.setConfigFile(absolutePath).configFilePath).to.equal(absolutePath);49 });50 it('sets no path, if none is passed in', () => {51 expect(mocker.setConfigFile().configFilePath).to.equal(undefined);52 });53 });54 describe('loadConfigFile: ', () => {55 // Note:56 // Starting mock config paths with a / or ~ to avoid57 // the absoulute path resolution within setConfig which will not match58 // the path mocked by mock-require.59 const mockConfig = {60 mockDirectory: '~/foo/bar/samplemocks/',61 quiet: true,62 port: '7879',63 latency: 50,64 logRequestHeaders: true,65 allowedDomains: ['abc'],66 allowedHeaders: ['my-custom1', 'my-custom2'],67 webServices: {68 first: {69 verbs: ['get', 'post'],70 responses: {71 get: {72 mockFile: 'king.json'73 },74 post: {75 mockFile: 'ace.json'76 }77 },78 alternatePaths: ['1st']79 },80 'nested/ace': {81 mockFile: 'ace.json',82 verbs: ['get']83 },84 'var/:id': {85 mockFile: 'xml/queen.xml',86 verbs: ['get']87 },88 queen: {89 mockFile: 'xml/queen.xml',90 verbs: ['all']91 }92 }93 };94 afterEach(() => {95 mockRequire.stopAll();96 });97 it('sets options from new format mock config file', () => {98 const mocker = apiMocker.createServer({ quiet: true });99 mockRequire('/mock-config.json', mockConfig);100 mocker.setConfigFile('/mock-config.json');101 mocker.loadConfigFile();102 expect(mocker.options.port).to.equal(mockConfig.port);103 expect(mocker.options.allowedDomains[0]).to.equal(mockConfig.allowedDomains[0]);104 expect(mocker.options.allowedHeaders[0]).to.equal('my-custom1');105 expect(mocker.options.allowedHeaders[1]).to.equal('my-custom2');106 expect(mocker.options.webServices.first).to.eql(mocker.options.webServices['1st']);107 delete mocker.options.webServices['1st'];108 expect(mocker.options.webServices).to.deep.equal(mockConfig.webServices);109 expect(mocker.options.quiet).to.equal(true);110 expect(mocker.options.latency).to.equal(mockConfig.latency);111 expect(mocker.options.logRequestHeaders).to.equal(mockConfig.logRequestHeaders);112 });113 it('combines values from defaults, options, and config file', () => {114 let mocker = apiMocker.createServer({ quiet: true, test: 'fun', port: 2323 });115 mockRequire('/partial-config', { port: 8765, latency: 99, logRequestHeaders: false });116 mocker = mocker.setConfigFile('/partial-config');117 mocker.loadConfigFile();118 // value from config file119 expect(mocker.options.port).to.equal(8765);120 expect(mocker.options.latency).to.equal(99);121 expect(mocker.options.logRequestHeaders).to.equal(false);122 // value from defaults123 expect(mocker.options.allowedDomains[0]).to.equal('*');124 expect(mocker.options.webServices).to.deep.equal(mocker.defaults.webServices);125 // value from options passed in to createServer:126 expect(mocker.options.test).to.equal('fun');127 });128 it('expands ~ in mockDirectory setting', () => {129 const mocker = apiMocker.createServer({ quiet: true });130 mockRequire('/mock-config.json', mockConfig);131 mocker.setConfigFile('/mock-config.json');132 mocker.loadConfigFile();133 expect(mocker.options.mockDirectory).to.equal(untildify(mockConfig.mockDirectory));134 });135 it('supports js config files that export a function', () => {136 const mocker = apiMocker.createServer({ quiet: true });137 const port = '1111';138 mockRequire('/partial-config', () => ({ port }));139 mocker.setConfigFile('/partial-config');140 mocker.loadConfigFile();141 expect(mocker.options.port).to.equal(port);142 });143 it('supports js config files that export an object', () => {144 const mocker = apiMocker.createServer({ quiet: true });145 const port = '2222';146 mockRequire('/partial-config', { port });147 mocker.setConfigFile('/partial-config');148 mocker.loadConfigFile();149 expect(mocker.options.port).to.equal(port);150 });151 it('should not allow requests that avoid pre flight by default', () => {152 const mocker = apiMocker.createServer({ quiet: true });153 expect(mocker.options.allowAvoidPreFlight).to.equal(false);154 });155 it('should allow requests that avoid pre flight if specified in config', () => {156 const mocker = apiMocker.createServer({ quiet: true });157 mockRequire('/partial-config', {158 allowAvoidPreFlight: true159 });160 mocker.setConfigFile('/partial-config');161 mocker.loadConfigFile();162 expect(mocker.options.allowAvoidPreFlight).to.equal(true);163 });164 });165 describe('setSwitchOptions: ', () => {166 let mocker;167 let svcOptions;168 let reqStub;169 beforeEach(() => {170 mocker = apiMocker.createServer({ quiet: true });171 svcOptions = { switch: 'productId', mockFile: 'base' };172 reqStub = {173 body: {},174 params: {},175 query: {},176 header: () => {}177 };178 });179 it('does not set mock file path if switch is not found in request', () => {180 mocker.setSwitchOptions(svcOptions, reqStub);181 expect(svcOptions.mockFile).to.equal('base');182 });183 it('sets correct mock file path if switch is found in query string', () => {184 reqStub.query = { productId: '123' };185 mocker.setSwitchOptions(svcOptions, reqStub);186 expect(svcOptions.mockFile).to.equal('productId123.base');187 });188 it('sets correct mock file path if switch is found in json body', () => {189 reqStub.body.productId = '678';190 mocker.setSwitchOptions(svcOptions, reqStub);191 expect(svcOptions.mockFile).to.equal('productId678.base');192 });193 it('sets correct mock file path if switch is found in route parameter', () => {194 reqStub.params = { productId: '123' };195 mocker.setSwitchOptions(svcOptions, reqStub);196 expect(svcOptions.mockFile).to.equal('productId123.base');197 });198 it('sets correct mock file path if switch is found in request header with matching case', () => {199 reqStub.header = () => '765';200 mocker.setSwitchOptions(svcOptions, reqStub);201 expect(svcOptions.mockFile).to.equal('productId765.base');202 });203 it('sets correct mock file path if switch is found in request header with different case', () => {204 reqStub.header = () => '765';205 svcOptions = { switch: 'PRodUCTID', mockFile: 'base' };206 mocker.setSwitchOptions(svcOptions, reqStub);207 expect(svcOptions.mockFile).to.equal('PRodUCTID765.base');208 });209 it('sets correct mock file path with switch and nested path', () => {210 reqStub.body.productId = '678';211 svcOptions.mockFile = 'path/to/base';212 mocker.setSwitchOptions(svcOptions, reqStub);213 expect(svcOptions.mockFile).to.equal('path/to/productId678.base');214 });215 it('sets correct mock file path with switch value containing special character', () => {216 reqStub.body.productId = 'abc/123';217 mocker.setSwitchOptions(svcOptions, reqStub);218 expect(svcOptions.mockFile).to.equal('productIdabc%2F123.base');219 });220 it('sets correct mock file path with two switch values', () => {221 svcOptions.switch = ['productId', 'color'];222 reqStub.body.productId = '345';223 reqStub.body.color = 'red';224 mocker.setSwitchOptions(svcOptions, reqStub);225 expect(svcOptions.mockFile).to.equal('productId345colorred.base');226 });227 it('sets correct http status based on matching switch value', () => {228 svcOptions.switch = 'password';229 svcOptions.switchResponses = {230 passwordgood: { httpStatus: 200 }231 };232 reqStub.body.password = 'good';233 mocker.setSwitchOptions(svcOptions, reqStub);234 expect(svcOptions.httpStatus).to.equal(200);235 });236 it('sets correct mock file path when switch matches and switchResponse contains a mockFile', () => {237 reqStub.body.productId = '678';238 svcOptions.switchResponses = {239 productId678: { mockFile: 'specialFileName' }240 };241 mocker.setSwitchOptions(svcOptions, reqStub);242 expect(svcOptions.mockFile).to.equal('specialFileName');243 });244 it('sets correct http status when switch value does not match', () => {245 svcOptions.switch = 'password';246 svcOptions.httpStatus = 401;247 svcOptions.switchResponses = {248 passwordgood: { httpStatus: 200 }249 };250 reqStub.body.password = 'bad';251 mocker.setSwitchOptions(svcOptions, reqStub);252 expect(svcOptions.httpStatus).to.equal(401);253 });254 it('sets correct http status when two switches match', () => {255 svcOptions.switch = ['userId', 'password'];256 svcOptions.httpStatus = 401;257 svcOptions.switchResponses = {258 userId1234passwordgood: { httpStatus: 200 }259 };260 reqStub.body.password = 'good';261 reqStub.body.userId = '1234';262 mocker.setSwitchOptions(svcOptions, reqStub);263 expect(svcOptions.httpStatus).to.equal(200);264 });265 it('sets correct mock file path when switch uses JsonPath and switch matches', () => {266 svcOptions.switch = '$.car.engine.part';267 svcOptions.switchResponses = {268 '$.car.engine.partTiming%20Belt': { mockFile: 'product456' }269 };270 reqStub.body = {271 car: {272 engine: {273 part: 'Timing Belt'274 }275 }276 };277 mocker.setSwitchOptions(svcOptions, reqStub);278 expect(svcOptions.mockFile).to.equal('product456');279 });280 it('sets correct mock file path when switch uses JsonPath and switch value does not match', () => {281 svcOptions.switch = '$.car.engine.part';282 svcOptions.switchResponses = {283 '$.car.engine.partTiming%20Belt': { mockFile: 'product456' }284 };285 reqStub.body = {286 car: {287 wheel: {}288 }289 };290 mocker.setSwitchOptions(svcOptions, reqStub);291 expect(svcOptions.mockFile).to.equal('base');292 });293 it('sets correct mock file path when switch uses JsonPath as a switch object and switch matches', () => {294 svcOptions.switch = {295 type: 'jsonpath',296 switch: '$.car.engine.part'297 };298 svcOptions.switchResponses = {299 '$.car.engine.partTiming%20Belt': { mockFile: 'product456' }300 };301 reqStub.body = {302 car: {303 engine: {304 part: 'Timing Belt'305 }306 }307 };308 mocker.setSwitchOptions(svcOptions, reqStub);309 expect(svcOptions.mockFile).to.equal('product456');310 });311 it('sets correct mock file path when switch uses JsonPath and switch value does not match', () => {312 svcOptions.switch = {313 type: 'jsonpath',314 switch: '$.car.engine.part'315 };316 svcOptions.switchResponses = {317 '$.car.engine.partTiming%20Belt': { mockFile: 'product456' }318 };319 reqStub.body = {320 car: {321 wheel: {}322 }323 };324 mocker.setSwitchOptions(svcOptions, reqStub);325 expect(svcOptions.mockFile).to.equal('base');326 });327 it('sets the correct mock file path when switch uses RegExp and switch matches', () => {328 svcOptions.switch = '/"carEnginePart([^"]*)"/';329 svcOptions.switchResponses = {330 '/"carEnginePart([^"]*)"/Belt': { mockFile: 'product456' }331 };332 reqStub.body = '"carPartWheel": wheel,\n"carEnginePartBelt": belt';333 mocker.setSwitchOptions(svcOptions, reqStub);334 expect(svcOptions.mockFile).to.equal('product456');335 });336 it('sets the correct mock file path when switch uses RegExp and switch value does not match', () => {337 svcOptions.switch = '/"carEnginePart([^"]*)"/';338 svcOptions.switchResponses = {339 Belt: { mockFile: 'product456' }340 };341 reqStub.body = '"carPartWheel": wheel';342 mocker.setSwitchOptions(svcOptions, reqStub);343 expect(svcOptions.mockFile).to.equal('base');344 });345 it('sets the correct mock file path when switch uses RegExp in a switch object and switch matches', () => {346 svcOptions.switch = {347 type: 'regexp',348 switch: '/"carEnginePart([^"]*)"/',349 key: 'carenginepart'350 };351 svcOptions.switchResponses = {352 carenginepartBelt: { mockFile: 'product456' }353 };354 reqStub.body = '"carPartWheel": wheel,\n"carEnginePartBelt": belt';355 mocker.setSwitchOptions(svcOptions, reqStub);356 expect(svcOptions.mockFile).to.equal('product456');357 });358 it('sets the correct mock file path when switch uses RegExp in a switch object and switch does not match', () => {359 svcOptions.switch = {360 type: 'regexp',361 switch: '/"carEnginePart([^"]*)"/',362 key: 'carenginepart'363 };364 svcOptions.switchResponses = {365 carenginepartBelt: { mockFile: 'product456' }366 };367 reqStub.body = '"carPartWheel": wheel';368 mocker.setSwitchOptions(svcOptions, reqStub);369 expect(svcOptions.mockFile).to.equal('base');370 });371 });372 describe('setRoute:', () => {373 const am = apiMocker.createServer();374 it('sets no default http status code', () => {375 const options = {376 verb: 'get',377 latency: 0,378 serviceUrl: 'foo.com',379 mockFile: 'file.json'380 };381 am.setRoute(options);382 expect(options.httpStatus).to.equal(undefined);383 });384 });385 describe('setRoutes:', () => {386 const am = apiMocker.createServer();387 let setRouteMock;388 beforeEach(() => {389 setRouteMock = sinon.mock(am, 'setRoute');390 });391 afterEach(() => {392 setRouteMock.restore();393 });394 it('calls setRoute with a simple service definition', () => {395 const webServices = {396 first: {397 mockFile: 'king.json',398 latency: 20,399 verbs: ['get', 'post']400 }401 };402 am.options.webServices = webServices;403 setRouteMock.expects('setRoute').withExactArgs({404 latency: 20,405 mockFile: 'king.json',406 serviceUrl: 'first',407 verb: 'get'408 });409 setRouteMock.expects('setRoute').withExactArgs({410 latency: 20,411 mockFile: 'king.json',412 serviceUrl: 'first',413 verb: 'post'414 });415 am.setRoutes(webServices);416 setRouteMock.verify();417 });418 it('calls setRoute with complex service definition', () => {419 const webServices = {420 second: {421 verbs: ['delete', 'post'],422 responses: {423 delete: { httpStatus: 204 },424 post: {425 contentType: 'foobar',426 mockFile: 'king.json'427 }428 }429 }430 };431 am.options.webServices = webServices;432 setRouteMock.expects('setRoute').withExactArgs({433 httpStatus: 204,434 latency: 0,435 serviceUrl: 'second',436 verb: 'delete'437 });438 setRouteMock.expects('setRoute').withExactArgs({439 latency: 0,440 serviceUrl: 'second',441 verb: 'post',442 contentType: 'foobar',443 mockFile: 'king.json'444 });445 am.setRoutes(webServices);446 setRouteMock.verify();447 });448 });...

Full Screen

Full Screen

mockers.ts

Source:mockers.ts Github

copy

Full Screen

1import { Dispatch } from 'react';2import { createMocker, deleteMocker, listMockers, updateMocker } from '../api/mockers';3import { IMocker } from "../interfaces/Mocker";4import { notifier } from '../utils/notify';5enum MockersActionType {6 RefreshList,7 UpdateMocker,8 AddMocker,9 RemoveMocker,10}11type Action = {12 type: MockersActionType.RefreshList;13 payload: IMocker[];14} | {15 type: MockersActionType.UpdateMocker;16 payload: IMocker;17} | {18 type: MockersActionType.AddMocker;19 payload: IMocker;20} | {21 type: MockersActionType.RemoveMocker;22 payload: { id: number }23}24export type MockerDispatcher = Dispatch<Action>25// reducer create method26export function mockersReducerInit(): IMocker[] {27 return []28}29export function mockersReducer(origin: IMocker[], action: Action): IMocker[] {30 switch (action.type) {31 case MockersActionType.RefreshList:32 if (!Array.isArray(action.payload)) {33 return [];34 }35 return [...action.payload];36 case MockersActionType.UpdateMocker:37 return origin.map((m) => m.id === action.payload.id ? action.payload : m);38 case MockersActionType.AddMocker:39 return [action.payload, ...origin];40 case MockersActionType.RemoveMocker:41 return origin.filter((m) => m.id !== action.payload.id);42 default:43 throw new Error();44 }45}46// operator methods47export function genRefreshMockersAction(dispatch: MockerDispatcher): () => Promise<void> {48 return async () => {49 const res = await listMockers();50 dispatch({51 type: MockersActionType.RefreshList,52 payload: res.mockers53 });54 };55}56export function genToggleMockersAction(dispatch: MockerDispatcher): (m: IMocker) => Promise<void> {57 return async (m: IMocker) => {58 dispatch({59 type: MockersActionType.UpdateMocker,60 payload: { ...m, status: 'updating' }61 });62 const nextStatus = m.status === 'active' ? 'inactive' : 'active';63 const res = await updateMocker({ ...m, status: nextStatus });64 65 if (res.mocker) {66 // TODO: check envoy status67 notifier.success(68 `Successfully update mocker status to ${nextStatus}.`,69 'Please wait few second for the backend service to update the Envoy proxy.'70 )71 dispatch({72 type: MockersActionType.UpdateMocker,73 payload: { ...res.mocker }74 });75 } else {76 dispatch({77 type: MockersActionType.UpdateMocker,78 payload: { ...m }79 });80 }81 }82}83export function genUpdateMockersAction(dispatch: MockerDispatcher): (m: IMocker) => Promise<boolean> {84 return async (m: IMocker) => {85 dispatch({86 type: MockersActionType.UpdateMocker,87 payload: { ...m, status: 'updating' }88 });89 const res = await updateMocker({ ...m });90 if (!res.mocker) {91 dispatch({92 type: MockersActionType.UpdateMocker,93 payload: { ...m }94 });95 return false96 }97 // TODO: check envoy status98 notifier.success(99 `Successfully update mocker.`,100 'Please wait few second for the backend service to update the Envoy proxy.'101 )102 dispatch({103 type: MockersActionType.UpdateMocker,104 payload: { ...res.mocker }105 });106 return true;107 }108}109export function genCreateMockersAction(dispatch: MockerDispatcher): (m: IMocker) => Promise<boolean> {110 return async (m: IMocker) => {111 const res = await createMocker({ ...m });112 if (!res.mocker) {113 return false114 }115 // TODO: check envoy status116 notifier.success(117 `Successfully create a new mocker.`,118 'Please wait few second for the backend service to update the Envoy proxy.'119 )120 dispatch({121 type: MockersActionType.AddMocker,122 payload: { ...res.mocker }123 });124 return true;125 }126}127export function genDeleteMockersAction(dispatch: MockerDispatcher): (mockerId: number) => Promise<boolean> {128 return async (mockerId: number) => {129 const success = await deleteMocker(mockerId);130 // TODO: check envoy status131 if (!success) {132 return false;133 }134 notifier.success(135 `Successfully create a new mocker.`,136 'Please wait few second for the backend service to update the Envoy proxy.'137 );138 dispatch({ type: MockersActionType.RemoveMocker, payload: { id: mockerId } });139 return true;140 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var mocker = require('apimocker');2mocker.setConfigFile('config.json');3mocker.run();4{5}6{7 {8 }9}10{11 "headers": {12 },13 "body": {14 }15}

Full Screen

Using AI Code Generation

copy

Full Screen

1const mocker = require('apimocker');2mocker.setConfigFile('./config.json');3mocker.run();4{5 {6 "request": {7 },8 "response": {9 }10 }11}12 {13 },14 {15 }16const mocker = require('apimocker');17mocker.setConfigFile('./config.json');18mocker.run();19{20 {21 "request": {22 },23 "response": {24 }25 }26}27 {28 },29 {30 }31const mocker = require('apimocker');32mocker.setConfigFile('./config.json');33mocker.run();34{35 {36 "request": {37 },38 "response": {39 }40 }41}42 {43 },44 {45 }

Full Screen

Using AI Code Generation

copy

Full Screen

1var mocker = require('apimocker');2mocker.setConfigFile('mocker-config.json');3mocker.listen();4{5}6{7 "request": {8 },9 "response": {10 "headers": {11 },12 "body": {13 }14 }15}16var mocker = require('apimocker');17mocker.setConfigFile('mocker-config.json');18mocker.listen();19{20}21{22 "request": {23 },24 "response": {25 "headers": {26 },27 "body": {28 }29 }30}31var mocker = require('apimocker');32mocker.setConfigFile('mocker-config.json');33mocker.listen();34{35}36{37 "request": {

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run apimocker automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful