How to test RESTful CRUD api with Mocha Chai on Node.js server side if login is required?
I want to test the CRUD logic on the web application server side. But only the login user can visit the web application.
if (res.locals.user){
//CRUD functions here
}
I know how to use Mocha and Chai to test these CRUD functions without checking the login, but how can I mock the login user to test them? Use a cookie?
+3
source to share
2 answers
I usually do something like:
var request = require('supertest');
describe('My tests', function(){
var agent = request.agent(app);
//before all the tests run, log in
before(function(done){
request(app)
.post('/login')
.send({
username: 'a@b.com',
password: 'password123'
})
.end(function (err, res) {
if (err) { return done(err); }
agent.saveCookies(res);
done();
});
});
it('Does something when logged in', function (done){
var req = request(app).get('/account/something')
.expect(200);
//attach the logged in cookies to the agent
agent.attachCookies(req);
req.end(done);
//assertions here
});
})
First open login request, save cookies to agent
Then I want to use the authenticated request in requests. attach cookies to it.
app
is an instance of the Express application
+2
source to share
@Russj assuming that:
- you are using
passport-local
as your authentication strategypassport
- you use
supertest
to simulate api calls - You already have a file that your Express app is exporting
Then this is how I would test the completed endpoints:
var request = require('supertest'),
agent = request.agent();
mongoose = require('mongoose'),
// this examples assumes /path/to/your/app exports your Express app
app = require('/path/to/your/app'),
// replace this with the model you use for authentication
UserModel = mongoose.model('UserModel');
// this example assumes your user model looks something like the following:
//
// UserModel = new mongoose.Schema({
// username: String,
// password: String
// });
describe('testing authenticated end-point', function () {
var UserModel, testuser;
before(function (done) {
// this is just to ensure we have a user to log in for your tests
UserModel.findOneAndUpdate({
{ username: 'testuser' },
{ username: 'testuser', password: 'testpassword' },
{ upsert: true }, // this will create the user if it doesn't already exist
function(err, doc) {
testuser = doc
}
});
// I assume /simulate-login is not an existing route in your app
app.get('/simulate-login', function(req, res) {
req.login(testuser); // .login is exposed in req by passport
});
// now we simulate login of our testuser and save the cookies
request(app)
.get('/simulate-login')
.end(function (err, res) {
if (err) { return done(err); }
// save cookies
agent.saveCookies(res);
done();
});
});
// clean up after ourselves
after(function () {
UserModel.remove({ username: 'testuser' }).exec();
});
// now we can test an authenticated end-point as long as we attach the saved cookies
it('should do whatever...', function (done) {
var req;
req = request(app)
.get('/path/to/route/to/test')
.expect(200);
// attach cookies
agent.attachCookies(req);
// do your reqeust
req.end(done);
});
});
+2
source to share