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


@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







All Articles