<commit_before>/* global describe, context, it, before, after */

// eslint-disable-next-line no-unused-vars
var should = require('should');
var jwt = require('jsonwebtoken');
var local = require('../../config/local');
var io = require('socket.io-client');


describe('TresDB Socket.io API', function () {
  var socket;

  before(function (done) {
    socket = io('http://localhost:' + local.port);
    socket.on('connect', done);
  });

  after(function () {
    socket.disconnect();
  });

  var createResponseAssert = function (ev, key, val) {
    // Return an assertion function that emits the given event and tests
    // that the response has correct key and value string.
    // Value is optional parameter.
    //
    // The returned function takes payload, and done-callback as its params.
    //
    // Usage:
    //   var he = createResponseAssert('auth/login', 'error', 'HashingError');
    //   ...
    //   it('should response with HashingError', function (done) {
    //     he({ pay: load, that: causes, hashing: error }, done);
    //   });
    //
    return function assertion(payload, done) {
      socket.emit(ev, payload, function (res) {
        if (typeof val === 'undefined') {
          res.should.have.property(key);
        } else {
          res.should.have.property(key, val);
        }
        done();
      });
    };
  };

  describe('auth/login should response with', function () {


    context('JWT token when', function () {

      var assertToken = createResponseAssert('auth/login', 'token');

      it('known email and password are provided', function (done) {
        assertToken({
          email: local.admin.email,
          password: <PASSWORD>,
        }, done);
      });
    });

    context('InvalidRequestError when', function () {

      var assertIRE = createResponseAssert('auth/login', 'error',
                                           'InvalidRequestError');

      it('an empty payload is provided', function (done) {
        assertIRE({}, done);
      });

      it('a valid email is provided without password', function (done) {
        assertIRE({ email: local.admin.email }, done);
      });

      it('an unknown email is provided without password', function (done) {
        assertIRE({ email: '<EMAIL>' }, done);
      });

      it('an object is injected as email', function (done) {
        assertIRE({
          email: {
            foo: 'bar',
          },
          password: '<PASSWORD>',
        }, done);
      });

      it('a malformed email is given', function (done) {
        // Client should ensure correctly formatted email address.
        assertIRE({
          email: 'foo@bar',
          password: '<PASSWORD>',
        }, done);
      });

      it('an empty password is given', function (done) {
        assertIRE({
          email: '<EMAIL>',
          password: '',
        }, done);
      });

    });

    context('UnknownEmailError when', function () {
      it('a unknown but correctly formatted email is given', function (done) {
        var payload = {
          email: '<EMAIL>',
          password: '<PASSWORD>',
        };

        socket.emit('auth/login', payload, function (res) {
          res.should.have.property('error', 'UnknownEmailError');
          done();
        });
      });
    });

    context('IncorrectPasswordError when', function () {
      it('a wrong is given with known email', function (done) {
        var payload = {
          email: local.admin.email,
          password: '<PASSWORD>',
        };

        socket.emit('auth/login', payload, function (res) {
          res.should.have.property('error', 'IncorrectPasswordError');
          done();
        });
      });
    });
  });

  describe('auth/changePassword should response with', function () {

    var goodToken = jwt.sign({ email: local.admin.email }, local.secret);
    var badEmailToken = jwt.sign({ email: '<EMAIL>' }, local.secret);
    var badToken1 = jwt.sign({ foo: 'bar' }, local.secret);
    var badToken2 = jwt.sign({ email: local.admin.email }, 'foo');

    context('InvalidRequestError when', function () {
      var assertIRE = createResponseAssert('auth/changePassword', 'error',
                                           'InvalidRequestError');

      it('no token is provided', function (done) {
        assertIRE({}, done);
      });

      it('the token has signed but unexpected content', function (done) {
        assertIRE({ token: badToken1 }, done);
      });

      it('the token is signed with unknown key', function (done) {
        assertIRE({ token: badToken2 }, done);
      });

      it('no current password is provided', function (done) {
        assertIRE({ token: goodToken }, done);
      });
    });

    context('UnknownEmailError when', function () {
      var assertUEE = createResponseAssert('auth/changePassword', 'error',
                                           'UnknownEmailError');

      it('unknown email is provided', function (done) {
        assertUEE({
          token: badEmailToken,
          currentPassword: <PASSWORD>,
          newPassword: <PASSWORD>,
        }, done);
      });

    });

    context('IncorrectPasswordError when', function () {
      var assertIPE = createResponseAssert('auth/changePassword', 'error',
                                           'IncorrectPasswordError');

      it('the current password is incorrect', function (done) {
        assertIPE({
          token: goodToken,
          currentPassword: '<PASSWORD>',
          newPassword: '<PASSWORD>',
        }, done);
      });
    });

    context('success when', function () {
      var assertSuccess = createResponseAssert('auth/changePassword', 'success',
                                               true);

      it('token ok, passwords match', function (done) {
        assertSuccess({
          token: goodToken,
          currentPassword: <PASSWORD>,
          newPassword: <PASSWORD>,
        }, done);
      });
    });
  });

});<commit_msg>tests: make auth.spec use test db<commit_after>/* global describe, context, it, before, after */

