restify-new-nodejs-compatible
Version:
REST framework
278 lines (240 loc) • 7.27 kB
JavaScript
;
/* eslint-disable func-names */
var restifyClients = require('restify-clients');
var validator = require('validator');
var restify = require('../lib');
if (require.cache[__dirname + '/lib/helper.js']) {
delete require.cache[__dirname + '/lib/helper.js'];
}
var helper = require('./lib/helper.js');
///--- Globals
var after = helper.after;
var before = helper.before;
var test = helper.test;
var PORT = process.env.UNIT_TEST_PORT || 0;
var CLIENT;
var SERVER;
before(function(cb) {
try {
SERVER = restify.createServer({
dtrace: helper.dtrace,
log: helper.getLog('server')
});
SERVER.listen(PORT, '127.0.0.1', function() {
PORT = SERVER.address().port;
CLIENT = restifyClients.createJsonClient({
url: 'http://127.0.0.1:' + PORT,
dtrace: helper.dtrace,
retry: false
});
cb();
});
} catch (e) {
console.error(e.stack);
process.exit(1);
}
});
after(function(cb) {
try {
CLIENT.close();
SERVER.close(function() {
CLIENT = null;
SERVER = null;
cb();
});
} catch (e) {
console.error(e.stack);
process.exit(1);
}
});
test('query should return empty string', function(t) {
SERVER.get('/emptyQs', function(req, res, next) {
t.equal(req.query(), '');
t.equal(req.getQuery(), '');
res.send();
next();
});
CLIENT.get('/emptyQs', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('query should return raw query string string', function(t) {
SERVER.get('/qs', function(req, res, next) {
t.equal(req.query(), 'a=1&b=2');
t.equal(req.getQuery(), 'a=1&b=2');
res.send();
next();
});
CLIENT.get('/qs?a=1&b=2', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should generate request id on first req.id() call', function(t) {
SERVER.get('/ping', function(req, res, next) {
t.equal(typeof req.id(), 'string');
t.equal(validator.isUUID(req.id(), 4), true);
res.send();
return next();
});
CLIENT.get('/ping', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should set request id', function(t) {
SERVER.pre(function setId(req, res, next) {
var newId = req.id('lagavulin');
t.equal(newId, 'lagavulin');
return next();
});
SERVER.get('/ping', function(req, res, next) {
t.equal(typeof req.id(), 'string');
t.equal(req.id(), 'lagavulin');
res.send();
return next();
});
CLIENT.get('/ping', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should throw when setting request id after autogeneration', function(t) {
SERVER.get('/ping', function(req, res, next) {
t.equal(typeof req.id(), 'string');
t.equal(validator.isUUID(req.id(), 4), true);
t.throws(
function() {
req.id('blowup');
},
Error,
'request id is immutable, cannot be set again!'
);
res.send();
return next();
});
CLIENT.get('/ping', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should throw when setting request id twice', function(t) {
SERVER.get('/ping', function(req, res, next) {
req.id('lagavulin');
t.throws(
function() {
req.id('blowup');
},
Error,
'request id is immutable, cannot be set again!'
);
res.send();
return next();
});
CLIENT.get('/ping', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should provide route object', function(t) {
SERVER.get('/ping/:name', function(req, res, next) {
/*
req.getRoute() should return something like this :
{
path: '/ping/:name',
method: 'GET',
versions: [],
name: 'getpingname'
}
*/
var routeInfo = req.getRoute();
t.equal(routeInfo.path, '/ping/:name');
t.equal(routeInfo.method, 'GET');
res.send({ name: req.params.name });
return next();
});
CLIENT.get('/ping/lagavulin', function(err, _, res, parsedBody) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.deepEqual(parsedBody, { name: 'lagavulin' });
t.end();
});
});
test('should provide time when request started', function(t) {
SERVER.get('/ping/:name', function(req, res, next) {
t.equal(typeof req.time(), 'number');
t.ok(req.time() > Date.now() - 1000);
t.ok(req.time() <= Date.now());
res.send('ok');
return next();
});
CLIENT.get('/ping/lagavulin', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
test('should provide date when request started', function(t) {
SERVER.get('/ping/:name', function(req, res, next) {
t.ok(req.date() instanceof Date);
t.ok(req.date().getTime() > Date.now() - 1000);
t.ok(req.date().getTime() <= Date.now());
res.send('ok');
return next();
});
CLIENT.get('/ping/lagavulin', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.end();
});
});
// restifyDone is emitted at the same time when server's after event is emitted,
// you can find more comprehensive testing for `after` lives in server tests.
test('should emit restifyDone event when request is fully served', function(t) {
var restifyDoneCalled = false;
SERVER.get('/', function(req, res, next) {
req.on('restifyDone', function(route, err) {
t.ifError(err);
t.ok(route);
setImmediate(function() {
restifyDoneCalled = true;
});
});
res.send('hello');
return next();
});
CLIENT.get('/', function(err, _, res) {
t.ifError(err);
t.equal(res.statusCode, 200);
t.ok(restifyDoneCalled);
t.end();
});
});
// eslint-disable-next-line max-len
test('should emit restifyDone event when request is fully served with error', function(t) {
var clientDone = false;
SERVER.get('/', function(req, res, next) {
var myErr = new Error('My Error');
req.on('restifyDone', function(route, err) {
t.ok(route);
t.deepEqual(err, myErr);
setImmediate(function() {
t.ok(clientDone);
t.end();
});
});
return next(myErr);
});
CLIENT.get('/', function(err, _, res) {
t.ok(err);
t.equal(res.statusCode, 500);
clientDone = true;
});
});