在 Mocha 上测试管理员用户

Testing admin user on Mocha

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

这些是路线:

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);

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

这是一个示例,您可以在其中看到我如何测试您想要的东西,我正在使用 mocha、supertest、express、body-parser、jsonwebtoken、express-jwt 和异步库。

我的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);
      }
    );

  });
});