var local = require('../../config/local');
// eslint-disable-next-line no-unused-vars
var should = require('should');
var jwt = require('jsonwebtoken');
var io = require('socket.io-client');
var monk = require('monk');
var bcrypt = require('bcryptjs');

var db = monk(local.mongo.testUrl);


// Set up test fixtures

var ADMIN_USER = 'admin';
var ADMIN_EMAIL = '<EMAIL>';
var ADMIN_PASSWORD = '<PASSWORD>';

var TESTER_USER = 'tester';
var TESTER_EMAIL = '<EMAIL>';
var TESTER_PASSWORD = '<PASSWORD>';

var fixture = {
  users: [
    {
      name: ADMIN_USER,
      email: ADMIN_EMAIL,
      hash: bcrypt.hashSync(ADMIN_PASSWORD, local.bcrypt.rounds),
      admin: true,
    },
    {
      name: TESTER_USER,
      email: TESTER_EMAIL,
      hash: bcrypt.hashSync(TESTER_PASSWORD, local.bcrypt.rounds),
      admin: false,
    },
  ],
};


describe('TresDB Socket.io API', function () {
  var socket;

  before(function (done) {
    socket = io('http://localhost:' + local.port);
    socket.on('connect', done);
  });

  after(function () {
    socket.disconnect();
  });

  beforeEach(function (done) {
    // Drop possibly existing collections
    var users = db.get('users');
    users.drop().then(function () {

      // Populate with test users
      users.insert(fixture.users).then(function () {
        done();
      }).catch(done);

    }).catch(done);
  });

  var createResponseAssert = function (ev, key, val) {
    // Return an assertion function that emits the given event and tests
    // that the response has correct key and value string.
    // Value is optional parameter.
    //
    // The returned function takes payload, and done-callback as its params.
    //
    // Usage:
    //   var he = createResponseAssert('auth/login', 'error', 'HashingError');
    //   ...
    //   it('should response with HashingError', function (done) {
    //     he({ pay: load, that: causes, hashing: error }, done);
    //   });
    //
    return function assertion(payload, done) {
      socket.emit(ev, payload, function (res) {
        if (typeof val === 'undefined') {
          res.should.have.property(key);
        } else {
          res.should.have.property(key, val);
        }
        done();
      });
    };
  };

  describe('auth/login should response with', function () {


    context('JWT token when', function () {

      var assertToken = createResponseAssert('auth/login', 'token');

      it('known email and password are provided', function (done) {
        assertToken({
          email: TESTER_EMAIL,
          password: <PASSWORD>,
        }, done);
      });
    });

    context('InvalidRequestError when', function () {

      var assertIRE = createResponseAssert('auth/login', 'error',
                                           'InvalidRequestError');

      it('an empty payload is provided', function (done) {
        assertIRE({}, done);
      });

      it('a valid email is provided without password', function (done) {
        assertIRE({ email: TESTER_EMAIL }, done);
      });

      it('an unknown email is provided without password', function (done) {
        assertIRE({ email: '<EMAIL>' }, done);
      });

      it('an object is injected as email', function (done) {
        assertIRE({
          email: {
            foo: 'bar',
          },
          password: '<PASSWORD>',
        }, done);
      });

      it('a malformed email is given', function (done) {
        // Client should ensure correctly formatted email address.
        assertIRE({
          email: 'foo@bar',
          password: '<PASSWORD>',
        }, done);
      });

      it('an empty password is given', function (done) {
        assertIRE({
          email: '<EMAIL>',
          password: '',
        }, done);
      });

    });

    context('UnknownEmailError when', function () {
      it('a unknown but correctly formatted email is given', function (done) {
        var payload = {
          email: '<EMAIL>',
          password: '<PASSWORD>',
        };

        socket.emit('auth/login', payload, function (res) {
          res.should.have.property('error', 'UnknownEmailError');
          done();
        });
      });
    });

    context('IncorrectPasswordError when', function () {
      it('a wrong pwd is given with known email', function (done) {
        var payload = {
          email: TESTER_EMAIL,
          password: '<PASSWORD>',
        };

        socket.emit('auth/login', payload, function (res) {
          res.should.have.property('error', 'IncorrectPasswordError');
          done();
        });
      });
    });
  });

  describe('auth/changePassword should response with', function () {

    var goodToken = jwt.sign({ email: TESTER_EMAIL }, local.secret);
    var badEmailToken = jwt.sign({ email: '<EMAIL>' }, local.secret);
    var badToken1 = jwt.sign({ foo: 'bar' }, local.secret);
    var badToken2 = jwt.sign({ email: TESTER_EMAIL }, 'foo');

    context('InvalidRequestError when', function () {
      var assertIRE = createResponseAssert('auth/changePassword', 'error',
                                           'InvalidRequestError');

      it('no token is provided', function (done) {
        assertIRE({}, done);
      });

      it('the token has signed but unexpected content', function (done) {
        assertIRE({ token: badToken1 }, done);
      });

      it('the token is signed with unknown key', function (done) {
        assertIRE({ token: badToken2 }, done);
      });

      it('no current password is provided', function (done) {
        assertIRE({ token: goodToken }, done);
      });
    });

    context('UnknownEmailError when', function () {
      var assertUEE = createResponseAssert('auth/changePassword', 'error',
                                           'UnknownEmailError');

      it('unknown email is provided', function (done) {
        assertUEE({
          token: badEmailToken,
          currentPassword: <PASSWORD>,
          newPassword: <PASSWORD>,
        }, done);
      });

    });

    context('IncorrectPasswordError when', function () {
      var assertIPE = createResponseAssert('auth/changePassword', 'error',
                                           'IncorrectPasswordError');

      it('the current password is incorrect', function (done) {
        assertIPE({
          token: goodToken,
          currentPassword: '<PASSWORD>',
          newPassword: '<PASSWORD>',
        }, done);
      });
    });

    context('success when', function () {
      var assertSuccess = createResponseAssert('auth/changePassword', 'success',
                                               true);

      it('token ok, passwords match', function (done) {
        assertSuccess({
          token: goodToken,
          currentPassword: <PASSWORD>,
          newPassword: <PASSWORD>,
        }, done);
      });
    });
  });

});
{'fraction_non_alphanumeric': 0.14471645491168267, 'fraction_numerical': 0.0006197706848466068, 'mean_word_length': 2.1508420795704173, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4195450', 'n_tokens_mistral': 3514, 'n_tokens_neox': 3401, 'n_words': 936}