在Mocha上测试管理员用户

时间:2015-06-24 15:27:51

标签: node.js testing tdd mocha jwt

我正在编写测试,尝试在使用JWT进行身份验证的应用程序上使用带有Mocha的TDD。基本上,管理员和普通用户使用布尔管理字段共享相同的用户模型。

这些是路线:

app.post('/register', controllers.auth.create);
app.post('/login', controllers.auth.login);

router.get('/admin', function (req, res) {..[render admin login tpl]..}); 
router.post('/admin', isAuthenticated, isAuthorized, controllers.admin.index);

我的问题是,如何测试管理员用户,我无法直接在DB上创建,因为我也在检查令牌(isAuthenticated)。 什么是在摩卡测试它的最佳方法?

1 个答案:

答案 0 :(得分:2)

这是一个例子,你可以看到我如何测试你想要的东西,我正在使用mocha,supertest,express,body-parser,jsonwebtoken,express-jwt和async libraries。

我的app.js文件:

  var express = require('express');
  var app = express();
  var bodyParser = require('body-parser');

  var jwt = require('jsonwebtoken');
  var auth = require('./auth.js');

  var secret = require('./config.js').secret;

  var dbUsers = [
      {
        id: 123,
        username: 'johndoe',
        password: 'foobar',
        fullName: 'John Doe',
        email: 'john@doe.com',
        admin: true
      },
      {
        id: 321,
        username: 'wilson',
        password: 'nosliw',
        fullName: 'Wilson Balderrama',
        email: 'wilson.balderrama@gmail.com',
        admin: false
      }
  ];

  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({extended: true}));

  app.post('/login', function(req, res, next) {
    var userFound = null;
    var error = null;

    dbUsers.some(function(user) {
      if (user.username === req.body.username && user.password === req.body.password) {
        userFound = user;
        return true;
      }
    });

    if (!userFound) {
      error = new Error('Wrong user or password');
      error.status = 401;
      return next(error);
    }

    var profile = {
        id: userFound.id,
        email: userFound.email,
        admin: userFound.admin
    };

    var token = jwt.sign(profile, secret, {expireInMinutes: 60*5});
    res.json({token: token});
  });

  app.post('/admin', auth.isAuthenticated, auth.isAuthorized, handlePost);

  app.use(handleError);

  function handlePost(req, res) {
    res.send('Hello Admin!');
  }

  function handleError(err, req, res, next) {
    res.status(err.status || 500).send(err.message);
  }

  app.listen(4040, function() {
    console.log('server up and running at 4040 port');
  });

  module.exports = app;

我的auth.js文件:

  var secret = require('./config.js').secret;
  var expressJwt = require('express-jwt');

  module.exports = {
    isAuthenticated: function (req, res, next) {
      return expressJwt({secret: secret})(req, res, next);
    },

    isAuthorized: function(req, res, next) {
      if (req.user.admin) {
        return next();
      }

      res.status(401).send('You are not an admin!');
    }
  };

我的config.js

module.exports = {
  secret: 'shh'
};

最后我的' test.js'文件:

var assert = require('assert');
var async = require('async');

var request = require('supertest');
var app = require('./app.js');

describe('Test Admin', function() {

  it('should not be able to login', function(done) {
    request(app)
      .post('/login')
      .expect(401, done);
  });

  it('should not be able to consume /admin route a user unkwown', function(done) {
    var user = {
        username: 'noone',
        password: 'nothing'
    };

    request(app)
      .post('/admin')
      .expect(401, done);
  });

  it('should not be able to consume /admin route a known user with no admin priv', function (done) {
    async.waterfall(
      [
        function login(next) {
          var user = {
              username: 'wilson',
              password: 'nosliw'
          };

          request(app)
            .post('/login')
            .send(user)
            .expect(200)
            .end(function(err, res) {
              if (err) return next(err);

              var result = JSON.parse(res.text);
              next(null, result.token);
            })
        },

        function tryConsumeAdminRoute(token, next) {
          request(app)
            .post('/admin')
            .set('Authorization', 'Bearer ' + token)
            .expect(401)
            .end(function(err, res) {
              assert.equal(res.text, 'You are not an admin!');
              done();
            });
        }
      ],
      function finished(err, result) {
        done(err);
      }
    );
  });

  it('should be able to consume /admin route', function(done) {

    async.waterfall(
      [
        function login(next) {
          var user = {
              username: 'johndoe',
              password: 'foobar'
          };

          request(app)
            .post('/login')
            .send(user)
            .expect(200)
            .end(function(err, res) {
              if (err) return next(err);

              var response = JSON.parse(res.text);
              console.log(response);
              next(null, response.token);
            });
        },
        function consumeAdminRoute(token, next) {
          request(app)
            .post('/admin')
            .set('Authorization', 'Bearer ' + token)
            .expect(200, done);
        }
      ],
      function finish(err, result) {
        done(err);
      }
    );

  });
});