build: Node.js@12.3
[express.git] / test / app.use.js
blob347937fbb3b1c15ec65a04be8f0e54cd1d8eba57
2 var after = require('after');
3 var assert = require('assert')
4 var express = require('..');
5 var request = require('supertest');
7 describe('app', function(){
8   it('should emit "mount" when mounted', function(done){
9     var blog = express()
10       , app = express();
12     blog.on('mount', function(arg){
13       arg.should.equal(app);
14       done();
15     });
17     app.use(blog);
18   })
20   describe('.use(app)', function(){
21     it('should mount the app', function(done){
22       var blog = express()
23         , app = express();
25       blog.get('/blog', function(req, res){
26         res.end('blog');
27       });
29       app.use(blog);
31       request(app)
32       .get('/blog')
33       .expect('blog', done);
34     })
36     it('should support mount-points', function(done){
37       var blog = express()
38         , forum = express()
39         , app = express();
41       blog.get('/', function(req, res){
42         res.end('blog');
43       });
45       forum.get('/', function(req, res){
46         res.end('forum');
47       });
49       app.use('/blog', blog);
50       app.use('/forum', forum);
52       request(app)
53       .get('/blog')
54       .expect('blog', function(){
55         request(app)
56         .get('/forum')
57         .expect('forum', done);
58       });
59     })
61     it('should set the child\'s .parent', function(){
62       var blog = express()
63         , app = express();
65       app.use('/blog', blog);
66       blog.parent.should.equal(app);
67     })
69     it('should support dynamic routes', function(done){
70       var blog = express()
71         , app = express();
73       blog.get('/', function(req, res){
74         res.end('success');
75       });
77       app.use('/post/:article', blog);
79       request(app)
80       .get('/post/once-upon-a-time')
81       .expect('success', done);
82     })
84     it('should support mounted app anywhere', function(done){
85       var cb = after(3, done);
86       var blog = express()
87         , other = express()
88         , app = express();
90       function fn1(req, res, next) {
91         res.setHeader('x-fn-1', 'hit');
92         next();
93       }
95       function fn2(req, res, next) {
96         res.setHeader('x-fn-2', 'hit');
97         next();
98       }
100       blog.get('/', function(req, res){
101         res.end('success');
102       });
104       blog.once('mount', function (parent) {
105         parent.should.equal(app);
106         cb();
107       });
108       other.once('mount', function (parent) {
109         parent.should.equal(app);
110         cb();
111       });
113       app.use('/post/:article', fn1, other, fn2, blog);
115       request(app)
116       .get('/post/once-upon-a-time')
117       .expect('x-fn-1', 'hit')
118       .expect('x-fn-2', 'hit')
119       .expect('success', cb);
120     })
121   })
123   describe('.use(middleware)', function(){
124     it('should accept multiple arguments', function (done) {
125       var app = express();
127       function fn1(req, res, next) {
128         res.setHeader('x-fn-1', 'hit');
129         next();
130       }
132       function fn2(req, res, next) {
133         res.setHeader('x-fn-2', 'hit');
134         next();
135       }
137       app.use(fn1, fn2, function fn3(req, res) {
138         res.setHeader('x-fn-3', 'hit');
139         res.end();
140       });
142       request(app)
143       .get('/')
144       .expect('x-fn-1', 'hit')
145       .expect('x-fn-2', 'hit')
146       .expect('x-fn-3', 'hit')
147       .expect(200, done);
148     })
150     it('should invoke middleware for all requests', function (done) {
151       var app = express();
152       var cb = after(3, done);
154       app.use(function (req, res) {
155         res.send('saw ' + req.method + ' ' + req.url);
156       });
158       request(app)
159       .get('/')
160       .expect(200, 'saw GET /', cb);
162       request(app)
163       .options('/')
164       .expect(200, 'saw OPTIONS /', cb);
166       request(app)
167       .post('/foo')
168       .expect(200, 'saw POST /foo', cb);
169     })
171     it('should accept array of middleware', function (done) {
172       var app = express();
174       function fn1(req, res, next) {
175         res.setHeader('x-fn-1', 'hit');
176         next();
177       }
179       function fn2(req, res, next) {
180         res.setHeader('x-fn-2', 'hit');
181         next();
182       }
184       function fn3(req, res, next) {
185         res.setHeader('x-fn-3', 'hit');
186         res.end();
187       }
189       app.use([fn1, fn2, fn3]);
191       request(app)
192       .get('/')
193       .expect('x-fn-1', 'hit')
194       .expect('x-fn-2', 'hit')
195       .expect('x-fn-3', 'hit')
196       .expect(200, done);
197     })
199     it('should accept multiple arrays of middleware', function (done) {
200       var app = express();
202       function fn1(req, res, next) {
203         res.setHeader('x-fn-1', 'hit');
204         next();
205       }
207       function fn2(req, res, next) {
208         res.setHeader('x-fn-2', 'hit');
209         next();
210       }
212       function fn3(req, res, next) {
213         res.setHeader('x-fn-3', 'hit');
214         res.end();
215       }
217       app.use([fn1, fn2], [fn3]);
219       request(app)
220       .get('/')
221       .expect('x-fn-1', 'hit')
222       .expect('x-fn-2', 'hit')
223       .expect('x-fn-3', 'hit')
224       .expect(200, done);
225     })
227     it('should accept nested arrays of middleware', function (done) {
228       var app = express();
230       function fn1(req, res, next) {
231         res.setHeader('x-fn-1', 'hit');
232         next();
233       }
235       function fn2(req, res, next) {
236         res.setHeader('x-fn-2', 'hit');
237         next();
238       }
240       function fn3(req, res, next) {
241         res.setHeader('x-fn-3', 'hit');
242         res.end();
243       }
245       app.use([[fn1], fn2], [fn3]);
247       request(app)
248       .get('/')
249       .expect('x-fn-1', 'hit')
250       .expect('x-fn-2', 'hit')
251       .expect('x-fn-3', 'hit')
252       .expect(200, done);
253     })
254   })
256   describe('.use(path, middleware)', function(){
257     it('should require middleware', function () {
258       var app = express()
259       assert.throws(function () { app.use('/') }, /requires a middleware function/)
260     })
262     it('should reject string as middleware', function () {
263       var app = express()
264       assert.throws(function () { app.use('/', 'foo') }, /requires a middleware function but got a string/)
265     })
267     it('should reject number as middleware', function () {
268       var app = express()
269       assert.throws(function () { app.use('/', 42) }, /requires a middleware function but got a number/)
270     })
272     it('should reject null as middleware', function () {
273       var app = express()
274       assert.throws(function () { app.use('/', null) }, /requires a middleware function but got a Null/)
275     })
277     it('should reject Date as middleware', function () {
278       var app = express()
279       assert.throws(function () { app.use('/', new Date()) }, /requires a middleware function but got a Date/)
280     })
282     it('should strip path from req.url', function (done) {
283       var app = express();
285       app.use('/foo', function (req, res) {
286         res.send('saw ' + req.method + ' ' + req.url);
287       });
289       request(app)
290       .get('/foo/bar')
291       .expect(200, 'saw GET /bar', done);
292     })
294     it('should accept multiple arguments', function (done) {
295       var app = express();
297       function fn1(req, res, next) {
298         res.setHeader('x-fn-1', 'hit');
299         next();
300       }
302       function fn2(req, res, next) {
303         res.setHeader('x-fn-2', 'hit');
304         next();
305       }
307       app.use('/foo', fn1, fn2, function fn3(req, res) {
308         res.setHeader('x-fn-3', 'hit');
309         res.end();
310       });
312       request(app)
313       .get('/foo')
314       .expect('x-fn-1', 'hit')
315       .expect('x-fn-2', 'hit')
316       .expect('x-fn-3', 'hit')
317       .expect(200, done);
318     })
320     it('should invoke middleware for all requests starting with path', function (done) {
321       var app = express();
322       var cb = after(3, done);
324       app.use('/foo', function (req, res) {
325         res.send('saw ' + req.method + ' ' + req.url);
326       });
328       request(app)
329       .get('/')
330       .expect(404, cb);
332       request(app)
333       .post('/foo')
334       .expect(200, 'saw POST /', cb);
336       request(app)
337       .post('/foo/bar')
338       .expect(200, 'saw POST /bar', cb);
339     })
341     it('should work if path has trailing slash', function (done) {
342       var app = express();
343       var cb = after(3, done);
345       app.use('/foo/', function (req, res) {
346         res.send('saw ' + req.method + ' ' + req.url);
347       });
349       request(app)
350       .get('/')
351       .expect(404, cb);
353       request(app)
354       .post('/foo')
355       .expect(200, 'saw POST /', cb);
357       request(app)
358       .post('/foo/bar')
359       .expect(200, 'saw POST /bar', cb);
360     })
362     it('should accept array of middleware', function (done) {
363       var app = express();
365       function fn1(req, res, next) {
366         res.setHeader('x-fn-1', 'hit');
367         next();
368       }
370       function fn2(req, res, next) {
371         res.setHeader('x-fn-2', 'hit');
372         next();
373       }
375       function fn3(req, res, next) {
376         res.setHeader('x-fn-3', 'hit');
377         res.end();
378       }
380       app.use('/foo', [fn1, fn2, fn3]);
382       request(app)
383       .get('/foo')
384       .expect('x-fn-1', 'hit')
385       .expect('x-fn-2', 'hit')
386       .expect('x-fn-3', 'hit')
387       .expect(200, done);
388     })
390     it('should accept multiple arrays of middleware', function (done) {
391       var app = express();
393       function fn1(req, res, next) {
394         res.setHeader('x-fn-1', 'hit');
395         next();
396       }
398       function fn2(req, res, next) {
399         res.setHeader('x-fn-2', 'hit');
400         next();
401       }
403       function fn3(req, res, next) {
404         res.setHeader('x-fn-3', 'hit');
405         res.end();
406       }
408       app.use('/foo', [fn1, fn2], [fn3]);
410       request(app)
411       .get('/foo')
412       .expect('x-fn-1', 'hit')
413       .expect('x-fn-2', 'hit')
414       .expect('x-fn-3', 'hit')
415       .expect(200, done);
416     })
418     it('should accept nested arrays of middleware', function (done) {
419       var app = express();
421       function fn1(req, res, next) {
422         res.setHeader('x-fn-1', 'hit');
423         next();
424       }
426       function fn2(req, res, next) {
427         res.setHeader('x-fn-2', 'hit');
428         next();
429       }
431       function fn3(req, res, next) {
432         res.setHeader('x-fn-3', 'hit');
433         res.end();
434       }
436       app.use('/foo', [fn1, [fn2]], [fn3]);
438       request(app)
439       .get('/foo')
440       .expect('x-fn-1', 'hit')
441       .expect('x-fn-2', 'hit')
442       .expect('x-fn-3', 'hit')
443       .expect(200, done);
444     })
446     it('should support array of paths', function (done) {
447       var app = express();
448       var cb = after(3, done);
450       app.use(['/foo/', '/bar'], function (req, res) {
451         res.send('saw ' + req.method + ' ' + req.url + ' through ' + req.originalUrl);
452       });
454       request(app)
455       .get('/')
456       .expect(404, cb);
458       request(app)
459       .get('/foo')
460       .expect(200, 'saw GET / through /foo', cb);
462       request(app)
463       .get('/bar')
464       .expect(200, 'saw GET / through /bar', cb);
465     })
467     it('should support array of paths with middleware array', function (done) {
468       var app = express();
469       var cb = after(2, done);
471       function fn1(req, res, next) {
472         res.setHeader('x-fn-1', 'hit');
473         next();
474       }
476       function fn2(req, res, next) {
477         res.setHeader('x-fn-2', 'hit');
478         next();
479       }
481       function fn3(req, res, next) {
482         res.setHeader('x-fn-3', 'hit');
483         res.send('saw ' + req.method + ' ' + req.url + ' through ' + req.originalUrl);
484       }
486       app.use(['/foo/', '/bar'], [[fn1], fn2], [fn3]);
488       request(app)
489       .get('/foo')
490       .expect('x-fn-1', 'hit')
491       .expect('x-fn-2', 'hit')
492       .expect('x-fn-3', 'hit')
493       .expect(200, 'saw GET / through /foo', cb);
495       request(app)
496       .get('/bar')
497       .expect('x-fn-1', 'hit')
498       .expect('x-fn-2', 'hit')
499       .expect('x-fn-3', 'hit')
500       .expect(200, 'saw GET / through /bar', cb);
501     })
503     it('should support regexp path', function (done) {
504       var app = express();
505       var cb = after(4, done);
507       app.use(/^\/[a-z]oo/, function (req, res) {
508         res.send('saw ' + req.method + ' ' + req.url + ' through ' + req.originalUrl);
509       });
511       request(app)
512       .get('/')
513       .expect(404, cb);
515       request(app)
516       .get('/foo')
517       .expect(200, 'saw GET / through /foo', cb);
519       request(app)
520       .get('/zoo/bear')
521       .expect(200, 'saw GET /bear through /zoo/bear', cb);
523       request(app)
524       .get('/get/zoo')
525       .expect(404, cb);
526     })
528     it('should support empty string path', function (done) {
529       var app = express();
531       app.use('', function (req, res) {
532         res.send('saw ' + req.method + ' ' + req.url + ' through ' + req.originalUrl);
533       });
535       request(app)
536       .get('/')
537       .expect(200, 'saw GET / through /', done);
538     })
539   })