Is it possible to reuse a nock object? - node.js

I am using nock for testing HTTP Endpoints and I don't want to define the headers and baseURL multiple times.
Is it problematic to do something like this?
const serviceNock = nock('https://my-service.local')
.matchHeader('Api-Key', 'my-api-key')
.matchHeader('Content-Type', 'application/json')
Use serviceNock in test1
const serviceNock1 = serviceNock
.patch('/resources')
.reply(200)
Use serviceNock in test2
const serviceNock2 = serviceNock
.patch('/resources')
.reply(500)

No idea about the nock (never used it and don't know if chaining creates new object or just modify the existing one), but why not to do something like next:
const getBaseNockService = () => nock('https://my-service.local')
.matchHeader('Api-Key', 'my-api-key')
.matchHeader('Content-Type', 'application/json')
const serviceNock1 = getBaseNockService()
.patch('/resources')
.reply(200)
const serviceNock2 = getBaseNockService()
.patch('/resources')
.reply(500)
Here we define factory function getBaseNockService and get full functionality you requested

Related

How to check the content of Koa's ctx.query?

For a Koa-based API server, I want to check what parameters the URL query contains.
My setup looks as simple as this:
const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
router = new Router()
router.get('/', ctx => {
console.log(ctx.query)
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000)
It seems that ctx.query has a structure like an object but doesn't work as one.
Methods like ctx.query.hasOwnProperty() or ctx.query.toString() result in an error saying that it is not a function.
Though, Object.keys(ctx.query) gives an array of the keys—which is confusing to me because it apparently is an object and should have above methods.
What is ctx.query exactly? How can I make the failing methods from above working?
ctx.query is the return from Node.js' querystring.parse() method. From the documentation:
The object returned by the querystring.parse() method does not
prototypically inherit from the JavaScript Object. This means that
typical Object methods such as obj.toString(), obj.hasOwnProperty(),
and others are not defined and will not work.
You can check Koa's request implementation.

How to extract data using async and await function in node js?

I tried redis cache implement in node js using mongodb.I set the data in cache.but i cant get the data in cache.how to solve this issue.
cache.js
async function Get_Value(){
let response = await client.get('products')
console.log("_______________")
console.log(response)
}
I got output : true
Excepted output: json data
how to get json data using cache get method
Redis does not provide a full async await adapter for node.js so usually as a workaround people are promisifying the lib.
const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
async function getValue(){
let response = await getAsync("products");
}
An other approach to promisify the entire redis library you can use:
const redis = require('redis');
bluebird.promisifyAll(redis);
Now you will be able also to use the methods using async/await.

Does express-validator sanitize.escape() the same as DOMPurify?

Want to take measures to protect myself against XSS.
Right now, I have:
sanitizeQuery('searchQuery').escape().trim()
Is that adequate protection? Or would you recommend adding something like DOM Purify (running on the node end) as well?
Short answer: No
Long answer: your approach will get you most part of the way but and I quote:
HTML entity encoding doesn't work if you're putting untrusted data inside a tag anywhere, or an event handler attribute like onmouseover, or inside CSS, or in a URL.
You should be using something like DOMPurify
Source XSS Prevention Cheat Sheet
You can use dompurify with express-validator.
const { param, validationResult } = require('express-validator')
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const xssSenitize = (value) => {
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
return DOMPurify.sanitize(value, { ALLOWED_TAGS: [] });
}
query(['id']).customSanitizer(xssSenitize)

how to mock twilio in unit tests with either sinon/proxyquire or dependency inejction in node.js

Say I want to test a a user login controller that sends login codes via SMS with Twilio. How should I set up the test so that I can mock Twilio and see what codes it's sending back. My approach was to proxyquire the twilio client object and spy on it with sinon, but I don't think I'm getting it quite right.
controller user.js
var smsClient = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
module.exports = {
checkCode: function(phone){
var code = getNewCode();
smsClient.sms.messages.create({
from: config.get('twilio_phone_number'),
to: phone,
body: 'Your code :' + code
}, callback);
}
}
test file
var twilioMock = //what goes here??
var smsSpy = sinon.spy(twilioMock.sms.messages, 'create');
var User = proxyquire('../models/user', { 'mongoose': mongooseMock, 'smsClient': twilioMock });
... some describe and it statements ...
twilioMock.sms.messages.should.have.been.calledOnce() //this is where I don't know what I should be checking
// or is this the right way?
//smsSpy.should.have.been.calledOnce()
I am answering this very late but this might help someone.
I haven't used proxywire but it seems very similar to rewire (just by looking at your code). You should try the following:
var twilioMock = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
I am more used to rewire. npm i rewire --save-dev. Using rewire you may try the following: (concept remains the same)
In your test:
var rewire = require('rewire');
var twilioMock = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
var userController = rewire('./path_to_user.js') // notice use of rewire
beforeEach(function(){
this.smsClient = twilioMock; // `this` is available within your tests
userController.__set__('smsClient', this.smsClient);
});
it('should something', sinon.test(function(){
var smsSpy = this.spy(this.smsClient.sms.messages, 'create');
}));

Updating the prototype of ServerRequest in an express/node configuration

I'd like to augment the prototype of the request object in expressjs, but it isn't clear where this request is defined? I think it is http.ServerRequest, but I can't find that definition either.
What's the right way to do the following...
http.ServerRequest.prototype.redirect = function(path) { }
Express itself adds it's utility methods to http.IncomingMessage.prototype, using this pattern in 2.*:
var http = require('http'),
req = http.IncomingMessage.prototype;
req.foo = function(bar) {
// Do cool stuff
};
And this pattern in 3.*:
var http = require('http');
var req = exports = module.exports = {
__proto__: http.IncomingMessage.prototype
};
It's wise to be careful with monkey patching though, as Vadim Baryshev warns in his answer.
Look at Connect framework and his middleware libs. Every middleware extends request and response objects after their creation. Changing prototype of core objects not the best way because this can lead to unpredictable behavior in other modules.

Resources