build: Node.js@12.3
[express.git] / test / app.param.js
blob8785567751f3744aee97d9580800a0879e44133d
2 var express = require('../')
3   , request = require('supertest');
5 describe('app', function(){
6   describe('.param(fn)', function(){
7     it('should map app.param(name, ...) logic', function(done){
8       var app = express();
10       app.param(function(name, regexp){
11         if (Object.prototype.toString.call(regexp) === '[object RegExp]') { // See #1557
12           return function(req, res, next, val){
13             var captures;
14             if (captures = regexp.exec(String(val))) {
15               req.params[name] = captures[1];
16               next();
17             } else {
18               next('route');
19             }
20           }
21         }
22       })
24       app.param(':name', /^([a-zA-Z]+)$/);
26       app.get('/user/:name', function(req, res){
27         res.send(req.params.name);
28       });
30       request(app)
31       .get('/user/tj')
32       .expect(200, 'tj', function (err) {
33         if (err) return done(err)
34         request(app)
35         .get('/user/123')
36         .expect(404, done);
37       });
39     })
41     it('should fail if not given fn', function(){
42       var app = express();
43       app.param.bind(app, ':name', 'bob').should.throw();
44     })
45   })
47   describe('.param(names, fn)', function(){
48     it('should map the array', function(done){
49       var app = express();
51       app.param(['id', 'uid'], function(req, res, next, id){
52         id = Number(id);
53         if (isNaN(id)) return next('route');
54         req.params.id = id;
55         next();
56       });
58       app.get('/post/:id', function(req, res){
59         var id = req.params.id;
60         id.should.be.a.Number()
61         res.send('' + id);
62       });
64       app.get('/user/:uid', function(req, res){
65         var id = req.params.id;
66         id.should.be.a.Number()
67         res.send('' + id);
68       });
70       request(app)
71       .get('/user/123')
72       .expect(200, '123', function (err) {
73         if (err) return done(err)
74         request(app)
75         .get('/post/123')
76         .expect('123', done);
77       })
78     })
79   })
81   describe('.param(name, fn)', function(){
82     it('should map logic for a single param', function(done){
83       var app = express();
85       app.param('id', function(req, res, next, id){
86         id = Number(id);
87         if (isNaN(id)) return next('route');
88         req.params.id = id;
89         next();
90       });
92       app.get('/user/:id', function(req, res){
93         var id = req.params.id;
94         id.should.be.a.Number()
95         res.send('' + id);
96       });
98       request(app)
99       .get('/user/123')
100       .expect('123', done);
101     })
103     it('should only call once per request', function(done) {
104       var app = express();
105       var called = 0;
106       var count = 0;
108       app.param('user', function(req, res, next, user) {
109         called++;
110         req.user = user;
111         next();
112       });
114       app.get('/foo/:user', function(req, res, next) {
115         count++;
116         next();
117       });
118       app.get('/foo/:user', function(req, res, next) {
119         count++;
120         next();
121       });
122       app.use(function(req, res) {
123         res.end([count, called, req.user].join(' '));
124       });
126       request(app)
127       .get('/foo/bob')
128       .expect('2 1 bob', done);
129     })
131     it('should call when values differ', function(done) {
132       var app = express();
133       var called = 0;
134       var count = 0;
136       app.param('user', function(req, res, next, user) {
137         called++;
138         req.users = (req.users || []).concat(user);
139         next();
140       });
142       app.get('/:user/bob', function(req, res, next) {
143         count++;
144         next();
145       });
146       app.get('/foo/:user', function(req, res, next) {
147         count++;
148         next();
149       });
150       app.use(function(req, res) {
151         res.end([count, called, req.users.join(',')].join(' '));
152       });
154       request(app)
155       .get('/foo/bob')
156       .expect('2 2 foo,bob', done);
157     })
159     it('should support altering req.params across routes', function(done) {
160       var app = express();
162       app.param('user', function(req, res, next, user) {
163         req.params.user = 'loki';
164         next();
165       });
167       app.get('/:user', function(req, res, next) {
168         next('route');
169       });
170       app.get('/:user', function(req, res, next) {
171         res.send(req.params.user);
172       });
174       request(app)
175       .get('/bob')
176       .expect('loki', done);
177     })
179     it('should not invoke without route handler', function(done) {
180       var app = express();
182       app.param('thing', function(req, res, next, thing) {
183         req.thing = thing;
184         next();
185       });
187       app.param('user', function(req, res, next, user) {
188         next(new Error('invalid invokation'));
189       });
191       app.post('/:user', function(req, res, next) {
192         res.send(req.params.user);
193       });
195       app.get('/:thing', function(req, res, next) {
196         res.send(req.thing);
197       });
199       request(app)
200       .get('/bob')
201       .expect(200, 'bob', done);
202     })
204     it('should work with encoded values', function(done){
205       var app = express();
207       app.param('name', function(req, res, next, name){
208         req.params.name = name;
209         next();
210       });
212       app.get('/user/:name', function(req, res){
213         var name = req.params.name;
214         res.send('' + name);
215       });
217       request(app)
218       .get('/user/foo%25bar')
219       .expect('foo%bar', done);
220     })
222     it('should catch thrown error', function(done){
223       var app = express();
225       app.param('id', function(req, res, next, id){
226         throw new Error('err!');
227       });
229       app.get('/user/:id', function(req, res){
230         var id = req.params.id;
231         res.send('' + id);
232       });
234       request(app)
235       .get('/user/123')
236       .expect(500, done);
237     })
239     it('should catch thrown secondary error', function(done){
240       var app = express();
242       app.param('id', function(req, res, next, val){
243         process.nextTick(next);
244       });
246       app.param('id', function(req, res, next, id){
247         throw new Error('err!');
248       });
250       app.get('/user/:id', function(req, res){
251         var id = req.params.id;
252         res.send('' + id);
253       });
255       request(app)
256       .get('/user/123')
257       .expect(500, done);
258     })
260     it('should defer to next route', function(done){
261       var app = express();
263       app.param('id', function(req, res, next, id){
264         next('route');
265       });
267       app.get('/user/:id', function(req, res){
268         var id = req.params.id;
269         res.send('' + id);
270       });
272       app.get('/:name/123', function(req, res){
273         res.send('name');
274       });
276       request(app)
277       .get('/user/123')
278       .expect('name', done);
279     })
281     it('should defer all the param routes', function(done){
282       var app = express();
284       app.param('id', function(req, res, next, val){
285         if (val === 'new') return next('route');
286         return next();
287       });
289       app.all('/user/:id', function(req, res){
290         res.send('all.id');
291       });
293       app.get('/user/:id', function(req, res){
294         res.send('get.id');
295       });
297       app.get('/user/new', function(req, res){
298         res.send('get.new');
299       });
301       request(app)
302       .get('/user/new')
303       .expect('get.new', done);
304     })
306     it('should not call when values differ on error', function(done) {
307       var app = express();
308       var called = 0;
309       var count = 0;
311       app.param('user', function(req, res, next, user) {
312         called++;
313         if (user === 'foo') throw new Error('err!');
314         req.user = user;
315         next();
316       });
318       app.get('/:user/bob', function(req, res, next) {
319         count++;
320         next();
321       });
322       app.get('/foo/:user', function(req, res, next) {
323         count++;
324         next();
325       });
327       app.use(function(err, req, res, next) {
328         res.status(500);
329         res.send([count, called, err.message].join(' '));
330       });
332       request(app)
333       .get('/foo/bob')
334       .expect(500, '0 1 err!', done)
335     });
337     it('should call when values differ when using "next"', function(done) {
338       var app = express();
339       var called = 0;
340       var count = 0;
342       app.param('user', function(req, res, next, user) {
343         called++;
344         if (user === 'foo') return next('route');
345         req.user = user;
346         next();
347       });
349       app.get('/:user/bob', function(req, res, next) {
350         count++;
351         next();
352       });
353       app.get('/foo/:user', function(req, res, next) {
354         count++;
355         next();
356       });
357       app.use(function(req, res) {
358         res.end([count, called, req.user].join(' '));
359       });
361       request(app)
362       .get('/foo/bob')
363       .expect('1 2 bob', done);
364     })
365   })