I want to test a web app server side CRUD logics. But only login user can visit the web app.
if (res.locals.user){
//CRUD functions here
}
I know how to use Mocha and Chai to test these CRUD functions without the login check there, but how can I mock login user to test them? Use cookie?
@Russj, assuming that:
passport-local as your passport authentication strategysupertest to simulate your api callsThen this is how I would go about testing authenticated end-points:
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);
});
});
I generally do something along the lines of:
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
});
})
Fire off a login request first, save the cookies to the agent
Then, in requests I want to use the authenticated request. attach the cookies to it.
app is the instance of the Express app