Test and stub params in POST request - javascript

Guys how can I stub params in POST request, for example here a part of function
gridCalculator : function(req,res){
// calculation logic
var options=[];
options.dateFirstLicensed = req.param('DateFirstLicensed');
options.dateFirstInsured = req.param('DateFirstInsured');
options.claimList = req.param('ClaimList');
options.suspenList = req.param('SuspenList');
...etc
if I did this
it('grid Calculate', function (done) {
var req = {
'DateFirstLicensed' : "01-01-2010",
'DateFirstInsured': "01-01-2011",
'ClaimList': ['05-03-2012'],
'SuspenList': [{'StartDate':'05-03-2012','EndDate':'05-05-2012' }]
};
gridCalculator.gridCalculator(req,function (err, result) {
result.should.exist;
done();
});
});
I get error because I'm simply passing an object not POST request
TypeError: req.param is not a function

Two options come to mind (there are probably a lot more):
Option 1: Define the param function yourself:
it('grid Calculate', function (done) {
var params = function(param) {
switch (param) {
case 'DateFirstLicensed':
return "01-01-2010";
case 'DateFirstInsured':
... //do the same for all params
}
};
var req = {
param: params
};
gridCalculator.gridCalculator(req,function (err, result) {
result.should.exist;
done();
});
});
Option 2: Use tools like supertest to create calls to your server's endpoint.

The problem is that you don't stub the function that is used in your gridCalculator method in your test.
It should look like this:
it('grid Calculate', function (done) {
var testParams = {
'DateFirstLicensed' : "01-01-2010",
'DateFirstInsured': "01-01-2011",
'ClaimList': ['05-03-2012'],
'SuspenList': [{'StartDate':'05-03-2012','EndDate':'05-05-2012'}]
};
var req = {
param: function (paramName) {
return testParams[paramName];
}
};
gridCalculator.gridCalculator(req,function (err, result) {
result.should.exist;
done();
});
});

Related

Unexpected Parsing Error On AWS Lambda JS

I think this is a syntax error but I'm having trouble finding documentation. I keep getting 'Parsing Error: Unexpected Token {". It says its to do with the 'YesIntent', but won't give specifics. I'm new to JS, but I can't see what could be the problem. Every '{' has a matching '}'.
Any insights would be appreciated. Thank you.
const Alexa = require("alexa-sdk");
const appId = ''; //'';
exports.handler = function(event, context, callback) {
const alexa = Alexa.handler(event, context);
alexa.appId = appId;
alexa.registerHandlers(handlers);
alexa.execute();
};
const handlers = {
'LaunchRequest': function() {
this.emit('YesIntent');
},
'YesIntent': function() {
getData(callback(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
}),
};
function getData() {
var ddb = new AWS.DynamoDB.DocumentClient({
region: 'us-west-1'
});
var params = {
TableName: 'WallyFlow_StartTime',
Key: 'TimeStamp',
};
ddb.get(params, function(err, data) {
if (err) {
callback(err, null);
} else {
title = data.Item.title;
}
});
}
Sorry, in this style you need more braces :) Updated to:
'YesIntent': function () {
getData( {
callback(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
}})
}};
I suspect it should be something like this. callback should be the name of the parameter to the getData() function, not something you call in the argument. The argument to getData() should be a function.
And getData() should call the callback function in the non-error case as well as the error case.
You also need an extra } to end the handlers object, and the end of the statement that calls getData() should be ;, not ,.
const handlers = {
'LaunchRequest': function() {
this.emit('YesIntent');
},
'YesIntent': function() {
getData(function(title) {
this.response.speak('Here are your data ' + title);
this.emit(':responseReady');
});
}
};
function getData(callback) {
var ddb = new AWS.DynamoDB.DocumentClient({
region: 'us-west-1'
});
var params = {
TableName: 'WallyFlow_StartTime',
Key: 'TimeStamp',
};
ddb.get(params, function(err, data) {
if (err) {
callback(err, null);
} else {
title = data.Item.title;
callback(title);
}
});
}

How to force a function to execute first in Jasmine test?

