Merge tag '3.8.0'
This commit is contained in:
commit
db4a061ed6
@ -7,3 +7,4 @@ matrix:
|
||||
- node_js: "0.11"
|
||||
fast_finish: true
|
||||
script: "npm run-script test-travis"
|
||||
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"
|
||||
|
12
History.md
12
History.md
@ -13,6 +13,7 @@ unreleased
|
||||
- `app.set('trust proxy', '10.0.0.1, 10.0.0.2')` trust list
|
||||
- `app.set('trust proxy', false)` turn off
|
||||
- `app.set('trust proxy', true)` trust everything
|
||||
* set proper `charset` in `Content-Type` for `res.send`
|
||||
* update type-is to 1.2.0
|
||||
- support suffix matching
|
||||
|
||||
@ -112,6 +113,17 @@ unreleased
|
||||
- `app.route()` - Proxy to the app's `Router#route()` method to create a new route
|
||||
- Router & Route - public API
|
||||
|
||||
3.8.0 / 2014-05-21
|
||||
==================
|
||||
|
||||
* keep previous `Content-Type` for `res.jsonp`
|
||||
* set proper `charset` in `Content-Type` for `res.send`
|
||||
* update connect to 2.17.1
|
||||
- fix `res.charset` appending charset when `content-type` has one
|
||||
- deps: express-session@1.2.0
|
||||
- deps: morgan@1.1.1
|
||||
- deps: serve-index@1.0.3
|
||||
|
||||
3.7.0 / 2014-05-18
|
||||
==================
|
||||
|
||||
|
@ -9,6 +9,7 @@ var escapeHtml = require('escape-html');
|
||||
var sign = require('cookie-signature').sign;
|
||||
var normalizeType = require('./utils').normalizeType;
|
||||
var normalizeTypes = require('./utils').normalizeTypes;
|
||||
var setCharset = require('./utils').setCharset;
|
||||
var contentDisposition = require('./utils').contentDisposition;
|
||||
var deprecate = require('./utils').deprecate;
|
||||
var etag = require('./utils').etag;
|
||||
@ -83,6 +84,8 @@ res.links = function(links){
|
||||
res.send = function(body){
|
||||
var req = this.req;
|
||||
var head = 'HEAD' == req.method;
|
||||
var type;
|
||||
var encoding;
|
||||
var len;
|
||||
|
||||
// settings
|
||||
@ -137,6 +140,17 @@ res.send = function(body){
|
||||
}
|
||||
}
|
||||
|
||||
// write strings in utf-8
|
||||
if ('string' === typeof body) {
|
||||
encoding = 'utf8';
|
||||
type = this.get('Content-Type');
|
||||
|
||||
// reflect this in content-type
|
||||
if ('string' === typeof type) {
|
||||
this.set('Content-Type', setCharset(type, 'utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
// freshness
|
||||
if (req.fresh) this.statusCode = 304;
|
||||
|
||||
@ -149,7 +163,8 @@ res.send = function(body){
|
||||
}
|
||||
|
||||
// respond
|
||||
this.end(head ? null : body);
|
||||
this.end((head ? null : body), encoding);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
36
lib/utils.js
36
lib/utils.js
@ -8,6 +8,11 @@ var basename = require('path').basename;
|
||||
var deprecate = require('util').deprecate;
|
||||
var proxyaddr = require('proxy-addr');
|
||||
|
||||
/**
|
||||
* Simple detection of charset parameter in content-type
|
||||
*/
|
||||
var charsetRegExp = /;\s*charset\s*=/;
|
||||
|
||||
/**
|
||||
* Deprecate function, like core `util.deprecate`,
|
||||
* but with NODE_ENV and color support.
|
||||
@ -187,3 +192,34 @@ exports.compileTrust = function(val) {
|
||||
|
||||
return proxyaddr.compile(val || []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the charset in a given Content-Type string.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} charset
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.setCharset = function(type, charset){
|
||||
if (!type || !charset) return type;
|
||||
|
||||
var exists = charsetRegExp.test(type);
|
||||
|
||||
// removing existing charset
|
||||
if (exists) {
|
||||
var parts = type.split(';');
|
||||
|
||||
for (var i = 1; i < parts.length; i++) {
|
||||
if (charsetRegExp.test(';' + parts[i])) {
|
||||
parts.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
type = parts.join(';');
|
||||
}
|
||||
|
||||
return type + '; charset=' + charset;
|
||||
};
|
||||
|
@ -68,9 +68,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"after": "0.8.1",
|
||||
"coveralls": "2.10.0",
|
||||
"istanbul": "0.2.10",
|
||||
"mocha": "~1.18.2",
|
||||
"mocha": "~1.19.0",
|
||||
"should": "~3.3.1",
|
||||
"supertest": "~0.12.0",
|
||||
"connect-redis": "~2.0.0",
|
||||
@ -93,6 +92,6 @@
|
||||
"prepublish": "npm prune",
|
||||
"test": "mocha --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/ && (cat ./coverage/lcov.info | coveralls || true)"
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/"
|
||||
}
|
||||
}
|
||||
|
@ -7,16 +7,43 @@ describe('content-negotiation', function(){
|
||||
it('should default to text/html', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>')
|
||||
.end(done);
|
||||
.expect(200, '<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>', done)
|
||||
})
|
||||
|
||||
it('should accept to text/plain', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/plain')
|
||||
.expect(' - Tobi\n - Loki\n - Jane\n')
|
||||
.end(done);
|
||||
.expect(200, ' - Tobi\n - Loki\n - Jane\n', done)
|
||||
})
|
||||
|
||||
it('should accept to application/json', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users', function(){
|
||||
it('should default to text/html', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.expect(200, '<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>', done)
|
||||
})
|
||||
|
||||
it('should accept to text/plain', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.set('Accept', 'text/plain')
|
||||
.expect(200, ' - Tobi\n - Loki\n - Jane\n', done)
|
||||
})
|
||||
|
||||
it('should accept to application/json', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -18,6 +18,35 @@ describe('cookies', function(){
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should respond to cookie', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Cookie', res.headers['set-cookie'][0])
|
||||
.expect(200, /Remembered/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /forget', function(){
|
||||
it('should clear cookie', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/forget')
|
||||
.set('Cookie', res.headers['set-cookie'][0])
|
||||
.expect('Set-Cookie', /remember=;/)
|
||||
.expect(302, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /', function(){
|
||||
@ -25,10 +54,20 @@ describe('cookies', function(){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.end(function(err, res){
|
||||
.expect(302, function(err, res){
|
||||
res.headers.should.have.property('set-cookie')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should no set cookie w/o reminder', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({})
|
||||
.expect(302, function(err, res){
|
||||
res.headers.should.not.have.property('set-cookie')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -7,10 +7,38 @@ describe('mvc', function(){
|
||||
it('should redirect to /users', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Location', '/users')
|
||||
.expect(302, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /pet/0', function(){
|
||||
it('should get pet', function(done){
|
||||
request(app)
|
||||
.get('/pet/0')
|
||||
.expect(200, /Tobi/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /pet/0/edit', function(){
|
||||
it('should get pet edit page', function(done){
|
||||
request(app)
|
||||
.get('/pet/0/edit')
|
||||
.expect(/<form/)
|
||||
.expect(200, /Tobi/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('PUT /pet/2', function(){
|
||||
it('should update the pet', function(done){
|
||||
request(app)
|
||||
.put('/pet/3')
|
||||
.send({ pet: { name: 'Boots' } })
|
||||
.end(function(err, res){
|
||||
res.should.have.status(302);
|
||||
res.headers.location.should.include('/users');
|
||||
done();
|
||||
if (err) return done(err);
|
||||
request(app)
|
||||
.get('/pet/3/edit')
|
||||
.expect(200, /Boots/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -65,11 +93,8 @@ describe('mvc', function(){
|
||||
it('should display the edit form', function(done){
|
||||
request(app)
|
||||
.get('/user/1/edit')
|
||||
.end(function(err, res){
|
||||
res.text.should.include('<h1>Guillermo</h1>');
|
||||
res.text.should.include('value="put"');
|
||||
done();
|
||||
})
|
||||
.expect(/Guillermo/)
|
||||
.expect(200, /<form/, done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -79,13 +104,26 @@ describe('mvc', function(){
|
||||
.put('/user/1')
|
||||
.send({ user: { name: 'Tobo' }})
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
request(app)
|
||||
.get('/user/1/edit')
|
||||
.end(function(err, res){
|
||||
res.text.should.include('<h1>Tobo</h1>');
|
||||
done();
|
||||
})
|
||||
.expect(200, /Tobo/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /user/:id/pet', function(){
|
||||
it('should create a pet for user', function(done){
|
||||
request(app)
|
||||
.post('/user/2/pet')
|
||||
.send({ pet: { name: 'Snickers' }})
|
||||
.expect('Location', '/user/2')
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/user/2')
|
||||
.expect(200, /Snickers/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -24,11 +24,72 @@ describe('web-service', function(){
|
||||
it('should respond users json', function(done){
|
||||
request(app)
|
||||
.get('/api/users?api-key=foo')
|
||||
.end(function(err, res){
|
||||
res.should.be.json;
|
||||
res.text.should.equal('[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/repos', function(){
|
||||
describe('without an api key', function(){
|
||||
it('should respond with 400 bad request', function(done){
|
||||
request(app)
|
||||
.get('/api/repos')
|
||||
.expect(400, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid api key', function(){
|
||||
it('should respond with 401 unauthorized', function(done){
|
||||
request(app)
|
||||
.get('/api/repos?api-key=rawr')
|
||||
.expect(401, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid api key', function(){
|
||||
it('should respond repos json', function(done){
|
||||
request(app)
|
||||
.get('/api/repos?api-key=foo')
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(/"name":"express"/)
|
||||
.expect(/"url":"http:\/\/github.com\/visionmedia\/express"/)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/user/:name/repos', function(){
|
||||
describe('without an api key', function(){
|
||||
it('should respond with 400 bad request', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos')
|
||||
.expect(400, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid api key', function(){
|
||||
it('should respond with 401 unauthorized', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos?api-key=rawr')
|
||||
.expect(401, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid api key', function(){
|
||||
it('should respond user repos json', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos?api-key=foo')
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(/"name":"stylus"/)
|
||||
.expect(/"url":"http:\/\/github.com\/learnboost\/stylus"/)
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
it('should 404 with unknown user', function(done){
|
||||
request(app)
|
||||
.get('/api/user/bob/repos?api-key=foo')
|
||||
.expect(404, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -45,4 +106,4 @@ describe('web-service', function(){
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -84,3 +84,12 @@ describe('in production', function(){
|
||||
process.env.NODE_ENV = 'test';
|
||||
})
|
||||
})
|
||||
|
||||
describe('without NODE_ENV', function(){
|
||||
it('should default to development', function(){
|
||||
process.env.NODE_ENV = '';
|
||||
var app = express();
|
||||
app.get('env').should.equal('development');
|
||||
process.env.NODE_ENV = 'test';
|
||||
})
|
||||
})
|
||||
|
@ -37,6 +37,11 @@ describe('app', function(){
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
it('should fail if not given fn', function(){
|
||||
var app = express();
|
||||
app.param.bind(app, ':name', 'bob').should.throw();
|
||||
})
|
||||
})
|
||||
|
||||
describe('.param(names, fn)', function(){
|
||||
@ -151,5 +156,43 @@ describe('app', function(){
|
||||
.get('/foo/bob')
|
||||
.expect('2 2 foo,bob', done);
|
||||
})
|
||||
|
||||
it('should catch thrown error', function(done){
|
||||
var app = express();
|
||||
|
||||
app.param('id', function(req, res, next, id){
|
||||
throw new Error('err!');
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res){
|
||||
var id = req.params.id;
|
||||
res.send('' + id);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/123')
|
||||
.expect(500, done);
|
||||
})
|
||||
|
||||
it('should defer to next route', function(done){
|
||||
var app = express();
|
||||
|
||||
app.param('id', function(req, res, next, id){
|
||||
next('route');
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res){
|
||||
var id = req.params.id;
|
||||
res.send('' + id);
|
||||
});
|
||||
|
||||
app.get('/:name/123', function(req, res){
|
||||
res.send('name');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/123')
|
||||
.expect('name', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -54,6 +54,27 @@ describe('app', function(){
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle render error throws', function(done){
|
||||
var app = express();
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fale';
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
throw new Error('err!');
|
||||
};
|
||||
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
err.should.be.ok;
|
||||
err.message.should.equal('err!');
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the file does not exist', function(){
|
||||
it('should provide a helpful error', function(done){
|
||||
var app = express();
|
||||
@ -132,6 +153,68 @@ describe('app', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('caching', function(){
|
||||
it('should always lookup view without cache', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', false);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(2);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should cache with "view cache" setting', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', true);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.render(name, options, fn)', function(){
|
||||
@ -175,5 +258,37 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('caching', function(){
|
||||
it('should cache with cache option', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', false);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', {cache: true}, function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', {cache: true}, function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
36
test/req.acceptsEncoding.js
Normal file
36
test/req.acceptsEncoding.js
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('supertest');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.acceptsEncodings', function(){
|
||||
it('should be true if encoding accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsEncoding('gzip').should.be.ok;
|
||||
req.acceptsEncoding('deflate').should.be.ok;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Encoding', ' gzip, deflate')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should be false if encoding not accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsEncoding('bogus').should.not.be.ok;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Encoding', ' gzip, deflate')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
53
test/req.acceptsLanguage.js
Normal file
53
test/req.acceptsLanguage.js
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('supertest');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.acceptsLanguage', function(){
|
||||
it('should be true if language accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('en-us').should.be.ok;
|
||||
req.acceptsLanguage('en').should.be.ok;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Language', 'en;q=.5, en-us')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should be false if language not accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('es').should.not.be.ok;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Language', 'en;q=.5, en-us')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
describe('when Accept-Language is not present', function(){
|
||||
it('should always return true', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('en').should.be.ok;
|
||||
req.acceptsLanguage('es').should.be.ok;
|
||||
req.acceptsLanguage('jp').should.be.ok;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -1,5 +1,6 @@
|
||||
|
||||
var express = require('../');
|
||||
var assert = require('assert');
|
||||
var express = require('..');
|
||||
|
||||
function req(ret) {
|
||||
return {
|
||||
@ -27,5 +28,11 @@ describe('req', function(){
|
||||
ret.type = 'users';
|
||||
req('users=0-').range(Infinity).should.eql(ret);
|
||||
})
|
||||
|
||||
it('should return undefined if no range', function(){
|
||||
var ret = [{ start: 0, end: 50 }, { start: 60, end: 100 }];
|
||||
ret.type = 'bytes';
|
||||
assert(req('').range(120) === undefined);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -36,7 +36,7 @@ describe('res', function(){
|
||||
|
||||
app.use(function(req, res){
|
||||
res.attachment('/path/to/image.png');
|
||||
res.send('foo');
|
||||
res.send(new Buffer(4));
|
||||
});
|
||||
|
||||
request(app)
|
||||
|
@ -27,7 +27,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/vnd.example+json')
|
||||
.expect('Content-Type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done);
|
||||
})
|
||||
|
||||
@ -41,11 +41,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
|
||||
it('should respond with json for Number', function(done){
|
||||
@ -57,12 +54,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('300');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '300', done)
|
||||
})
|
||||
|
||||
it('should respond with json for String', function(done){
|
||||
@ -74,12 +67,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('"str"');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '"str"', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -93,11 +82,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('["foo","bar","baz"]');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '["foo","bar","baz"]', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -111,11 +97,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -135,10 +118,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -159,10 +140,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{\n "name": "tobi",\n "age": 2\n}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{\n "name": "tobi",\n "age": 2\n}', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -177,12 +156,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -196,12 +171,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
|
||||
it('should use status as second number for backwards compat', function(done){
|
||||
@ -213,12 +184,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('200');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '200', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -46,11 +46,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/?callback[a]=something')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"count":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"count":1}', done)
|
||||
})
|
||||
|
||||
it('should allow renaming callback', function(done){
|
||||
@ -129,7 +126,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/vnd.example+json')
|
||||
.expect('Content-Type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done);
|
||||
})
|
||||
|
||||
@ -157,11 +154,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -175,11 +169,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('["foo","bar","baz"]');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '["foo","bar","baz"]', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -193,11 +184,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -211,11 +199,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
|
||||
it('should respond with json for Number', function(done){
|
||||
@ -227,12 +212,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('300');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '300', done)
|
||||
})
|
||||
|
||||
it('should respond with json for String', function(done){
|
||||
@ -244,12 +225,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('"str"');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '"str"', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -269,10 +246,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -293,10 +268,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{\n "name": "tobi",\n "age": 2\n}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{\n "name": "tobi",\n "age": 2\n}', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -311,12 +284,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@ -330,12 +299,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
|
||||
it('should use status as second number for backwards compat', function(done){
|
||||
@ -347,12 +312,22 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('200');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '200', done)
|
||||
})
|
||||
})
|
||||
|
||||
it('should not override previous Content-Types', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.type('application/vnd.example+json');
|
||||
res.jsonp({ hello: 'world' });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('content-type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done)
|
||||
})
|
||||
})
|
||||
|
@ -140,8 +140,33 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||
.expect('hey')
|
||||
.expect(200, done);
|
||||
.expect(200, 'hey', done);
|
||||
})
|
||||
|
||||
it('should override charset in Content-Type', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send('hey');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||
.expect(200, 'hey', done);
|
||||
})
|
||||
|
||||
it('should keep charset in Content-Type for Buffers', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send(new Buffer('hi'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain; charset=iso-8859-1')
|
||||
.expect(200, 'hi', done);
|
||||
})
|
||||
})
|
||||
|
||||
@ -205,11 +230,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user