express, mocha testing always returns 404 - javascript

My express POST route is:
app.post("/addPost", function(req, res) {
let newComment = { post: req.body.createP, comment: req.body.createC };
myDB.push(newComment);
res.render("index.ejs", { posts: myDB });
});
And my mocha test
describe("POST /", function() {
it("it ", function(done) {
supertest(myApp.app)
.post("/")
.expect(200)
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});
Manually, the POST route works fine, but the mocha test always returns 404 instead of 200. Also, the mocha test for GET routes does work. Any ideas whats causing this?
Plus, how would one test html form data being sent via a POST request. Thanks in advance!

Related

Using chai to mock http requests

I'm testing a nodejs app written using express. For the unit testing I'm using chai and sinon. I have the following route in my API that I would like to test.
In my test, I'm simulating the get request with the following code:
chai.request(app)
.get('/downloads')
.send({ wmauth: {
_identity: {
cn: "username",
}
} })
.end((err, res) => {
res.status.should.be.equal(200);
res.body.should.be.a('object');
res.body.should.have.property('Items', []);
AWS.restore('DynamoDB.DocumentClient');
done();
However, I'm always getting the error "Cannot read property '_identity' of undefined". Because the object "wmauth" is not sent in the request, so it is undefined. I have tried to use the send method to try to include it in the request, but no luck. I guess I need to mock it somehow and send it into the request but have no idea how to do it. Could someone help me with this?
Below the method to test:
app.get('/downloads', async (req, res) => {
const created_by_cn = req.wmauth['_identity'].cn;
if(!created_by_cn) {
return res.status(400).json({
error: 'Mandatory parameters: created_by_cn',
});
}
try {
const data = await downloadService.getDownloads(created_by_cn);
return res.status(200).json(data);
}
catch(error){
res.status(500).json({error: error.message});
}
});
THanks
I guess you forgot to use req.body as in:
const created_by_cn = req.body.wmauth['_identity'].cn;
Hope can solve your issue
Since chai-http use superagent, so according to its doc, you need to use query() in order to pass query parameter in get request:
chai.request(app)
.get('/downloads')
.query({ wmauth: {_identity: {cn: "username"}}})
.end((err, res) => { ... });
Then in the express route you can find the parameters in req.query:
app.get('/downloads', function (req, res) {
const created_by_cn = req.query.wmauth._identity.cn;
...
})

Sending a POST request with chai sends an empty body?

I have the following setup right now
test.js
var user = {
username: 'test_user',
email: 'test#test.me',
password: 'you shall not pass',
address: 'No where street'
};
chai.request(app)
.post('/api/v1/users')
.send(user);
I'm handling the post request in my routes/user.js
router.post('/', function(req, res, next) {
console.log('body: ' + req.body);
queries.insertUser(req.body)
.then(function(id) {
return queries.getSingleUser(id);
})
.then(function(user) {
res.status(200).json(user);
})
.catch(function(err) {
next(err);
});
});
req.body ends up being undefined. Any clue as to what might be going wrong?
The code is live at https://ide.c9.io/burtonium/node-from-scratch if anybody wants to have a look.
req.body being undefined is generally caused by either not using the body-parser middleware in Express, or declaring it incorrectly (for instance, after the route that wants to access req.body).
Assuming that Chai sends JSON, add this to your Express app:
app.use(require('body-parser').json());
(before you declare the routers)

404 Error with 'get' fetch request from locally hosted server

I am building a simple blog using the principles I learned here (CRUD app with Express and MongoDB). In order to edit previously published posts, I want to populate a text field with the contents of a blog post whose title is selected from a drop-down menu. That way I can easily make my changes and submit them.
I have written a basic 'put' fetch request that does absolutely nothing except report an error if something goes wrong:
fetch('articles', {method: 'put'})
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
Nothing goes wrong here, so console.log(data) is executed:
However, when I change 'put' to 'get' (and make no other changes), I get a 404 error:
How can it be that the 'get' fetch request causes a 404 error, but the 'put' request doesn't? I am hosting this app locally, so I'm running it from localhost:3000. The 'get', 'post', and 'put' operations in my server code look like this:
app.get('/', function (req, res) {
db.collection('articles').find().toArray(function (err, result) {
if (err) return console.log(err);
res.render('index.ejs', {articles: result});
});
});
app.post('/articles', function (req, res) {
db.collection('articles').save(req.body, function (err, result) {
if (err) return console.log(err);
console.log('saved to database');
res.redirect('/');
});
});
app.put('/articles', function (req, res) {
db.collection('articles')
.findOneAndUpdate({title: 'test title'}, {
$set: {
title: req.body.title,
body: req.body.body
}
}, {
sort: {_id: -1},
upsert: true
}, function (err, result) {
if (err) return res.send(err);
res.send(result);
});
});
I would like to eliminate this 404 error so I can proceed with the ultimate reason I'm using the 'get' request: to populate a text field with the contents of a previously published blog entry. After I've made my edits, I plan to use the 'put' request to finalize the changes in MongoDB.
Please let me know whether you need any additional information. Your advice is much appreciated!
You do not have a GET /articles route; you do have a GET / route, however.
If you want GET /articles to work, you should change the first argument to app.get to '/articles'.

Mocha test cases throwing Error: expected 200 "OK", got 403 "Forbidden"

I am using mochajs for my mean applications server side test cases.The test cases are showing an error, Error: expected 200 "OK", got 403 "Forbidden".
I tried using console logs inside the functions that I am trying to test, but they never get executed. I am unable to find out the issue. Can someone help me with this.
My controller
exports.signin = function(req, res) {
req.body.username = new Buffer(req.body.username, base64').toString('ascii');
User.findOne({
username: req.body.username.toLowerCase()
}, function(err, user) {
if (err) {
//do something
} else if (!user) {
//do something
} else {
//do something
}
});
};
My test case
it('should be able to signin if the credentials are valid', function(done) {
var obj = {
username: new Buffer('demo').toString('base64'),
password: new Buffer('demouser').toString('base64')
};
agent.post('/auth/signin')
.send(obj)
.expect(200)
.end(function(signinErr, res) {
if (signinErr){
console.log(signinErr);
done(signinErr);
}
else{
var temp = res.body;
console.log(temp);
done();
}
});
});
And my route
app.route('/auth/signin').post(users.signin);
I was facing the same issue. I found out that we were forcing SSL in our application using the middleware express-force-ssl by app.use(force-ssl). We used a flag to control this behavior. When I made that false, the test cases ran fine.
So if you are not controlling it with the flag. Try removing that module and running your test cases.

NodeJs Server Request Testing

For testing my NodeJs Server I am using mocha and supertest.
But I don`t like the simplicity of my tests, they actually are not checking server properly.
// simple test
describe('Server GET requests', function() {
it('GET /index', function(done){
request(app)
.get('/')
.expect(200, done)
})
})
So the test is only checking that server has a response for the request, but is not checking the correctnes of the response. I want test to be looking something like this:
// test should be
describe('Server GET requests', function() {
it('GET /index', function(done){
request(app)
.get('/')
.expect(200)
.end(function (err, res) {
if (err != null)
done(err);
checkContentTitle('Home Page', res.text);
checkContent(params, res.text);
done();
})
})
})
// function to check the title of the send result
function checkContentTitle(title, htmlText){
// checkTitle(title, parse('title', htmlText));
}
But I can`t find the propriate way of doing this.
What is a good practice of testing server responses, GET-request responses for example?
I suppose I need some tols like html\DOM parser, to get specific tags? Can somebody advise proper tools?
Try the cheerio library:
cheerio
It works like jquery for selecting DOM elements, very easy to use.
You can compare the cheerio returned values with the assertions that you want.
Example of test/test.js:
var assert = require("assert");
var cheerio = require('cheerio');
var request = require('request');
describe('domtesting', function() {
describe('GET /', function () {
it('title must be Hello', function (done) {
request('http://example.com/',function(err,response,html){
if(!err){
var $ = cheerio.load(html);
assert.equal('Hello', $('title').text());
done();
}
else{
console.log(err);
}
})
});
});
});
Use named functions or mocha promise syntax in order to get more readable and maintainable code. I also used the request library for launch http request inside tests.

Categories