I have a route in Node that gets an auth key. I want to use this auth key in all my jasmine tests as a parameter in the URL request. I want SetUp function to run, set a global var, then allow me to use this variable in all the rest of the test cases.
SetUp Function
var global_key = request({
uri : 'http://localhost:3000/grabToken',
method : 'GET'
},
function (err, body, res) {
if (err) { console.log(err);}
else {
return body['auth_key'];
}
});
Test Suite
function testCases() {
describe(TEST_SUITE, function() {
describe("GET /retrieveSecret/VALID_UUID", function() {
it('Requests the secret - Successful response', function(done) {
// ...
}
}
}
}
You could use asynchronous version of beforeAll function:
describe(TEST_SUITE, function() {
let key;
beforeAll(function (done) {
const params = { uri: 'http://localhost:3000/grabToken', method: 'GET' };
request(params, function (err, body, res) {
if (err) {
console.log(err);
done.fail();
} else {
key = body['auth_key'];
done();
}
});
})
describe("GET /retrieveSecret/VALID_UUID", function() {
it('Requests the secret - Successful response', function(done) {
// `key` is available here
}
});
})

Collect data and make response SailsJS

I just started to learn SailsJS and I ran into the following problem:
In the UserController I've got following method:
/**
* `UserController.create()`
*/
create: function (req, res) {
var d = {};
c = {'fullname' : 'Sergiu Pirlici'}
User.findOne(c, function(err, found) {
d.found = found;
});
User.destroy(c, function(err){
d.destroyed = !err;
});
if(req.method == 'GET') {
res.view(d);
}
else if(req.method == 'POST') {
var dat = req.params.all();
User.create(dat, function(err, created){
d.err = err;
if(!err) {
d.created = created;
}
});
}
d.foo = true;
res.json(d);
},
In variable d I want to collect data and pass it to view or send as JSON.
But in the value of d is {'foo': true}.
I understant that this happens because precedent actions are asynchronous.
Is there an another way to collect data and pass it to response?
How can I do this?
you can use a service http://sailsjs.org/#/documentation/concepts/Services
then pass a callback parameter.
so on the UserService.js
module.exports = {
FindOne: function(cb){
User.findOne(c, function(err, found) {
cb(found);
});
}
};
then on your controller:
UserService.FindOne(function(found){
//other logic
var d = { result : found } ;
res.json(d);
});

node.js and async module error

I am getting an undefined variable in my code and not sure what the error in my code is:
I get client as undefined when I call getClient...
I have a soap client creation singleton and I have:
var mySingleton = (function() {
var soap = require('soap');
var async = require('async');
var instance;
var client;
function init() {
var url = "http://172.31.19.39/MgmtServer.wsdl";
var endPoint = "https://172.31.19.39:9088";
var options = {};
options.endpoint = endPoint;
async.series([
function(callback) {
soap.createClient(url, options, function (err, result){
console.log('Client is ready');
client = result;
client.setSecurity(new soap.BasicAuthSecurity('admin-priv', 'password'));
callback();
});
}
],
function(err) {
if (err)
return next(err);
});
return {
getClient : function() {
console.log("I will give you the client");
**return client;**
},
publicProperty : "I am also public",
};
};
return {
getInstance : function() {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
module.exports = mySingleton;
so my consumer is :
var soapC = mySingleton.getInstance();
var mySoapClient = soapC.getClient();
I get mySingleton.client is undefined.
Why?
Sure there are better solutions than this one, but it shows you that it can be implemented easier (without async, without singleton):
var soap = require('soap');
var client;
var url = "http://172.31.19.39/MgmtServer.wsdl";
var options = {
endpoint: "https://172.31.19.39:9088"
};
module.exports = {
getClient: function (callback) {
if (client) {
callback(null, client);
return;
}
soap.createClient(url, options, function (err, result) {
if (err) {
callback(err);
return;
}
console.log('Client is ready');
client = result;
client.setSecurity(new soap.BasicAuthSecurity('admin-priv', 'password'));
callback(null, client);
});
},
publicProperty: "I am also public"
};
And when using the client:
// using the client
var mySoapServer = require('./path/to/above/code.js');
mySoapServer.getClient(function (err, client) {
if (err) { /* to error handling and return */ }
client.someRequestMethod(myEnvelope, function (err, response) {
// ...
});
});
There might be a problem when your Soap-Clients gets into trouble (there is no logic to reconnect in case of error). For this you could have a look at the source code of Redis-Client, MySQL-Client, MongoDB-Client, ...
Edit
Some comments on the different aproaches:
The Singleton-pattern is not needed here. Node will execute this JS file only once and further requires get only a reference to the exports. There is no need to create an IIFE scope - the variables won't be visible outside, only the exports.
Programming in Node.js is (besides some special cases) an all-async way. If not done consequently, it just doesn't work or fails/succeeds only if you have good/bad luck.
Error handling looks very much like a lot of boilerplate, but it's necessary in most cases.

This scope lost with inheritance

Here is the example code, two files and "classes".
CRUD class with defined methods, the problem occurs with this.modelName, as I set the routes the this context changes with this code:
The question is how, to get the same scope under the CRUD where you have defined the modelName ?
server.get('/users/:id', UserRoutes.find);
Code:
var db = require('../models');
function CRUD(modelName) {
this.modelName = modelName;
this.db = db;
}
CRUD.prototype = {
ping: function (req, res, next) {
res.json(200, { works: 1 });
},
list: function (req, res, next) {
// FAILS BECAUSE the modelName is undefined
console.log(this);
db[this.modelName].findAll()
.success(function (object) {
res.json(200, object);
})
.fail(function (error) {
res.json(500, { msg: error });
});
}
};
module.exports = CRUD;
UserRoutes class:
var CRUD = require('../utils/CRUD'),
util = require('util');
var UserModel = function() {
UserModel.super_.apply(this, arguments);
};
util.inherits(UserModel, CRUD);
var userRoutes = new UserModel('User');
module.exports = userRoutes;
I assume that you are using userRoutes.list as a handler somewhere else, i.e. the context changes. In that case this should be a simple solution:
function CRUD(modelName) {
this.modelName = modelName;
this.db = db;
this.list = CRUD.prototype.list.bind(this);
}
Note that you won't be able to access "the other this" with that solution (this will be permamently bound to CRUD instance, no matter how .list is called).
The other option is to turn list into a function generator (which is pretty much the same what .bind does, except you can still use this from the other context):
CRUD.prototype = {
// some code
list: function() {
var that = this;
return function (req, res, next) {
console.log(that);
db[that.modelName].findAll()
.success(function (object) {
res.json(200, object);
})
.fail(function (error) {
res.json(500, { msg: error });
});
}
}
};
and then use userRoutes.list() as a handler.
This sort of thing is generally fixed by stowing the right this into _this. In your list function this is the function object, which doesn't have a modelName object.
var _this;
function CRUD(modelName) {
this.modelName = modelName;
this.db = db;
_this = this // <---------------
}
....
// call the _this in the outer scope
db[_this.modelName]

Categories