Use let or const to avoid scope issues and hoisting
var assert = require('node:assert')
1'use strict'23var assert = require('node:assert')4const { Buffer } = require('node:buffer');5var express = require('..');6var methods = require('../lib/utils').methods;7var request = require('supertest');8var utils = require('./support/utils');910var shouldSkipQuery = require('./support/utils').shouldSkipQuery1112describe('res', function(){13 describe('.send()', function(){14 it('should set body to ""', function(done){15 var app = express();1617 app.use(function(req, res){18 res.send();19 });2021 request(app)22 .get('/')23 .expect(200, '', done);24 })25 })2627 describe('.send(null)', function(){28 it('should set body to ""', function(done){29 var app = express();3031 app.use(function(req, res){32 res.send(null);33 });3435 request(app)36 .get('/')37 .expect('Content-Length', '0')38 .expect(200, '', done);39 })40 })4142 describe('.send(undefined)', function(){43 it('should set body to ""', function(done){44 var app = express();4546 app.use(function(req, res){47 res.send(undefined);48 });4950 request(app)51 .get('/')52 .expect(200, '', done);53 })54 })5556 describe('.send(Number)', function(){57 it('should send as application/json', function(done){58 var app = express();5960 app.use(function(req, res){61 res.send(1000);62 });6364 request(app)65 .get('/')66 .expect('Content-Type', 'application/json; charset=utf-8')67 .expect(200, '1000', done)68 })69 })7071 describe('.send(String)', function(){72 it('should send as html', function(done){73 var app = express();7475 app.use(function(req, res){76 res.send('<p>hey</p>');77 });7879 request(app)80 .get('/')81 .expect('Content-Type', 'text/html; charset=utf-8')82 .expect(200, '<p>hey</p>', done);83 })8485 it('should set ETag', function (done) {86 var app = express();8788 app.use(function (req, res) {89 var str = Array(1000).join('-');90 res.send(str);91 });9293 request(app)94 .get('/')95 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')96 .expect(200, done);97 })9899 it('should not override Content-Type', function(done){100 var app = express();101102 app.use(function(req, res){103 res.set('Content-Type', 'text/plain').send('hey');104 });105106 request(app)107 .get('/')108 .expect('Content-Type', 'text/plain; charset=utf-8')109 .expect(200, 'hey', done);110 })111112 it('should override charset in Content-Type', function(done){113 var app = express();114115 app.use(function(req, res){116 res.set('Content-Type', 'text/plain; charset=iso-8859-1').send('hey');117 });118119 request(app)120 .get('/')121 .expect('Content-Type', 'text/plain; charset=utf-8')122 .expect(200, 'hey', done);123 })124125 it('should preserve existing parameters when adding charset', function(done){126 var app = express();127128 app.use(function(req, res){129 res.set('Content-Type', 'text/plain; foo=bar').send('hey');130 });131132 request(app)133 .get('/')134 .expect('Content-Type', 'text/plain; foo=bar; charset=utf-8')135 .expect(200, 'hey', done);136 })137138 it('should not throw on a Content-Type that fails to parse', function(done){139 var app = express();140141 app.use(function(req, res){142 res.set('Content-Type', 'text/plain; foo').send('hey');143 });144145 request(app)146 .get('/')147 .expect('Content-Type', 'text/plain; charset=utf-8')148 .expect(200, 'hey', done);149 })150151 it('should keep charset in Content-Type for Buffers', function(done){152 var app = express();153154 app.use(function(req, res){155 res.set('Content-Type', 'text/plain; charset=iso-8859-1').send(Buffer.from('hi'))156 });157158 request(app)159 .get('/')160 .expect('Content-Type', 'text/plain; charset=iso-8859-1')161 .expect(200, 'hi', done);162 })163 })164165 describe('.send(Buffer)', function(){166 it('should send as octet-stream', function(done){167 var app = express();168169 app.use(function(req, res){170 res.send(Buffer.from('hello'))171 });172173 request(app)174 .get('/')175 .expect(200)176 .expect('Content-Type', 'application/octet-stream')177 .expect(utils.shouldHaveBody(Buffer.from('hello')))178 .end(done)179 })180181 it('should set ETag', function (done) {182 var app = express();183184 app.use(function (req, res) {185 res.send(Buffer.alloc(999, '-'))186 });187188 request(app)189 .get('/')190 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')191 .expect(200, done);192 })193194 it('should not override Content-Type', function(done){195 var app = express();196197 app.use(function(req, res){198 res.set('Content-Type', 'text/plain').send(Buffer.from('hey'))199 });200201 request(app)202 .get('/')203 .expect('Content-Type', 'text/plain; charset=utf-8')204 .expect(200, 'hey', done);205 })206207 it('should accept Uint8Array', function(done){208 var app = express();209 app.use(function(req, res){210 const encodedHey = new TextEncoder().encode("hey");211 res.set("Content-Type", "text/plain").send(encodedHey);212 })213214 request(app)215 .get("/")216 .expect("Content-Type", "text/plain; charset=utf-8")217 .expect(200, "hey", done);218 })219220 it('should not override ETag', function (done) {221 var app = express()222223 app.use(function (req, res) {224 res.type('text/plain').set('ETag', '"foo"').send(Buffer.from('hey'))225 })226227 request(app)228 .get('/')229 .expect('ETag', '"foo"')230 .expect(200, 'hey', done)231 })232 })233234 describe('.send(Object)', function(){235 it('should send as application/json', function(done){236 var app = express();237238 app.use(function(req, res){239 res.send({ name: 'tobi' });240 });241242 request(app)243 .get('/')244 .expect('Content-Type', 'application/json; charset=utf-8')245 .expect(200, '{"name":"tobi"}', done)246 })247 })248249 describe('when the request method is HEAD', function(){250 it('should ignore the body', function(done){251 var app = express();252253 app.use(function(req, res){254 res.send('yay');255 });256257 request(app)258 .head('/')259 .expect(200)260 .expect(utils.shouldNotHaveBody())261 .end(done)262 })263 })264265 describe('when .statusCode is 204', function(){266 it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){267 var app = express();268269 app.use(function(req, res){270 res.status(204).set('Transfer-Encoding', 'chunked').send('foo');271 });272273 request(app)274 .get('/')275 .expect(utils.shouldNotHaveHeader('Content-Type'))276 .expect(utils.shouldNotHaveHeader('Content-Length'))277 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))278 .expect(204, '', done);279 })280 })281282 describe('when .statusCode is 205', function () {283 it('should strip Transfer-Encoding field and body, set Content-Length', function (done) {284 var app = express()285286 app.use(function (req, res) {287 res.status(205).set('Transfer-Encoding', 'chunked').send('foo')288 })289290 request(app)291 .get('/')292 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))293 .expect('Content-Length', '0')294 .expect(205, '', done)295 })296 })297298 describe('when .statusCode is 304', function(){299 it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){300 var app = express();301302 app.use(function(req, res){303 res.status(304).set('Transfer-Encoding', 'chunked').send('foo');304 });305306 request(app)307 .get('/')308 .expect(utils.shouldNotHaveHeader('Content-Type'))309 .expect(utils.shouldNotHaveHeader('Content-Length'))310 .expect(utils.shouldNotHaveHeader('Transfer-Encoding'))311 .expect(304, '', done);312 })313 })314315 it('should always check regardless of length', function(done){316 var app = express();317 var etag = '"asdf"';318319 app.use(function(req, res, next){320 res.set('ETag', etag);321 res.send('hey');322 });323324 request(app)325 .get('/')326 .set('If-None-Match', etag)327 .expect(304, done);328 })329330 it('should respond with 304 Not Modified when fresh', function(done){331 var app = express();332 var etag = '"asdf"';333334 app.use(function(req, res){335 var str = Array(1000).join('-');336 res.set('ETag', etag);337 res.send(str);338 });339340 request(app)341 .get('/')342 .set('If-None-Match', etag)343 .expect(304, done);344 })345346 it('should not perform freshness check unless 2xx or 304', function(done){347 var app = express();348 var etag = '"asdf"';349350 app.use(function(req, res, next){351 res.status(500);352 res.set('ETag', etag);353 res.send('hey');354 });355356 request(app)357 .get('/')358 .set('If-None-Match', etag)359 .expect('hey')360 .expect(500, done);361 })362363 it('should not support jsonp callbacks', function(done){364 var app = express();365366 app.use(function(req, res){367 res.send({ foo: 'bar' });368 });369370 request(app)371 .get('/?callback=foo')372 .expect('{"foo":"bar"}', done);373 })374375 it('should be chainable', function (done) {376 var app = express()377378 app.use(function (req, res) {379 assert.equal(res.send('hey'), res)380 })381382 request(app)383 .get('/')384 .expect(200, 'hey', done)385 })386387 describe('"etag" setting', function () {388 describe('when enabled', function () {389 it('should send ETag', function (done) {390 var app = express();391392 app.use(function (req, res) {393 res.send('kajdslfkasdf');394 });395396 app.enable('etag');397398 request(app)399 .get('/')400 .expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')401 .expect(200, done);402 });403404 methods.forEach(function (method) {405 if (method === 'connect') return;406407 it('should send ETag in response to ' + method.toUpperCase() + ' request', function (done) {408 if (method === 'query' && shouldSkipQuery(process.versions.node)) {409 this.skip()410 }411 var app = express();412413 app[method]('/', function (req, res) {414 res.send('kajdslfkasdf');415 });416417 request(app)418 [method]('/')419 .expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')420 .expect(200, done);421 })422 });423424 it('should send ETag for empty string response', function (done) {425 var app = express();426427 app.use(function (req, res) {428 res.send('');429 });430431 app.enable('etag');432433 request(app)434 .get('/')435 .expect('ETag', 'W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"')436 .expect(200, done);437 })438439 it('should send ETag for long response', function (done) {440 var app = express();441442 app.use(function (req, res) {443 var str = Array(1000).join('-');444 res.send(str);445 });446447 app.enable('etag');448449 request(app)450 .get('/')451 .expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')452 .expect(200, done);453 });454455 it('should not override ETag when manually set', function (done) {456 var app = express();457458 app.use(function (req, res) {459 res.set('etag', '"asdf"');460 res.send('hello!');461 });462463 app.enable('etag');464465 request(app)466 .get('/')467 .expect('ETag', '"asdf"')468 .expect(200, done);469 });470471 it('should not send ETag for res.send()', function (done) {472 var app = express();473474 app.use(function (req, res) {475 res.send();476 });477478 app.enable('etag');479480 request(app)481 .get('/')482 .expect(utils.shouldNotHaveHeader('ETag'))483 .expect(200, done);484 })485 });486487 describe('when disabled', function () {488 it('should send no ETag', function (done) {489 var app = express();490491 app.use(function (req, res) {492 var str = Array(1000).join('-');493 res.send(str);494 });495496 app.disable('etag');497498 request(app)499 .get('/')500 .expect(utils.shouldNotHaveHeader('ETag'))501 .expect(200, done);502 });503504 it('should send ETag when manually set', function (done) {505 var app = express();506507 app.disable('etag');508509 app.use(function (req, res) {510 res.set('etag', '"asdf"');511 res.send('hello!');512 });513514 request(app)515 .get('/')516 .expect('ETag', '"asdf"')517 .expect(200, done);518 });519 });520521 describe('when "strong"', function () {522 it('should send strong ETag', function (done) {523 var app = express();524525 app.set('etag', 'strong');526527 app.use(function (req, res) {528 res.send('hello, world!');529 });530531 request(app)532 .get('/')533 .expect('ETag', '"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')534 .expect(200, done);535 })536 })537538 describe('when "weak"', function () {539 it('should send weak ETag', function (done) {540 var app = express();541542 app.set('etag', 'weak');543544 app.use(function (req, res) {545 res.send('hello, world!');546 });547548 request(app)549 .get('/')550 .expect('ETag', 'W/"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')551 .expect(200, done)552 })553 })554555 describe('when a function', function () {556 it('should send custom ETag', function (done) {557 var app = express();558559 app.set('etag', function (body, encoding) {560 var chunk = !Buffer.isBuffer(body)561 ? Buffer.from(body, encoding)562 : body;563 assert.strictEqual(chunk.toString(), 'hello, world!')564 return '"custom"';565 });566567 app.use(function (req, res) {568 res.send('hello, world!');569 });570571 request(app)572 .get('/')573 .expect('ETag', '"custom"')574 .expect(200, done);575 })576577 it('should not send falsy ETag', function (done) {578 var app = express();579580 app.set('etag', function (body, encoding) {581 return undefined;582 });583584 app.use(function (req, res) {585 res.send('hello, world!');586 });587588 request(app)589 .get('/')590 .expect(utils.shouldNotHaveHeader('ETag'))591 .expect(200, done);592 })593 })594 })595596 describe('when Transfer-Encoding header is present', function(){597 var transferEncodings = [598 'chunked',599 'compress',600 'deflate',601 'gzip'602 ];603604 transferEncodings.forEach(function(encoding){605 it('should not add Content-Length header if Transfer-Encoding header is equal to ' + encoding, function(done){606 var app = express();607608 app.use(function(_, res){609 res.status(200).set('Transfer-Encoding', encoding).send('');610 });611612 request(app)613 .get('/')614 .expect(utils.shouldNotHaveHeader('Content-Length'))615 .expect(utils.shouldHaveHeader('Transfer-Encoding'))616 .expect(200, '', done);617 })618 });619 })620})
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.