3 var assert = require('assert')
4 var Buffer = require('safe-buffer').Buffer
5 var express = require('..');
6 var methods = require('methods');
7 var request = require('supertest');
8 var utils = require('./support/utils');
10 describe('res', function(){
11 describe('.send()', function(){
12 it('should set body to ""', function(done){
15 app.use(function(req, res){
21 .expect(200, '', done);
25 describe('.send(null)', function(){
26 it('should set body to ""', function(done){
29 app.use(function(req, res){
35 .expect('Content-Length', '0')
36 .expect(200, '', done);
40 describe('.send(undefined)', function(){
41 it('should set body to ""', function(done){
44 app.use(function(req, res){
50 .expect(200, '', done);
54 describe('.send(Number)', function(){
55 it('should send as application/json', function(done){
58 app.use(function(req, res){
64 .expect('Content-Type', 'application/json; charset=utf-8')
65 .expect(200, '1000', done)
69 describe('.send(String)', function(){
70 it('should send as html', function(done){
73 app.use(function(req, res){
74 res.send('<p>hey</p>');
79 .expect('Content-Type', 'text/html; charset=utf-8')
80 .expect(200, '<p>hey</p>', done);
83 it('should set ETag', function (done) {
86 app.use(function (req, res) {
87 var str = Array(1000).join('-');
93 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
97 it('should not override Content-Type', function(done){
100 app.use(function(req, res){
101 res.set('Content-Type', 'text/plain').send('hey');
106 .expect('Content-Type', 'text/plain; charset=utf-8')
107 .expect(200, 'hey', done);
110 it('should override charset in Content-Type', function(done){
113 app.use(function(req, res){
114 res.set('Content-Type', 'text/plain; charset=iso-8859-1').send('hey');
119 .expect('Content-Type', 'text/plain; charset=utf-8')
120 .expect(200, 'hey', done);
123 it('should keep charset in Content-Type for Buffers', function(done){
126 app.use(function(req, res){
127 res.set('Content-Type', 'text/plain; charset=iso-8859-1').send(Buffer.from('hi'))
132 .expect('Content-Type', 'text/plain; charset=iso-8859-1')
133 .expect(200, 'hi', done);
137 describe('.send(Buffer)', function(){
138 it('should send as octet-stream', function(done){
141 app.use(function(req, res){
142 res.send(Buffer.from('hello'))
148 .expect('Content-Type', 'application/octet-stream')
149 .expect(utils.shouldHaveBody(Buffer.from('hello')))
153 it('should set ETag', function (done) {
156 app.use(function (req, res) {
157 res.send(Buffer.alloc(999, '-'))
162 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
166 it('should not override Content-Type', function(done){
169 app.use(function(req, res){
170 res.set('Content-Type', 'text/plain').send(Buffer.from('hey'))
175 .expect('Content-Type', 'text/plain; charset=utf-8')
176 .expect(200, 'hey', done);
179 it('should not override ETag', function (done) {
182 app.use(function (req, res) {
183 res.type('text/plain').set('ETag', '"foo"').send(Buffer.from('hey'))
188 .expect('ETag', '"foo"')
189 .expect(200, 'hey', done)
193 describe('.send(Object)', function(){
194 it('should send as application/json', function(done){
197 app.use(function(req, res){
198 res.send({ name: 'tobi' });
203 .expect('Content-Type', 'application/json; charset=utf-8')
204 .expect(200, '{"name":"tobi"}', done)
208 describe('when the request method is HEAD', function(){
209 it('should ignore the body', function(done){
212 app.use(function(req, res){
219 .expect(utils.shouldNotHaveBody())
224 describe('when .statusCode is 204', function(){
225 it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
228 app.use(function(req, res){
229 res.status(204).set('Transfer-Encoding', 'chunked').send('foo');
234 .expect(utils.shouldNotHaveHeader('Content-Type'))
235 .expect(utils.shouldNotHaveHeader('Content-Length'))
236 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
237 .expect(204, '', done);
241 describe('when .statusCode is 205', function () {
242 it('should strip Transfer-Encoding field and body, set Content-Length', function (done) {
245 app.use(function (req, res) {
246 res.status(205).set('Transfer-Encoding', 'chunked').send('foo')
251 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
252 .expect('Content-Length', '0')
253 .expect(205, '', done)
257 describe('when .statusCode is 304', function(){
258 it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
261 app.use(function(req, res){
262 res.status(304).set('Transfer-Encoding', 'chunked').send('foo');
267 .expect(utils.shouldNotHaveHeader('Content-Type'))
268 .expect(utils.shouldNotHaveHeader('Content-Length'))
269 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
270 .expect(304, '', done);
274 it('should always check regardless of length', function(done){
278 app.use(function(req, res, next){
279 res.set('ETag', etag);
285 .set('If-None-Match', etag)
289 it('should respond with 304 Not Modified when fresh', function(done){
293 app.use(function(req, res){
294 var str = Array(1000).join('-');
295 res.set('ETag', etag);
301 .set('If-None-Match', etag)
305 it('should not perform freshness check unless 2xx or 304', function(done){
309 app.use(function(req, res, next){
311 res.set('ETag', etag);
317 .set('If-None-Match', etag)
322 it('should not support jsonp callbacks', function(done){
325 app.use(function(req, res){
326 res.send({ foo: 'bar' });
330 .get('/?callback=foo')
331 .expect('{"foo":"bar"}', done);
334 it('should be chainable', function (done) {
337 app.use(function (req, res) {
338 assert.equal(res.send('hey'), res)
343 .expect(200, 'hey', done)
346 describe('"etag" setting', function () {
347 describe('when enabled', function () {
348 it('should send ETag', function (done) {
351 app.use(function (req, res) {
352 res.send('kajdslfkasdf');
359 .expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')
363 methods.forEach(function (method) {
364 if (method === 'connect') return;
366 it('should send ETag in response to ' + method.toUpperCase() + ' request', function (done) {
369 app[method]('/', function (req, res) {
370 res.send('kajdslfkasdf');
375 .expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')
380 it('should send ETag for empty string response', function (done) {
383 app.use(function (req, res) {
391 .expect('ETag', 'W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"')
395 it('should send ETag for long response', function (done) {
398 app.use(function (req, res) {
399 var str = Array(1000).join('-');
407 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
411 it('should not override ETag when manually set', function (done) {
414 app.use(function (req, res) {
415 res.set('etag', '"asdf"');
423 .expect('ETag', '"asdf"')
427 it('should not send ETag for res.send()', function (done) {
430 app.use(function (req, res) {
438 .expect(utils.shouldNotHaveHeader('ETag'))
443 describe('when disabled', function () {
444 it('should send no ETag', function (done) {
447 app.use(function (req, res) {
448 var str = Array(1000).join('-');
456 .expect(utils.shouldNotHaveHeader('ETag'))
460 it('should send ETag when manually set', function (done) {
465 app.use(function (req, res) {
466 res.set('etag', '"asdf"');
472 .expect('ETag', '"asdf"')
477 describe('when "strong"', function () {
478 it('should send strong ETag', function (done) {
481 app.set('etag', 'strong');
483 app.use(function (req, res) {
484 res.send('hello, world!');
489 .expect('ETag', '"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')
494 describe('when "weak"', function () {
495 it('should send weak ETag', function (done) {
498 app.set('etag', 'weak');
500 app.use(function (req, res) {
501 res.send('hello, world!');
506 .expect('ETag', 'W/"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')
511 describe('when a function', function () {
512 it('should send custom ETag', function (done) {
515 app.set('etag', function (body, encoding) {
516 var chunk = !Buffer.isBuffer(body)
517 ? Buffer.from(body, encoding)
519 assert.strictEqual(chunk.toString(), 'hello, world!')
523 app.use(function (req, res) {
524 res.send('hello, world!');
529 .expect('ETag', '"custom"')
533 it('should not send falsy ETag', function (done) {
536 app.set('etag', function (body, encoding) {
540 app.use(function (req, res) {
541 res.send('hello, world!');
546 .expect(utils.shouldNotHaveHeader('ETag'))