Я создаю веб-приложение, которое соединяется с 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();
});
};
Любая помощь будет оценена.
С уважением.