Nock не ловит почтовые запросы используя chai-http и mocha - PullRequest
0 голосов
/ 05 июня 2019

Я создаю веб-приложение, которое соединяется с API для входа в систему и некоторых других вещей, в настоящее время я пытаюсь проверить маршрут /authenticate в моем приложении, используя chai, chai-http и nock.

var chai = require('chai');        
var expect = chai.expect;
var chaiHttp = require('chai-http');
var nock = require('nock');

chai.use(chaiHttp);

describe('/authenticate', function() {
var agent = chai.request.agent('http://localhost:3000');

  afterEach(function() {
    agent.close();         
    nock.cleanAll();       
  });

  describe('User authorized', function() {
    it('redirects to /dashboard', function() {
      // I'm trying to mock the response here but is not working.
      nock('http://the.api.com:8080')
      .post('/v1/authenticate')
      .reply(201, {
        'authorized': true,
        'jwt': 'thejwtasdf'
      });
      agent
      .post('/authenticate')
      .send({ email: 'test@gmail.com', password: 'TheAmazingPass' })
      .then(function(res) {
        expect(res).to.redirectTo('http://localhost:3000/dashboard');
        expect(res.text).to.match(/Dashboard/);
      })
      .catch(function(e) { console.log(e);  });
    });
  });
});

Пройден тест, но я получил эту пойманную ошибку, согласно которой страница не перенаправляется, потому что nock не перехватывает вызов, и он напрямую отправляется в API:

{ AssertionError: expected redirect with 30X status code but got 200
  at Proxy.<anonymous>
  ... rest of the error omitted.

Но когда я использую реальный и действительный адрес электронной почты и пароль, этот тест проходит без обнаруженной ошибки:

var chai = require('chai');
var expect = chai.expect;
var chaiHttp = require('chai-http');
var nock = require('nock');

chai.use(chaiHttp);

describe('/authenticate', function() {
  var agent = chai.request.agent('http://localhost:3000')

  afterEach(function() {
    agent.close();
    nock.cleanAll();
  });

  describe('User authorized', function() {
    it('redirects to /dashboard', function() {
      agent
      .post('/authenticate')
      .send({ email: 'realemail@gmail.com', password: 'RealPass'  })
      .then(function(res) {
        expect(res).to.redirectTo('http://localhost:3000/dashboard');
        expect(res.text).to.match(/Dashboard/);
      })
      .catch(function(e) { console.log(e);  });
    });
  });
});

С этим кодом тест проходит, я что-то пропустил с nock?

=== РЕДАКТИРОВАТЬ ===

Это код, который я пытаюсь проверить:

Это мой маршрутизатор входа в систему (flashMessages - это специальное промежуточное ПО, которое помогает сфлеш-сообщения).

var loginService = require('../services/login');
var flashMessages = require('../utils/flash_messages').flashMessages;
var router = require('express').Router();

// check if user is logged in
var sessionChecker = function(req, res, next) {
  if (req.session.auth && req.cookies.user_sid) {
    res.redirect('/dashboard');
  } else {
    next();
  }
};

router.get('/', sessionChecker, flashMessages, function(req, res, next){
  res.render('login', {
    title: 'Welcome',
    errors: res.locals.flash.errors,
    typeError: res.locals.flash.errorType,
  });
});

router.post('/authenticate', function(req, res, next){
  req.checkBody('email', 'Email is required').notEmpty();
  req.checkBody('email', 'Invalid email format').isEmail();
  req.checkBody('password', 'Password is required').notEmpty();
  req.getValidationResult().then(function(result){
    if (result.isEmpty()) {
      loginService.authenticate(req.body).then(function(result){
        if (result.authorized){
          // success
          req.session.auth = result;
          req.session.auth.user = loginService.currentUser(result.jwt)
          res.redirect('/dashboard');
        } else {
          // user not found error
          req.session.flash = {
            errors: [{msg: result.msg}],
            errorType: 'anotherError'
          };
          res.redirect('/');
        }
      }).catch(function(e){
        // server errors
        req.session.flash = {
          errors: [e],
          errorType: 'anotherError'
        };
        res.redirect('/');
      });
    } else {
      //validation errors
      req.session.flash = {
        errors: result.array(),
        errorType: 'validationError'
      };
      res.redirect('/');
    }
  });
});

module.exports = router;

Маршрутизатор входа использует loginService, это часть, которая работает с именем входа:

var httpReq = require('../utils/http_requests');

module.exports.authenticate = function(params){
  return new Promise(function(resolve, reject) {
    httpReq.callToAPI(params, {
      path: '/v1/authenticate',
      method: 'POST'
    })
    .then(function(authorization) {
      resolve(JSON.parse(authorization));
    })
    .catch(function(err) {
      reject(err);
    });
  });
};

module.exports.currentUser = function(shaCode){
  return JSON.parse(Buffer.from(shaCode.split('.')[1], 'base64').toString());
};

И, наконец, у меня есть утилиты для запросов http:

var http = require('http');

function createOptions(options) {
  headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Connection': 'close'
  };
  if (options.jwt) { headers['Authorization'] = 'Bearer ' + options.jwt; }
  return {
    hostname: 'the.api.com',
    port: 8080,
    path: options.path,
    method: options.method,
    headers: headers
  };
};

module.exports.callToAPI = function(params, options) {
  reqObj = createOptions(options);
  return new Promise(function(resolve, reject) {
    body = [];
    req = http.request(reqObj, function(res) {
      res.on('data', function(chunk) {
        body.push(chunk);
      });
      res.on('end', function() {
        console.log(body.join(''));
        resolve(body.join(''));
      });
    });
    req.on('error', function(err) {
      reject({ msg: "We're sorry, but something went wrong" });
    });
    if (params) { req.write(JSON.stringify(params)); }
    req.end();
  });
};

Любая помощь будет оценена.

С уважением.

...