I am having trouble making my unit test pass and I think it is because it is posting using the wrong type of data. My route:
let upload = multer({
storage: storage
});
router.route('/')
.post(upload.any('image'), function (req, res, next) {
let memory = new Memory();
if (req.files.length === 0) {
Object.assign(memory, req.body);
} else {
Object.assign(memory, req.body, {'image': req.file.secure_url});
}
memory.save(function (err) {
if (err) {
return res.send(err);
}
res.json({message: 'Memory Created', memory});
});
})
As you can see my route uses multer which accepts form-data as input. However, in my Chai test:
it('it should not post an item without a location field', (done) => {
let formData = new FormData();
formData.append('description', "First time we met");
formData.append('image','n/a');
chai.request(server)
.post('/api/memory')
.set('Accept', 'application/form-data')
.send(formData)
.end((err, res) => {
res.should.have.status(200);
res.body.should.be.a('object');
res.body.should.have.property('errors');
res.body.errors.should.have.property('location');
res.body.errors.location.should.have.property('kind').eql('required');
done();
});
I am using Chai's send method but this test just freezes and gives me no response. So I tried using postman and if I send data using x-www-form-urlencoded it feezes but if I send data using form-data it works fine. So I suspect I am sending data in x-www-form-urlencded using Chai. How do I fix this? (Note: I tried using .set('Accept', 'application/form-data'))
Simply use .field()
describe('/POST item', () => {
it('it should not post an item without a location field', (done) => {
chai.request(server)
.post('/api/memory')
.set('Accept', 'application/form-data')
.field('description', "First time we met")
.end((err, res) => {
res.should.have.status(200);
res.body.should.be.a('object');
res.body.should.have.property('errors');
res.body.errors.should.have.property('location');
res.body.errors.location.should.have.property('kind').eql('required');
done();
});
});
Related
In the file where I have written the request methods looks like this:
article.js
router
.route("/")
.all((req, res) => {
console.log("this should happen for any call to the article route");
})
.get((req, res) => {
// returns all the data in the database
Rest.find({}, (err, result) => {
if (!err) {
console.log(result);
res.send(result);
} else {
res.send(err);
}
});
})
.post((req, res) => {
const articleTitle = req.body.title;
const articleContent = req.body.content;
const articleDate = req.body.date;
const article = new Rest({
title: articleTitle,
content: articleContent,
date: articleDate,
});
article
.save()
.then((result) => {
res.send(result);
})
.catch((err) => {
res.send(err);
});
})
.delete((req, res) => {
Rest.deleteMany({}, (err, result) => {
if (!err) {
res.send(result);
} else {
res.send(err);
}
});
});
module.exports = router;
and I have and app.js
const article = require("./article");
app.use('/articles', article);
When I make a call to url it just loads and I get no response.
At first I was just writing it http verb on it own. But it was making my app.js have a lot of code so I decided to move all this logic to its own file article.js and use router.route() to chain the http verbs together to make the code look cleaner. But doing that I encounter the error when I get no result and it just loads forever.
Am I doing something wrong?
Any help is appreciated thanks.
I figured it out. The solution was to add next() to .all() method. Because I was passing next, I think the http request was just stuck at that point waiting.
So the new code should be
router
.route('/')
.all((req, res, next)) => {
// logic
next();
})
and the rest of the code follows.
Given is my code to test a post request with an Authorization header set to the jwt token and a path parameter passed in to the post path, i.e. the id:5ee9b12ab08b6c3c58375a6d
Is there a better way to do this?
const expect = require("expect");
const request = require("request");
const chai = require("chai");
let chaiHttp = require("chai-http");
let server = require("../app");
let should = chai.should();
chai.use(chaiHttp);
describe("Admin Priveleges", () => {
describe("/Update Status", () => {
it("Update membership and registration status", (done) => {
chai
.request(server)
.post("/api/v2/user/update-status/5ee9b12ab08b6c3c58375a6d")
.set('Authorization', "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWU5YjEzN2IwOGI2YzNjNTgzNzVhNmUiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE1OTI0NjEyMjIyMDgsIm5hbWUiOiJVdGthcnNoIFNocml2YXN0YXZhIiwiaWF0IjoxNTkyMzc0ODIyfQ.M53gRzIppbhhLSCf9bD6xcdXfITiD1jUOzTlDqHK3is")
.send({
membership_status: "active",
registration_status: "pending_approval",
status_comment: "Good going"
})
.end((err, res) => {
if (err) throw err;
if (should) console.log("****Status Updated Successfully****");
res.should.have.status(200);
done();
});
}).timeout(30000);
});
});
So this is my testing code and each time I run this for testing I get the following error:
How can I solve this error?
When I copy-pasted you 'url' in web console, it showed the actual string with the otherwise 'invisible' .
Test:
context('Should not show "Request path contains unescaped characters, in Mocha/chai testing"', function() {
it('POST /api/v2/user/update-status/5ee9b12ab08b6c3c58375a6d', function(done) {
chai
.request(server)
.post('/api/v2/user/update-status/5ee9b12ab08b6c3c58375a6d')
// .post('/api/v2/user/update-status/5ee9b12ab08b6c3c58375a6d') // with the 'hidden dots'
.set('Authorization', "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWU5YjEzN2IwOGI2YzNjNTgzNzVhNmUiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE1OTI0NjEyMjIyMDgsIm5hbWUiOiJVdGthcnNoIFNocml2YXN0YXZhIiwiaWF0IjoxNTkyMzc0ODIyfQ.M53gRzIppbhhLSCf9bD6xcdXfITiD1jUOzTlDqHK3is")
.send({
membership_status: "active",
registration_status: "pending_approval",
status_comment: "Good going"
})
.end((err, res) => {
// if (err) throw err;
// if (should) console.log("****Status Updated Successfully****");
// res.should.have.status(200);
expect(res).to.have.status(404);
done();
});
});
})
I have a problem right now that I can't solve by myself. I assume you know more here. I'm just getting started.
By using the following code I'm getting a list of customers:
app.get("/customers", customers.findAll);
I wanted to add authentication. But now I don't know how to execute "customers.findAll" and get the value as JSON.
app.get("/customers", verifyToken, (req, res) => {
jwt.verify(req.token, 'justAtest, (err, authData) => {
if (err) {
res.sendStatus(403);
} else {
// execute customers.findAll
}
});
});
Customers is integrated via a requirement
const customers = require("../controllers/customer.controller.js");
The contents are as follows:
exports.findAll = (req, res) => {
Customer.getAll((err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while retrieving customers."
});
else res.send(data);
});
};
Do you have any ideas?
Thank you in advance.
Grettings
Rok
You achieve that using something called "middleware". Explore it since it is very important.
Basically :
app.get("/customers", verifyToken,customers.findAll);
Wherre verify token is a funtion that has 3 parameters: req, res and 3rd one called "next".
So your verify token function would look something like:
(req, res,next) => {
jwt.verify(req.token, 'justAtest, (err, authData) => {
if (err) {
res.sendStatus(403);
} else {
next();
}
});
}
I took it from your snippet. Basically if you want to jump to customeeers.finalAll, just call "next" and it jumps to next function :D.
I am working with postman where i am sending my post data to api to insert data in mongodb.My issue is that i am not able to handle the error message properly. Here is my code for it
exports.addUser = (req, res, next) => {
const db = getdb();
// console.log(db)
// console.log(db)
db.collection12("user").insertOne({
name: req.body.name,
password:req.body.password
}).then((result) => {
res.send(result)
}).catch((err) => {
res.status(404).send('Error in adding')
});
};
so i knowingly made and error and wrote "collection12" so that i get and error but then in my catch method i am returning
("Error in addding")
so why then in postman i am not able to see this instead of that i am seeing a hude error meassge that says
See error here
I guess than same would be the issue in my react side where instead of getting my own error meassge i would get this huge message
You actually don't enter the catch block because it cannot even execute the db call. If you want a 404 error to be dispatched in this situation you need to add a try/catch statement like this:
exports.addUser = (req, res, next) => {
const db = getdb();
// console.log(db)
// console.log(db)
try {
db.collection12("user").insertOne({
name: req.body.name,
password:req.body.password
}).then((result) => {
res.send(result)
}).catch((err) => {
res.status(404).send('Error in adding')
});
} catch {
res.status(404).send('Error in adding')
}
};
I'm testing the controller logic behind API endpoints in my node server with jasmine-node. Here is what this controller logic typically looks like:
var getSummary = function(req, res) {
var playerId = req.params.playerId;
db.players.getAccountSummary(playerId, function(err, summary) {
if (err) {
logger.warn('Error while retrieving summary for player %d.', playerId, err);
return res.status(500).json({
message: err.message || 'Error while retrieving summary.',
success: false
});
} else {
res.json({success: true, summary: summary});
}
});
};
Below is how I successfully test the else block:
describe('GET /api/players/:playerId/summary', function() {
it('should return an object summarizing the player account', function(done) {
request
.get('/api/players/' + playerId + '/summary')
.set('Content-Type', 'application/json')
.set('cookie', cookie)
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
expect(err).toBeNull(err ? err.message : null);
expect(res.body.success).toBe(true);
expect(res.body.summary).toBeDefined();
done();
});
});
});
This works nicely, but leaves me with poor branch coverage as the if block is never tested. My question is, how do I force the error block to run in a test? Can I mock a response which is set to return an error so that I can test the correct warning is logged and correct data is passed back?
It depends on your tests. If you only want to unit test, spies are the way to go.
You can just stub your db response. Be aware that in this case the database is not called though. It's just simulated.
const db = require('./yourDbModel');
spyOn(db.players, 'getAccountSummary').and.callFake(function(id, cb) {
cb(new Error('database error');
});
request
.get('/api/players/' + playerId + '/summary')
.set('Content-Type', 'application/json')
.set('cookie', cookie)
.expect(500)
// ...
If you want functional/integration tests, you need to call your request simply with wrong data, for example a players id that doesn't exist in your database.
request
.get('/api/players/i_am_no_player/summary')
.set('Content-Type', 'application/json')
.set('cookie', cookie)
.expect(500)
// ...