UNPKG

62 kBHTMLView Raw
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>SuperAgent - Ajax with less suck</title>
5 <link rel="stylesheet" href="style.css">
6 <script src="jquery.js"></script>
7 <script src="jquery-ui.min.js"></script>
8 <script src="highlight.js"></script>
9 <script src="jquery.tocify.min.js"></script>
10 <script>
11 $(function(){
12 $('#menu').tocify({
13 selectors: 'h2',
14 hashGenerator: 'pretty'
15 });
16 });
17 </script>
18 </head>
19 <body>
20 <ul id="menu"></ul>
21 <div id="content"> <section class="suite">
22 <h1>request</h1>
23 <dl>
24 <section class="suite">
25 <h1>with a callback</h1>
26 <dl>
27 <dt>should invoke .end()</dt>
28 <dd><pre><code>request
29.get(uri + '/login', function(err, res){
30 assert.equal(res.status, 200);
31 done();
32})</code></pre></dd>
33 </dl>
34 </section>
35 <section class="suite">
36 <h1>.end()</h1>
37 <dl>
38 <dt>should issue a request</dt>
39 <dd><pre><code>request
40.get(uri + '/login')
41.end(function(err, res){
42 assert.equal(res.status, 200);
43 done();
44});</code></pre></dd>
45 </dl>
46 </section>
47 <section class="suite">
48 <h1>res.error</h1>
49 <dl>
50 <dt>should should be an Error object</dt>
51 <dd><pre><code>request
52.get(uri + '/error')
53.end(function(err, res){
54 if (NODE) {
55 res.error.message.should.equal('cannot GET /error (500)');
56 }
57 else {
58 res.error.message.should.equal('cannot GET ' + uri + '/error (500)');
59 }
60 assert.strictEqual(res.error.status, 500);
61 assert(err, 'should have an error for 500');
62 assert.equal(err.message, 'Internal Server Error');
63 done();
64});</code></pre></dd>
65 </dl>
66 </section>
67 <section class="suite">
68 <h1>res.header</h1>
69 <dl>
70 <dt>should be an object</dt>
71 <dd><pre><code>request
72.get(uri + '/login')
73.end(function(err, res){
74 assert.equal('Express', res.header['x-powered-by']);
75 done();
76});</code></pre></dd>
77 </dl>
78 </section>
79 <section class="suite">
80 <h1>res.charset</h1>
81 <dl>
82 <dt>should be set when present</dt>
83 <dd><pre><code>request
84.get(uri + '/login')
85.end(function(err, res){
86 res.charset.should.equal('utf-8');
87 done();
88});</code></pre></dd>
89 </dl>
90 </section>
91 <section class="suite">
92 <h1>res.statusType</h1>
93 <dl>
94 <dt>should provide the first digit</dt>
95 <dd><pre><code>request
96.get(uri + '/login')
97.end(function(err, res){
98 assert(!err, 'should not have an error for success responses');
99 assert.equal(200, res.status);
100 assert.equal(2, res.statusType);
101 done();
102});</code></pre></dd>
103 </dl>
104 </section>
105 <section class="suite">
106 <h1>res.type</h1>
107 <dl>
108 <dt>should provide the mime-type void of params</dt>
109 <dd><pre><code>request
110.get(uri + '/login')
111.end(function(err, res){
112 res.type.should.equal('text/html');
113 res.charset.should.equal('utf-8');
114 done();
115});</code></pre></dd>
116 </dl>
117 </section>
118 <section class="suite">
119 <h1>req.set(field, val)</h1>
120 <dl>
121 <dt>should set the header field</dt>
122 <dd><pre><code>request
123.post(uri + '/echo')
124.set('X-Foo', 'bar')
125.set('X-Bar', 'baz')
126.end(function(err, res){
127 assert.equal('bar', res.header['x-foo']);
128 assert.equal('baz', res.header['x-bar']);
129 done();
130})</code></pre></dd>
131 </dl>
132 </section>
133 <section class="suite">
134 <h1>req.set(obj)</h1>
135 <dl>
136 <dt>should set the header fields</dt>
137 <dd><pre><code>request
138.post(uri + '/echo')
139.set({ 'X-Foo': 'bar', 'X-Bar': 'baz' })
140.end(function(err, res){
141 assert.equal('bar', res.header['x-foo']);
142 assert.equal('baz', res.header['x-bar']);
143 done();
144})</code></pre></dd>
145 </dl>
146 </section>
147 <section class="suite">
148 <h1>req.type(str)</h1>
149 <dl>
150 <dt>should set the Content-Type</dt>
151 <dd><pre><code>request
152.post(uri + '/echo')
153.type('text/x-foo')
154.end(function(err, res){
155 res.header['content-type'].should.equal('text/x-foo');
156 done();
157});</code></pre></dd>
158 <dt>should map &quot;json&quot;</dt>
159 <dd><pre><code>request
160.post(uri + '/echo')
161.type('json')
162.send('{&quot;a&quot;: 1}')
163.end(function(err, res){
164 res.should.be.json;
165 done();
166});</code></pre></dd>
167 <dt>should map &quot;html&quot;</dt>
168 <dd><pre><code>request
169.post(uri + '/echo')
170.type('html')
171.end(function(err, res){
172 res.header['content-type'].should.equal('text/html');
173 done();
174});</code></pre></dd>
175 </dl>
176 </section>
177 <section class="suite">
178 <h1>req.accept(str)</h1>
179 <dl>
180 <dt>should set Accept</dt>
181 <dd><pre><code>request
182.get(uri + '/echo')
183.accept('text/x-foo')
184.end(function(err, res){
185 res.header['accept'].should.equal('text/x-foo');
186 done();
187});</code></pre></dd>
188 <dt>should map &quot;json&quot;</dt>
189 <dd><pre><code>request
190.get(uri + '/echo')
191.accept('json')
192.end(function(err, res){
193 res.header['accept'].should.equal('application/json');
194 done();
195});</code></pre></dd>
196 <dt>should map &quot;xml&quot;</dt>
197 <dd><pre><code>request
198.get(uri + '/echo')
199.accept('xml')
200.end(function(err, res){
201 res.header['accept'].should.equal('application/xml');
202 done();
203});</code></pre></dd>
204 <dt>should map &quot;html&quot;</dt>
205 <dd><pre><code>request
206.get(uri + '/echo')
207.accept('html')
208.end(function(err, res){
209 res.header['accept'].should.equal('text/html');
210 done();
211});</code></pre></dd>
212 </dl>
213 </section>
214 <section class="suite">
215 <h1>req.send(str)</h1>
216 <dl>
217 <dt>should write the string</dt>
218 <dd><pre><code>request
219.post(uri + '/echo')
220.type('json')
221.send('{&quot;name&quot;:&quot;tobi&quot;}')
222.end(function(err, res){
223 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
224 done();
225});</code></pre></dd>
226 </dl>
227 </section>
228 <section class="suite">
229 <h1>req.send(Object)</h1>
230 <dl>
231 <dt>should default to json</dt>
232 <dd><pre><code>request
233.post(uri + '/echo')
234.send({ name: 'tobi' })
235.end(function(err, res){
236 res.should.be.json
237 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
238 done();
239});</code></pre></dd>
240 <section class="suite">
241 <h1>when called several times</h1>
242 <dl>
243 <dt>should merge the objects</dt>
244 <dd><pre><code>request
245.post(uri + '/echo')
246.send({ name: 'tobi' })
247.send({ age: 1 })
248.end(function(err, res){
249 res.should.be.json
250 if (NODE) {
251 res.buffered.should.be.true;
252 }
253 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;,&quot;age&quot;:1}');
254 done();
255});</code></pre></dd>
256 </dl>
257 </section>
258 </dl>
259 </section>
260 <section class="suite">
261 <h1>.end(fn)</h1>
262 <dl>
263 <dt>should check arity</dt>
264 <dd><pre><code>request
265.post(uri + '/echo')
266.send({ name: 'tobi' })
267.end(function(err, res){
268 assert.equal(null, err);
269 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
270 done();
271});</code></pre></dd>
272 <dt>should emit request</dt>
273 <dd><pre><code>var req = request.post(uri + '/echo');
274req.on('request', function(request){
275 assert.equal(req, request);
276 done();
277});
278req.end();</code></pre></dd>
279 <dt>should emit response</dt>
280 <dd><pre><code>request
281.post(uri + '/echo')
282.send({ name: 'tobi' })
283.on('response', function(res){
284 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
285 done();
286})
287.end();</code></pre></dd>
288 </dl>
289 </section>
290 <section class="suite">
291 <h1>.then(fulfill, reject)</h1>
292 <dl>
293 <dt>should support successful fulfills with .then(fulfill)</dt>
294 <dd><pre><code>request
295.post(uri + '/echo')
296.send({ name: 'tobi' })
297.then(function(res) {
298 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
299 done();
300})</code></pre></dd>
301 <dt>should reject an error with .then(null, reject)</dt>
302 <dd><pre><code>request
303.get(uri + '/error')
304.then(null, function(err) {
305 assert.equal(err.status, 500);
306 assert.equal(err.response.text, 'boom');
307 done();
308})</code></pre></dd>
309 </dl>
310 </section>
311 <section class="suite">
312 <h1>.abort()</h1>
313 <dl>
314 <dt>should abort the request</dt>
315 <dd><pre><code>var req = request
316.get(uri + '/delay/3000')
317.end(function(err, res){
318 assert(false, 'should not complete the request');
319});
320req.on('abort', done);
321setTimeout(function() {
322 req.abort();
323}, 1000);</code></pre></dd>
324 </dl>
325 </section>
326 </dl>
327 </section>
328 <section class="suite">
329 <h1>request</h1>
330 <dl>
331 <section class="suite">
332 <h1>persistent agent</h1>
333 <dl>
334 <dt>should gain a session on POST</dt>
335 <dd><pre><code>agent3
336 .post('http://localhost:4000/signin')
337 .end(function(err, res) {
338 should.not.exist(err);
339 res.should.have.status(200);
340 should.not.exist(res.headers['set-cookie']);
341 res.text.should.containEql('dashboard');
342 done();
343 });</code></pre></dd>
344 <dt>should start with empty session (set cookies)</dt>
345 <dd><pre><code>agent1
346 .get('http://localhost:4000/dashboard')
347 .end(function(err, res) {
348 should.exist(err);
349 res.should.have.status(401);
350 should.exist(res.headers['set-cookie']);
351 done();
352 });</code></pre></dd>
353 <dt>should gain a session (cookies already set)</dt>
354 <dd><pre><code>agent1
355 .post('http://localhost:4000/signin')
356 .end(function(err, res) {
357 should.not.exist(err);
358 res.should.have.status(200);
359 should.not.exist(res.headers['set-cookie']);
360 res.text.should.containEql('dashboard');
361 done();
362 });</code></pre></dd>
363 <dt>should persist cookies across requests</dt>
364 <dd><pre><code>agent1
365 .get('http://localhost:4000/dashboard')
366 .end(function(err, res) {
367 should.not.exist(err);
368 res.should.have.status(200);
369 done();
370 });</code></pre></dd>
371 <dt>should have the cookie set in the end callback</dt>
372 <dd><pre><code>agent4
373 .post('http://localhost:4000/setcookie')
374 .end(function(err, res) {
375 agent4
376 .get('http://localhost:4000/getcookie')
377 .end(function(err, res) {
378 should.not.exist(err);
379 res.should.have.status(200);
380 assert.strictEqual(res.text, 'jar');
381 done();
382 });
383 });</code></pre></dd>
384 <dt>should not share cookies</dt>
385 <dd><pre><code>agent2
386 .get('http://localhost:4000/dashboard')
387 .end(function(err, res) {
388 should.exist(err);
389 res.should.have.status(401);
390 done();
391 });</code></pre></dd>
392 <dt>should not lose cookies between agents</dt>
393 <dd><pre><code>agent1
394 .get('http://localhost:4000/dashboard')
395 .end(function(err, res) {
396 should.not.exist(err);
397 res.should.have.status(200);
398 done();
399 });</code></pre></dd>
400 <dt>should be able to follow redirects</dt>
401 <dd><pre><code>agent1
402 .get('http://localhost:4000/')
403 .end(function(err, res) {
404 should.not.exist(err);
405 res.should.have.status(200);
406 res.text.should.containEql('dashboard');
407 done();
408 });</code></pre></dd>
409 <dt>should be able to post redirects</dt>
410 <dd><pre><code>agent1
411 .post('http://localhost:4000/redirect')
412 .send({ foo: 'bar', baz: 'blaaah' })
413 .end(function(err, res) {
414 should.not.exist(err);
415 res.should.have.status(200);
416 res.text.should.containEql('simple');
417 res.redirects.should.eql(['http://localhost:4000/simple']);
418 done();
419 });</code></pre></dd>
420 <dt>should be able to limit redirects</dt>
421 <dd><pre><code>agent1
422 .get('http://localhost:4000/')
423 .redirects(0)
424 .end(function(err, res) {
425 should.exist(err);
426 res.should.have.status(302);
427 res.redirects.should.eql([]);
428 res.header.location.should.equal('/dashboard');
429 done();
430 });</code></pre></dd>
431 <dt>should be able to create a new session (clear cookie)</dt>
432 <dd><pre><code>agent1
433 .post('http://localhost:4000/signout')
434 .end(function(err, res) {
435 should.not.exist(err);
436 res.should.have.status(200);
437 should.exist(res.headers['set-cookie']);
438 done();
439 });</code></pre></dd>
440 <dt>should regenerate with an empty session</dt>
441 <dd><pre><code>agent1
442 .get('http://localhost:4000/dashboard')
443 .end(function(err, res) {
444 should.exist(err);
445 res.should.have.status(401);
446 should.not.exist(res.headers['set-cookie']);
447 done();
448 });</code></pre></dd>
449 </dl>
450 </section>
451 </dl>
452 </section>
453 <section class="suite">
454 <h1>Basic auth</h1>
455 <dl>
456 <section class="suite">
457 <h1>when credentials are present in url</h1>
458 <dl>
459 <dt>should set Authorization</dt>
460 <dd><pre><code>request
461.get('http://tobi:learnboost@localhost:3010')
462.end(function(err, res){
463 res.status.should.equal(200);
464 done();
465});</code></pre></dd>
466 </dl>
467 </section>
468 <section class="suite">
469 <h1>req.auth(user, pass)</h1>
470 <dl>
471 <dt>should set Authorization</dt>
472 <dd><pre><code>request
473.get('http://localhost:3010')
474.auth('tobi', 'learnboost')
475.end(function(err, res){
476 res.status.should.equal(200);
477 done();
478});</code></pre></dd>
479 </dl>
480 </section>
481 <section class="suite">
482 <h1>req.auth(user + &quot;:&quot; + pass)</h1>
483 <dl>
484 <dt>should set authorization</dt>
485 <dd><pre><code>request
486.get('http://localhost:3010/again')
487.auth('tobi')
488.end(function(err, res){
489 res.status.should.eql(200);
490 done();
491});</code></pre></dd>
492 </dl>
493 </section>
494 </dl>
495 </section>
496 <section class="suite">
497 <h1>[node] request</h1>
498 <dl>
499 <section class="suite">
500 <h1>res.statusCode</h1>
501 <dl>
502 <dt>should set statusCode</dt>
503 <dd><pre><code>request
504.get('http://localhost:5000/login', function(err, res){
505 assert.strictEqual(res.statusCode, 200);
506 done();
507})</code></pre></dd>
508 </dl>
509 </section>
510 <section class="suite">
511 <h1>with an object</h1>
512 <dl>
513 <dt>should format the url</dt>
514 <dd><pre><code>request
515.get(url.parse('http://localhost:5000/login'))
516.end(function(err, res){
517 assert(res.ok);
518 done();
519})</code></pre></dd>
520 </dl>
521 </section>
522 <section class="suite">
523 <h1>without a schema</h1>
524 <dl>
525 <dt>should default to http</dt>
526 <dd><pre><code>request
527.get('localhost:5000/login')
528.end(function(err, res){
529 assert.equal(res.status, 200);
530 done();
531})</code></pre></dd>
532 </dl>
533 </section>
534 <section class="suite">
535 <h1>req.toJSON()</h1>
536 <dl>
537 <dt>should describe the request</dt>
538 <dd><pre><code>request
539.post(':5000/echo')
540.send({ foo: 'baz' })
541.end(function(err, res){
542 var obj = res.request.toJSON();
543 assert.equal('POST', obj.method);
544 assert.equal(':5000/echo', obj.url);
545 assert.equal('baz', obj.data.foo);
546 done();
547});</code></pre></dd>
548 </dl>
549 </section>
550 <section class="suite">
551 <h1>should allow the send shorthand</h1>
552 <dl>
553 <dt>with callback in the method call</dt>
554 <dd><pre><code>request
555.get('http://localhost:5000/login', function(err, res) {
556 assert.equal(res.status, 200);
557 done();
558});</code></pre></dd>
559 <dt>with data in the method call</dt>
560 <dd><pre><code>request
561.post('http://localhost:5000/echo', { foo: 'bar' })
562.end(function(err, res) {
563 assert.equal('{&quot;foo&quot;:&quot;bar&quot;}', res.text);
564 done();
565});</code></pre></dd>
566 <dt>with callback and data in the method call</dt>
567 <dd><pre><code>request
568.post('http://localhost:5000/echo', { foo: 'bar' }, function(err, res) {
569 assert.equal('{&quot;foo&quot;:&quot;bar&quot;}', res.text);
570 done();
571});</code></pre></dd>
572 </dl>
573 </section>
574 <section class="suite">
575 <h1>res.toJSON()</h1>
576 <dl>
577 <dt>should describe the response</dt>
578 <dd><pre><code>request
579.post('http://localhost:5000/echo')
580.send({ foo: 'baz' })
581.end(function(err, res){
582 var obj = res.toJSON();
583 assert.equal('object', typeof obj.header);
584 assert.equal('object', typeof obj.req);
585 assert.equal(200, obj.status);
586 assert.equal('{&quot;foo&quot;:&quot;baz&quot;}', obj.text);
587 done();
588});</code></pre></dd>
589 </dl>
590 </section>
591 <section class="suite">
592 <h1>res.links</h1>
593 <dl>
594 <dt>should default to an empty object</dt>
595 <dd><pre><code>request
596.get('http://localhost:5000/login')
597.end(function(err, res){
598 res.links.should.eql({});
599 done();
600})</code></pre></dd>
601 <dt>should parse the Link header field</dt>
602 <dd><pre><code>request
603.get('http://localhost:5000/links')
604.end(function(err, res){
605 res.links.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2');
606 done();
607})</code></pre></dd>
608 </dl>
609 </section>
610 <section class="suite">
611 <h1>req.unset(field)</h1>
612 <dl>
613 <dt>should remove the header field</dt>
614 <dd><pre><code>request
615.post('http://localhost:5000/echo')
616.unset('User-Agent')
617.end(function(err, res){
618 assert.equal(void 0, res.header['user-agent']);
619 done();
620})</code></pre></dd>
621 </dl>
622 </section>
623 <section class="suite">
624 <h1>req.write(str)</h1>
625 <dl>
626 <dt>should write the given data</dt>
627 <dd><pre><code>var req = request.post('http://localhost:5000/echo');
628req.set('Content-Type', 'application/json');
629req.write('{&quot;name&quot;').should.be.a.boolean;
630req.write(':&quot;tobi&quot;}').should.be.a.boolean;
631req.end(function(err, res){
632 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
633 done();
634});</code></pre></dd>
635 </dl>
636 </section>
637 <section class="suite">
638 <h1>req.pipe(stream)</h1>
639 <dl>
640 <dt>should pipe the response to the given stream</dt>
641 <dd><pre><code>var stream = new EventEmitter;
642stream.buf = '';
643stream.writable = true;
644stream.write = function(chunk){
645 this.buf += chunk;
646};
647stream.end = function(){
648 this.buf.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
649 done();
650};
651request
652.post('http://localhost:5000/echo')
653.send('{&quot;name&quot;:&quot;tobi&quot;}')
654.pipe(stream);</code></pre></dd>
655 </dl>
656 </section>
657 <section class="suite">
658 <h1>.buffer()</h1>
659 <dl>
660 <dt>should enable buffering</dt>
661 <dd><pre><code>request
662.get('http://localhost:5000/custom')
663.buffer()
664.end(function(err, res){
665 assert.equal(null, err);
666 assert.equal('custom stuff', res.text);
667 assert(res.buffered);
668 done();
669});</code></pre></dd>
670 </dl>
671 </section>
672 <section class="suite">
673 <h1>.buffer(false)</h1>
674 <dl>
675 <dt>should disable buffering</dt>
676 <dd><pre><code>request
677.post('http://localhost:5000/echo')
678.type('application/x-dog')
679.send('hello this is dog')
680.buffer(false)
681.end(function(err, res){
682 assert.equal(null, err);
683 assert.equal(null, res.text);
684 res.body.should.eql({});
685 var buf = '';
686 res.setEncoding('utf8');
687 res.on('data', function(chunk){ buf += chunk });
688 res.on('end', function(){
689 buf.should.equal('hello this is dog');
690 done();
691 });
692});</code></pre></dd>
693 </dl>
694 </section>
695 <section class="suite">
696 <h1>.agent()</h1>
697 <dl>
698 <dt>should return the defaut agent</dt>
699 <dd><pre><code>var req = request.post('http://localhost:5000/echo');
700req.agent().should.equal(false);
701done();</code></pre></dd>
702 </dl>
703 </section>
704 <section class="suite">
705 <h1>.agent(undefined)</h1>
706 <dl>
707 <dt>should set an agent to undefined and ensure it is chainable</dt>
708 <dd><pre><code>var req = request.get('http://localhost:5000/echo');
709var ret = req.agent(undefined);
710ret.should.equal(req);
711assert.strictEqual(req.agent(), undefined);
712done();</code></pre></dd>
713 </dl>
714 </section>
715 <section class="suite">
716 <h1>.agent(new http.Agent())</h1>
717 <dl>
718 <dt>should set passed agent</dt>
719 <dd><pre><code>var http = require('http');
720var req = request.get('http://localhost:5000/echo');
721var agent = new http.Agent();
722var ret = req.agent(agent);
723ret.should.equal(req);
724req.agent().should.equal(agent)
725done();</code></pre></dd>
726 </dl>
727 </section>
728 <section class="suite">
729 <h1>with a content type other than application/json or text/*</h1>
730 <dl>
731 <dt>should disable buffering</dt>
732 <dd><pre><code>request
733.post('http://localhost:5000/echo')
734.type('application/x-dog')
735.send('hello this is dog')
736.end(function(err, res){
737 assert.equal(null, err);
738 assert.equal(null, res.text);
739 res.body.should.eql({});
740 var buf = '';
741 res.setEncoding('utf8');
742 res.buffered.should.be.false;
743 res.on('data', function(chunk){ buf += chunk });
744 res.on('end', function(){
745 buf.should.equal('hello this is dog');
746 done();
747 });
748});</code></pre></dd>
749 </dl>
750 </section>
751 <section class="suite">
752 <h1>content-length</h1>
753 <dl>
754 <dt>should be set to the byte length of a non-buffer object</dt>
755 <dd><pre><code>var decoder = new StringDecoder('utf8');
756var img = fs.readFileSync(__dirname + '/fixtures/test.png');
757img = decoder.write(img);
758request
759.post('http://localhost:5000/echo')
760.type('application/x-image')
761.send(img)
762.buffer(false)
763.end(function(err, res){
764 assert.equal(null, err);
765 assert(!res.buffered);
766 assert.equal(res.header['content-length'], Buffer.byteLength(img));
767 done();
768});</code></pre></dd>
769 <dt>should be set to the length of a buffer object</dt>
770 <dd><pre><code>var img = fs.readFileSync(__dirname + '/fixtures/test.png');
771request
772.post('http://localhost:5000/echo')
773.type('application/x-image')
774.send(img)
775.buffer(true)
776.end(function(err, res){
777 assert.equal(null, err);
778 assert(res.buffered);
779 assert.equal(res.header['content-length'], img.length);
780 done();
781});</code></pre></dd>
782 </dl>
783 </section>
784 </dl>
785 </section>
786 <section class="suite">
787 <h1>req.set(&quot;Content-Type&quot;, contentType)</h1>
788 <dl>
789 <dt>should work with just the contentType component</dt>
790 <dd><pre><code>request
791.post('http://localhost:3005/echo')
792.set('Content-Type', 'application/json')
793.send({ name: 'tobi' })
794.end(function(err, res){
795 assert(!err);
796 done();
797});</code></pre></dd>
798 <dt>should work with the charset component</dt>
799 <dd><pre><code>request
800.post('http://localhost:3005/echo')
801.set('Content-Type', 'application/json; charset=utf-8')
802.send({ name: 'tobi' })
803.end(function(err, res){
804 assert(!err);
805 done();
806});</code></pre></dd>
807 </dl>
808 </section>
809 <section class="suite">
810 <h1>exports</h1>
811 <dl>
812 <dt>should expose Part</dt>
813 <dd><pre><code>request.Part.should.be.a.function;</code></pre></dd>
814 <dt>should expose .protocols</dt>
815 <dd><pre><code>Object.keys(request.protocols)
816 .should.eql(['http:', 'https:']);</code></pre></dd>
817 <dt>should expose .serialize</dt>
818 <dd><pre><code>Object.keys(request.serialize)
819 .should.eql(['application/x-www-form-urlencoded', 'application/json']);</code></pre></dd>
820 <dt>should expose .parse</dt>
821 <dd><pre><code>Object.keys(request.parse)
822 .should.eql(['application/x-www-form-urlencoded', 'application/json', 'text', 'image']);</code></pre></dd>
823 </dl>
824 </section>
825 <section class="suite">
826 <h1>flags</h1>
827 <dl>
828 <section class="suite">
829 <h1>with 4xx response</h1>
830 <dl>
831 <dt>should set res.error and res.clientError</dt>
832 <dd><pre><code>request
833.get('http://localhost:3004/notfound')
834.end(function(err, res){
835 assert(err);
836 assert(!res.ok, 'response should not be ok');
837 assert(res.error, 'response should be an error');
838 assert(res.clientError, 'response should be a client error');
839 assert(!res.serverError, 'response should not be a server error');
840 done();
841});</code></pre></dd>
842 </dl>
843 </section>
844 <section class="suite">
845 <h1>with 5xx response</h1>
846 <dl>
847 <dt>should set res.error and res.serverError</dt>
848 <dd><pre><code>request
849.get('http://localhost:3004/error')
850.end(function(err, res){
851 assert(err);
852 assert(!res.ok, 'response should not be ok');
853 assert(!res.notFound, 'response should not be notFound');
854 assert(res.error, 'response should be an error');
855 assert(!res.clientError, 'response should not be a client error');
856 assert(res.serverError, 'response should be a server error');
857 done();
858});</code></pre></dd>
859 </dl>
860 </section>
861 <section class="suite">
862 <h1>with 404 Not Found</h1>
863 <dl>
864 <dt>should res.notFound</dt>
865 <dd><pre><code>request
866.get('http://localhost:3004/notfound')
867.end(function(err, res){
868 assert(err);
869 assert(res.notFound, 'response should be .notFound');
870 done();
871});</code></pre></dd>
872 </dl>
873 </section>
874 <section class="suite">
875 <h1>with 400 Bad Request</h1>
876 <dl>
877 <dt>should set req.badRequest</dt>
878 <dd><pre><code>request
879.get('http://localhost:3004/bad-request')
880.end(function(err, res){
881 assert(err);
882 assert(res.badRequest, 'response should be .badRequest');
883 done();
884});</code></pre></dd>
885 </dl>
886 </section>
887 <section class="suite">
888 <h1>with 401 Bad Request</h1>
889 <dl>
890 <dt>should set res.unauthorized</dt>
891 <dd><pre><code>request
892.get('http://localhost:3004/unauthorized')
893.end(function(err, res){
894 assert(err);
895 assert(res.unauthorized, 'response should be .unauthorized');
896 done();
897});</code></pre></dd>
898 </dl>
899 </section>
900 <section class="suite">
901 <h1>with 406 Not Acceptable</h1>
902 <dl>
903 <dt>should set res.notAcceptable</dt>
904 <dd><pre><code>request
905.get('http://localhost:3004/not-acceptable')
906.end(function(err, res){
907 assert(err);
908 assert(res.notAcceptable, 'response should be .notAcceptable');
909 done();
910});</code></pre></dd>
911 </dl>
912 </section>
913 <section class="suite">
914 <h1>with 204 No Content</h1>
915 <dl>
916 <dt>should set res.noContent</dt>
917 <dd><pre><code>request
918.get('http://localhost:3004/no-content')
919.end(function(err, res){
920 assert(!err);
921 assert(res.noContent, 'response should be .noContent');
922 done();
923});</code></pre></dd>
924 </dl>
925 </section>
926 </dl>
927 </section>
928 <section class="suite">
929 <h1>req.send(Object) as &quot;form&quot;</h1>
930 <dl>
931 <section class="suite">
932 <h1>with req.type() set to form</h1>
933 <dl>
934 <dt>should send x-www-form-urlencoded data</dt>
935 <dd><pre><code>request
936.post('http://localhost:3002/echo')
937.type('form')
938.send({ name: 'tobi' })
939.end(function(err, res){
940 res.header['content-type'].should.equal('application/x-www-form-urlencoded');
941 res.text.should.equal('name=tobi');
942 done();
943});</code></pre></dd>
944 </dl>
945 </section>
946 <section class="suite">
947 <h1>when called several times</h1>
948 <dl>
949 <dt>should merge the objects</dt>
950 <dd><pre><code>request
951.post('http://localhost:3002/echo')
952.type('form')
953.send({ name: { first: 'tobi', last: 'holowaychuk' } })
954.send({ age: '1' })
955.end(function(err, res){
956 res.header['content-type'].should.equal('application/x-www-form-urlencoded');
957 res.text.should.equal('name%5Bfirst%5D=tobi&amp;name%5Blast%5D=holowaychuk&amp;age=1');
958 done();
959});</code></pre></dd>
960 </dl>
961 </section>
962 </dl>
963 </section>
964 <section class="suite">
965 <h1>req.send(String)</h1>
966 <dl>
967 <dt>should default to &quot;form&quot;</dt>
968 <dd><pre><code>request
969.post('http://localhost:3002/echo')
970.send('user[name]=tj')
971.send('user[email]=tj@vision-media.ca')
972.end(function(err, res){
973 res.header['content-type'].should.equal('application/x-www-form-urlencoded');
974 res.body.should.eql({ user: { name: 'tj', email: 'tj@vision-media.ca' } });
975 done();
976})</code></pre></dd>
977 </dl>
978 </section>
979 <section class="suite">
980 <h1>res.body</h1>
981 <dl>
982 <section class="suite">
983 <h1>application/x-www-form-urlencoded</h1>
984 <dl>
985 <dt>should parse the body</dt>
986 <dd><pre><code>request
987.get('http://localhost:3002/form-data')
988.end(function(err, res){
989 res.text.should.equal('pet[name]=manny');
990 res.body.should.eql({ pet: { name: 'manny' }});
991 done();
992});</code></pre></dd>
993 </dl>
994 </section>
995 </dl>
996 </section>
997 <section class="suite">
998 <h1>https</h1>
999 <dl>
1000 <section class="suite">
1001 <h1>request</h1>
1002 <dl>
1003 <dt>should give a good response</dt>
1004 <dd><pre><code>request
1005.get('https://localhost:8443/')
1006.ca(cert)
1007.end(function(err, res){
1008 assert(res.ok);
1009 assert.strictEqual('Safe and secure!', res.text);
1010 done();
1011});</code></pre></dd>
1012 </dl>
1013 </section>
1014 <section class="suite">
1015 <h1>.agent</h1>
1016 <dl>
1017 <dt>should be able to make multiple requests without redefining the certificate</dt>
1018 <dd><pre><code>var agent = request.agent({ca: cert});
1019agent
1020.get('https://localhost:8443/')
1021.end(function(err, res){
1022 assert(res.ok);
1023 assert.strictEqual('Safe and secure!', res.text);
1024 agent
1025 .get(url.parse('https://localhost:8443/'))
1026 .end(function(err, res){
1027 assert(res.ok);
1028 assert.strictEqual('Safe and secure!', res.text);
1029 done();
1030 });
1031});</code></pre></dd>
1032 </dl>
1033 </section>
1034 </dl>
1035 </section>
1036 <section class="suite">
1037 <h1>res.body</h1>
1038 <dl>
1039 <section class="suite">
1040 <h1>image/png</h1>
1041 <dl>
1042 <dt>should parse the body</dt>
1043 <dd><pre><code>request
1044.get('http://localhost:3011/image')
1045.end(function(err, res){
1046 (res.body.length - img.length).should.equal(0);
1047 done();
1048});</code></pre></dd>
1049 </dl>
1050 </section>
1051 </dl>
1052 </section>
1053 <section class="suite">
1054 <h1>zlib</h1>
1055 <dl>
1056 <dt>should deflate the content</dt>
1057 <dd><pre><code>request
1058 .get('http://localhost:3080')
1059 .end(function(err, res){
1060 res.should.have.status(200);
1061 res.text.should.equal(subject);
1062 res.headers['content-length'].should.be.below(subject.length);
1063 done();
1064 });</code></pre></dd>
1065 <dt>should handle corrupted responses</dt>
1066 <dd><pre><code>request
1067 .get('http://localhost:3080/corrupt')
1068 .end(function(err, res){
1069 assert(err, 'missing error');
1070 assert(!res, 'response should not be defined');
1071 done();
1072 });</code></pre></dd>
1073 <section class="suite">
1074 <h1>without encoding set</h1>
1075 <dl>
1076 <dt>should emit buffers</dt>
1077 <dd><pre><code>request
1078 .get('http://localhost:3080/binary')
1079 .end(function(err, res){
1080 res.should.have.status(200);
1081 res.headers['content-length'].should.be.below(subject.length);
1082 res.on('data', function(chunk){
1083 chunk.should.have.length(subject.length);
1084 });
1085 res.on('end', done);
1086 });</code></pre></dd>
1087 </dl>
1088 </section>
1089 </dl>
1090 </section>
1091 <section class="suite">
1092 <h1>req.send(Object) as &quot;json&quot;</h1>
1093 <dl>
1094 <dt>should default to json</dt>
1095 <dd><pre><code>request
1096.post('http://localhost:3005/echo')
1097.send({ name: 'tobi' })
1098.end(function(err, res){
1099 res.should.be.json
1100 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
1101 done();
1102});</code></pre></dd>
1103 <dt>should work with arrays</dt>
1104 <dd><pre><code>request
1105.post('http://localhost:3005/echo')
1106.send([1,2,3])
1107.end(function(err, res){
1108 res.should.be.json
1109 res.text.should.equal('[1,2,3]');
1110 done();
1111});</code></pre></dd>
1112 <dt>should work with value null</dt>
1113 <dd><pre><code>request
1114.post('http://localhost:3005/echo')
1115.type('json')
1116.send('null')
1117.end(function(err, res){
1118 res.should.be.json
1119 assert.strictEqual(res.body, null);
1120 done();
1121});</code></pre></dd>
1122 <dt>should work with value false</dt>
1123 <dd><pre><code>request
1124.post('http://localhost:3005/echo')
1125.type('json')
1126.send('false')
1127.end(function(err, res){
1128 res.should.be.json
1129 res.body.should.equal(false);
1130 done();
1131});</code></pre></dd>
1132 <dt>should work with value 0</dt>
1133 <dd><pre><code>request
1134.post('http://localhost:3005/echo')
1135.type('json')
1136.send('0')
1137.end(function(err, res){
1138 res.should.be.json
1139 res.body.should.equal(0);
1140 done();
1141});</code></pre></dd>
1142 <dt>should work with empty string value</dt>
1143 <dd><pre><code>request
1144.post('http://localhost:3005/echo')
1145.type('json')
1146.send('&quot;&quot;')
1147.end(function(err, res){
1148 res.should.be.json
1149 res.body.should.equal(&quot;&quot;);
1150 done();
1151});</code></pre></dd>
1152 <dt>should work with GET</dt>
1153 <dd><pre><code>request
1154.get('http://localhost:3005/echo')
1155.send({ tobi: 'ferret' })
1156.end(function(err, res){
1157 res.should.be.json
1158 res.text.should.equal('{&quot;tobi&quot;:&quot;ferret&quot;}');
1159 done();
1160});</code></pre></dd>
1161 <dt>should work with vendor MIME type</dt>
1162 <dd><pre><code>request
1163.post('http://localhost:3005/echo')
1164.set('Content-Type', 'application/vnd.example+json')
1165.send({ name: 'vendor' })
1166.end(function(err, res){
1167 res.text.should.equal('{&quot;name&quot;:&quot;vendor&quot;}');
1168 done();
1169});</code></pre></dd>
1170 <section class="suite">
1171 <h1>when called several times</h1>
1172 <dl>
1173 <dt>should merge the objects</dt>
1174 <dd><pre><code>request
1175.post('http://localhost:3005/echo')
1176.send({ name: 'tobi' })
1177.send({ age: 1 })
1178.end(function(err, res){
1179 res.should.be.json
1180 res.text.should.equal('{&quot;name&quot;:&quot;tobi&quot;,&quot;age&quot;:1}');
1181 done();
1182});</code></pre></dd>
1183 </dl>
1184 </section>
1185 </dl>
1186 </section>
1187 <section class="suite">
1188 <h1>res.body</h1>
1189 <dl>
1190 <section class="suite">
1191 <h1>application/json</h1>
1192 <dl>
1193 <dt>should parse the body</dt>
1194 <dd><pre><code>request
1195.get('http://localhost:3005/json')
1196.end(function(err, res){
1197 res.text.should.equal('{&quot;name&quot;:&quot;manny&quot;}');
1198 res.body.should.eql({ name: 'manny' });
1199 done();
1200});</code></pre></dd>
1201 </dl>
1202 </section>
1203 <section class="suite">
1204 <h1>HEAD requests</h1>
1205 <dl>
1206 <dt>should not throw a parse error</dt>
1207 <dd><pre><code>request
1208.head('http://localhost:3005/json')
1209.end(function(err, res){
1210 assert.strictEqual(err, null);
1211 assert.strictEqual(res.text, undefined)
1212 assert.strictEqual(Object.keys(res.body).length, 0)
1213 done();
1214});</code></pre></dd>
1215 </dl>
1216 </section>
1217 <section class="suite">
1218 <h1>Invalid JSON response</h1>
1219 <dl>
1220 <dt>should return the raw response</dt>
1221 <dd><pre><code>request
1222.get('http://localhost:3005/invalid-json')
1223.end(function(err, res){
1224 assert.deepEqual(err.rawResponse, &quot;)]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}&quot;);
1225 done();
1226});</code></pre></dd>
1227 </dl>
1228 </section>
1229 <section class="suite">
1230 <h1>No content</h1>
1231 <dl>
1232 <dt>should not throw a parse error</dt>
1233 <dd><pre><code>request
1234.get('http://localhost:3005/no-content')
1235.end(function(err, res){
1236 assert.strictEqual(err, null);
1237 assert.strictEqual(res.text, '');
1238 assert.strictEqual(Object.keys(res.body).length, 0);
1239 done();
1240});</code></pre></dd>
1241 </dl>
1242 </section>
1243 <section class="suite">
1244 <h1>application/json+hal</h1>
1245 <dl>
1246 <dt>should parse the body</dt>
1247 <dd><pre><code>request
1248.get('http://localhost:3005/json-hal')
1249.end(function(err, res){
1250 if (err) return done(err);
1251 res.text.should.equal('{&quot;name&quot;:&quot;hal 5000&quot;}');
1252 res.body.should.eql({ name: 'hal 5000' });
1253 done();
1254});</code></pre></dd>
1255 </dl>
1256 </section>
1257 <section class="suite">
1258 <h1>vnd.collection+json</h1>
1259 <dl>
1260 <dt>should parse the body</dt>
1261 <dd><pre><code>request
1262.get('http://localhost:3005/collection-json')
1263.end(function(err, res){
1264 res.text.should.equal('{&quot;name&quot;:&quot;chewbacca&quot;}');
1265 res.body.should.eql({ name: 'chewbacca' });
1266 done();
1267});</code></pre></dd>
1268 </dl>
1269 </section>
1270 </dl>
1271 </section>
1272 <section class="suite">
1273 <h1>Request</h1>
1274 <dl>
1275 <section class="suite">
1276 <h1>#attach(name, path, filename)</h1>
1277 <dl>
1278 <dt>should use the custom filename</dt>
1279 <dd><pre><code>request
1280.post(':3005/echo')
1281.attach('document', 'test/node/fixtures/user.html', 'doc.html')
1282.end(function(err, res){
1283 if (err) return done(err);
1284 var html = res.files.document;
1285 html.name.should.equal('doc.html');
1286 html.type.should.equal('text/html');
1287 read(html.path).should.equal('&lt;h1&gt;name&lt;/h1&gt;');
1288 done();
1289})</code></pre></dd>
1290 <dt>should fire progress event</dt>
1291 <dd><pre><code>var loaded = 0;
1292var total = 0;
1293request
1294.post(':3005/echo')
1295.attach('document', 'test/node/fixtures/user.html')
1296.on('progress', function (event) {
1297 total = event.total;
1298 loaded = event.loaded;
1299})
1300.end(function(err, res){
1301 if (err) return done(err);
1302 var html = res.files.document;
1303 html.name.should.equal('user.html');
1304 html.type.should.equal('text/html');
1305 read(html.path).should.equal('&lt;h1&gt;name&lt;/h1&gt;');
1306 total.should.equal(221);
1307 loaded.should.equal(221);
1308 done();
1309})</code></pre></dd>
1310 </dl>
1311 </section>
1312 </dl>
1313 </section>
1314 <section class="suite">
1315 <h1>with network error</h1>
1316 <dl>
1317 <dt>should error</dt>
1318 <dd><pre><code>request
1319.get('http://localhost:' + this.port + '/')
1320.end(function(err, res){
1321 assert(err, 'expected an error');
1322 done();
1323});</code></pre></dd>
1324 </dl>
1325 </section>
1326 <section class="suite">
1327 <h1>request</h1>
1328 <dl>
1329 <section class="suite">
1330 <h1>not modified</h1>
1331 <dl>
1332 <dt>should start with 200</dt>
1333 <dd><pre><code>request
1334.get('http://localhost:3008/')
1335.end(function(err, res){
1336 res.should.have.status(200)
1337 res.text.should.match(/^\d+$/);
1338 ts = +res.text;
1339 done();
1340});</code></pre></dd>
1341 <dt>should then be 304</dt>
1342 <dd><pre><code>request
1343.get('http://localhost:3008/')
1344.set('If-Modified-Since', new Date(ts).toUTCString())
1345.end(function(err, res){
1346 res.should.have.status(304)
1347 // res.text.should.be.empty
1348 done();
1349});</code></pre></dd>
1350 </dl>
1351 </section>
1352 </dl>
1353 </section>
1354 <section class="suite">
1355 <h1>req.parse(fn)</h1>
1356 <dl>
1357 <dt>should take precedence over default parsers</dt>
1358 <dd><pre><code>request
1359.get('http://localhost:3033/manny')
1360.parse(request.parse['application/json'])
1361.end(function(err, res){
1362 assert(res.ok);
1363 assert.equal('{&quot;name&quot;:&quot;manny&quot;}', res.text);
1364 assert.equal('manny', res.body.name);
1365 done();
1366});</code></pre></dd>
1367 <dt>should be the only parser</dt>
1368 <dd><pre><code>request
1369.get('http://localhost:3033/image')
1370.parse(function(res, fn) {
1371 res.on('data', function() {});
1372})
1373.end(function(err, res){
1374 assert(res.ok);
1375 assert.strictEqual(res.text, undefined);
1376 res.body.should.eql({});
1377 done();
1378});</code></pre></dd>
1379 <dt>should emit error if parser throws</dt>
1380 <dd><pre><code>request
1381.get('http://localhost:3033/manny')
1382.parse(function() {
1383 throw new Error('I am broken');
1384})
1385.on('error', function(err) {
1386 err.message.should.equal('I am broken');
1387 done();
1388})
1389.end();</code></pre></dd>
1390 <dt>should emit error if parser returns an error</dt>
1391 <dd><pre><code>request
1392.get('http://localhost:3033/manny')
1393.parse(function(res, fn) {
1394 fn(new Error('I am broken'));
1395})
1396.on('error', function(err) {
1397 err.message.should.equal('I am broken');
1398 done();
1399})
1400.end()</code></pre></dd>
1401 <dt>should not emit error on chunked json</dt>
1402 <dd><pre><code>request
1403.get('http://localhost:3033/chunked-json')
1404.end(function(err){
1405 assert(!err);
1406 done();
1407});</code></pre></dd>
1408 <dt>should not emit error on aborted chunked json</dt>
1409 <dd><pre><code>var req = request
1410.get('http://localhost:3033/chunked-json')
1411.end(function(err){
1412 assert(!err);
1413 done();
1414});
1415setTimeout(function(){req.abort()},50);</code></pre></dd>
1416 </dl>
1417 </section>
1418 <section class="suite">
1419 <h1>pipe on redirect</h1>
1420 <dl>
1421 <dt>should follow Location</dt>
1422 <dd><pre><code>var stream = fs.createWriteStream('test/node/fixtures/pipe.txt');
1423var redirects = [];
1424var req = request
1425 .get('http://localhost:3012/')
1426 .on('redirect', function (res) {
1427 redirects.push(res.headers.location);
1428 })
1429 .on('end', function () {
1430 var arr = [];
1431 arr.push('/movies');
1432 arr.push('/movies/all');
1433 arr.push('/movies/all/0');
1434 redirects.should.eql(arr);
1435 fs.readFileSync('test/node/fixtures/pipe.txt', 'utf8').should.eql('first movie page');
1436 done();
1437 });
1438 req.pipe(stream);</code></pre></dd>
1439 </dl>
1440 </section>
1441 <section class="suite">
1442 <h1>request pipe</h1>
1443 <dl>
1444 <dt>should act as a writable stream</dt>
1445 <dd><pre><code>var req = request.post('http://localhost:3020');
1446var stream = fs.createReadStream('test/node/fixtures/user.json');
1447req.type('json');
1448req.on('response', function(res){
1449 res.body.should.eql({ name: 'tobi' });
1450 done();
1451});
1452stream.pipe(req);</code></pre></dd>
1453 <dt>should act as a readable stream</dt>
1454 <dd><pre><code>var stream = fs.createWriteStream('test/node/fixtures/tmp.json');
1455var req = request.get('http://localhost:3025');
1456req.type('json');
1457req.on('end', function(){
1458 JSON.parse(fs.readFileSync('test/node/fixtures/tmp.json', 'utf8')).should.eql({ name: 'tobi' });
1459 done();
1460});
1461req.pipe(stream);</code></pre></dd>
1462 </dl>
1463 </section>
1464 <section class="suite">
1465 <h1>req.query(String)</h1>
1466 <dl>
1467 <dt>should supply uri malformed error to the callback</dt>
1468 <dd><pre><code>request
1469.get('http://localhost:3006')
1470.query('name=toby')
1471.query('a=\uD800')
1472.query({ b: '\uD800' })
1473.end(function(err, res){
1474 assert(err instanceof Error);
1475 assert.equal('URIError', err.name);
1476 done();
1477});</code></pre></dd>
1478 <dt>should support passing in a string</dt>
1479 <dd><pre><code>request
1480.del('http://localhost:3006')
1481.query('name=t%F6bi')
1482.end(function(err, res){
1483 res.body.should.eql({ name: 't%F6bi' });
1484 done();
1485});</code></pre></dd>
1486 <dt>should work with url query-string and string for query</dt>
1487 <dd><pre><code>request
1488.del('http://localhost:3006/?name=tobi')
1489.query('age=2%20')
1490.end(function(err, res){
1491 res.body.should.eql({ name: 'tobi', age: '2 ' });
1492 done();
1493});</code></pre></dd>
1494 <dt>should support compound elements in a string</dt>
1495 <dd><pre><code>request
1496 .del('http://localhost:3006/')
1497 .query('name=t%F6bi&amp;age=2')
1498 .end(function(err, res){
1499 res.body.should.eql({ name: 't%F6bi', age: '2' });
1500 done();
1501 });</code></pre></dd>
1502 <dt>should work when called multiple times with a string</dt>
1503 <dd><pre><code>request
1504.del('http://localhost:3006/')
1505.query('name=t%F6bi')
1506.query('age=2%F6')
1507.end(function(err, res){
1508 res.body.should.eql({ name: 't%F6bi', age: '2%F6' });
1509 done();
1510});</code></pre></dd>
1511 <dt>should work with normal `query` object and query string</dt>
1512 <dd><pre><code>request
1513.del('http://localhost:3006/')
1514.query('name=t%F6bi')
1515.query({ age: '2' })
1516.end(function(err, res){
1517 res.body.should.eql({ name: 't%F6bi', age: '2' });
1518 done();
1519});</code></pre></dd>
1520 </dl>
1521 </section>
1522 <section class="suite">
1523 <h1>req.query(Object)</h1>
1524 <dl>
1525 <dt>should construct the query-string</dt>
1526 <dd><pre><code>request
1527.del('http://localhost:3006/')
1528.query({ name: 'tobi' })
1529.query({ order: 'asc' })
1530.query({ limit: ['1', '2'] })
1531.end(function(err, res){
1532 res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] });
1533 done();
1534});</code></pre></dd>
1535 <dt>should not error on dates</dt>
1536 <dd><pre><code>var date = new Date(0);
1537request
1538.del('http://localhost:3006/')
1539.query({ at: date })
1540.end(function(err, res){
1541 assert.equal(date.toISOString(), res.body.at);
1542 done();
1543});</code></pre></dd>
1544 <dt>should work after setting header fields</dt>
1545 <dd><pre><code>request
1546.del('http://localhost:3006/')
1547.set('Foo', 'bar')
1548.set('Bar', 'baz')
1549.query({ name: 'tobi' })
1550.query({ order: 'asc' })
1551.query({ limit: ['1', '2'] })
1552.end(function(err, res){
1553 res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] });
1554 done();
1555});</code></pre></dd>
1556 <dt>should append to the original query-string</dt>
1557 <dd><pre><code>request
1558.del('http://localhost:3006/?name=tobi')
1559.query({ order: 'asc' })
1560.end(function(err, res) {
1561 res.body.should.eql({ name: 'tobi', order: 'asc' });
1562 done();
1563});</code></pre></dd>
1564 <dt>should retain the original query-string</dt>
1565 <dd><pre><code>request
1566.del('http://localhost:3006/?name=tobi')
1567.end(function(err, res) {
1568 res.body.should.eql({ name: 'tobi' });
1569 done();
1570});</code></pre></dd>
1571 </dl>
1572 </section>
1573 <section class="suite">
1574 <h1>request.get</h1>
1575 <dl>
1576 <section class="suite">
1577 <h1>on 301 redirect</h1>
1578 <dl>
1579 <dt>should follow Location with a GET request</dt>
1580 <dd><pre><code>var req = request
1581 .get('http://localhost:3210/test-301')
1582 .redirects(1)
1583 .end(function(err, res){
1584 req.req._headers.host.should.eql('localhost:3211');
1585 res.status.should.eql(200);
1586 res.text.should.eql('GET');
1587 done();
1588 });</code></pre></dd>
1589 </dl>
1590 </section>
1591 <section class="suite">
1592 <h1>on 302 redirect</h1>
1593 <dl>
1594 <dt>should follow Location with a GET request</dt>
1595 <dd><pre><code>var req = request
1596 .get('http://localhost:3210/test-302')
1597 .redirects(1)
1598 .end(function(err, res){
1599 req.req._headers.host.should.eql('localhost:3211');
1600 res.status.should.eql(200);
1601 res.text.should.eql('GET');
1602 done();
1603 });</code></pre></dd>
1604 </dl>
1605 </section>
1606 <section class="suite">
1607 <h1>on 303 redirect</h1>
1608 <dl>
1609 <dt>should follow Location with a GET request</dt>
1610 <dd><pre><code>var req = request
1611 .get('http://localhost:3210/test-303')
1612 .redirects(1)
1613 .end(function(err, res){
1614 req.req._headers.host.should.eql('localhost:3211');
1615 res.status.should.eql(200);
1616 res.text.should.eql('GET');
1617 done();
1618 });</code></pre></dd>
1619 </dl>
1620 </section>
1621 <section class="suite">
1622 <h1>on 307 redirect</h1>
1623 <dl>
1624 <dt>should follow Location with a GET request</dt>
1625 <dd><pre><code>var req = request
1626 .get('http://localhost:3210/test-307')
1627 .redirects(1)
1628 .end(function(err, res){
1629 req.req._headers.host.should.eql('localhost:3211');
1630 res.status.should.eql(200);
1631 res.text.should.eql('GET');
1632 done();
1633 });</code></pre></dd>
1634 </dl>
1635 </section>
1636 <section class="suite">
1637 <h1>on 308 redirect</h1>
1638 <dl>
1639 <dt>should follow Location with a GET request</dt>
1640 <dd><pre><code>var req = request
1641 .get('http://localhost:3210/test-308')
1642 .redirects(1)
1643 .end(function(err, res){
1644 req.req._headers.host.should.eql('localhost:3211');
1645 res.status.should.eql(200);
1646 res.text.should.eql('GET');
1647 done();
1648 });</code></pre></dd>
1649 </dl>
1650 </section>
1651 </dl>
1652 </section>
1653 <section class="suite">
1654 <h1>request.post</h1>
1655 <dl>
1656 <section class="suite">
1657 <h1>on 301 redirect</h1>
1658 <dl>
1659 <dt>should follow Location with a GET request</dt>
1660 <dd><pre><code>var req = request
1661 .post('http://localhost:3210/test-301')
1662 .redirects(1)
1663 .end(function(err, res){
1664 req.req._headers.host.should.eql('localhost:3211');
1665 res.status.should.eql(200);
1666 res.text.should.eql('GET');
1667 done();
1668 });</code></pre></dd>
1669 </dl>
1670 </section>
1671 <section class="suite">
1672 <h1>on 302 redirect</h1>
1673 <dl>
1674 <dt>should follow Location with a GET request</dt>
1675 <dd><pre><code>var req = request
1676 .post('http://localhost:3210/test-302')
1677 .redirects(1)
1678 .end(function(err, res){
1679 req.req._headers.host.should.eql('localhost:3211');
1680 res.status.should.eql(200);
1681 res.text.should.eql('GET');
1682 done();
1683 });</code></pre></dd>
1684 </dl>
1685 </section>
1686 <section class="suite">
1687 <h1>on 303 redirect</h1>
1688 <dl>
1689 <dt>should follow Location with a GET request</dt>
1690 <dd><pre><code>var req = request
1691 .post('http://localhost:3210/test-303')
1692 .redirects(1)
1693 .end(function(err, res){
1694 req.req._headers.host.should.eql('localhost:3211');
1695 res.status.should.eql(200);
1696 res.text.should.eql('GET');
1697 done();
1698 });</code></pre></dd>
1699 </dl>
1700 </section>
1701 <section class="suite">
1702 <h1>on 307 redirect</h1>
1703 <dl>
1704 <dt>should follow Location with a POST request</dt>
1705 <dd><pre><code>var req = request
1706 .post('http://localhost:3210/test-307')
1707 .redirects(1)
1708 .end(function(err, res){
1709 req.req._headers.host.should.eql('localhost:3211');
1710 res.status.should.eql(200);
1711 res.text.should.eql('POST');
1712 done();
1713 });</code></pre></dd>
1714 </dl>
1715 </section>
1716 <section class="suite">
1717 <h1>on 308 redirect</h1>
1718 <dl>
1719 <dt>should follow Location with a POST request</dt>
1720 <dd><pre><code>var req = request
1721 .post('http://localhost:3210/test-308')
1722 .redirects(1)
1723 .end(function(err, res){
1724 req.req._headers.host.should.eql('localhost:3211');
1725 res.status.should.eql(200);
1726 res.text.should.eql('POST');
1727 done();
1728 });</code></pre></dd>
1729 </dl>
1730 </section>
1731 </dl>
1732 </section>
1733 <section class="suite">
1734 <h1>request</h1>
1735 <dl>
1736 <section class="suite">
1737 <h1>on redirect</h1>
1738 <dl>
1739 <dt>should follow Location</dt>
1740 <dd><pre><code>var redirects = [];
1741request
1742.get('http://localhost:3003/')
1743.on('redirect', function(res){
1744 redirects.push(res.headers.location);
1745})
1746.end(function(err, res){
1747 var arr = [];
1748 arr.push('/movies');
1749 arr.push('/movies/all');
1750 arr.push('/movies/all/0');
1751 redirects.should.eql(arr);
1752 res.text.should.equal('first movie page');
1753 done();
1754});</code></pre></dd>
1755 <dt>should retain header fields</dt>
1756 <dd><pre><code>request
1757.get('http://localhost:3003/header')
1758.set('X-Foo', 'bar')
1759.end(function(err, res){
1760 res.body.should.have.property('x-foo', 'bar');
1761 done();
1762});</code></pre></dd>
1763 <dt>should remove Content-* fields</dt>
1764 <dd><pre><code>request
1765.post('http://localhost:3003/header')
1766.type('txt')
1767.set('X-Foo', 'bar')
1768.set('X-Bar', 'baz')
1769.send('hey')
1770.end(function(err, res){
1771 res.body.should.have.property('x-foo', 'bar');
1772 res.body.should.have.property('x-bar', 'baz');
1773 res.body.should.not.have.property('content-type');
1774 res.body.should.not.have.property('content-length');
1775 res.body.should.not.have.property('transfer-encoding');
1776 done();
1777});</code></pre></dd>
1778 <dt>should retain cookies</dt>
1779 <dd><pre><code>request
1780.get('http://localhost:3003/header')
1781.set('Cookie', 'foo=bar;')
1782.end(function(err, res){
1783 res.body.should.have.property('cookie', 'foo=bar;');
1784 done();
1785});</code></pre></dd>
1786 <dt>should preserve timeout across redirects</dt>
1787 <dd><pre><code>request
1788.get('http://localhost:3003/movies/random')
1789.timeout(250)
1790.end(function(err, res){
1791 assert(err instanceof Error, 'expected an error');
1792 err.should.have.property('timeout', 250);
1793 done();
1794});</code></pre></dd>
1795 <dt>should not resend query parameters</dt>
1796 <dd><pre><code>var redirects = [];
1797var query = [];
1798request
1799.get('http://localhost:3003/?foo=bar')
1800.on('redirect', function(res){
1801 query.push(res.headers.query);
1802 redirects.push(res.headers.location);
1803})
1804.end(function(err, res){
1805 var arr = [];
1806 arr.push('/movies');
1807 arr.push('/movies/all');
1808 arr.push('/movies/all/0');
1809 redirects.should.eql(arr);
1810 res.text.should.equal('first movie page');
1811 query.should.eql(['{&quot;foo&quot;:&quot;bar&quot;}', '{}', '{}']);
1812 res.headers.query.should.eql('{}');
1813 done();
1814});</code></pre></dd>
1815 <dt>should handle no location header</dt>
1816 <dd><pre><code>request
1817.get('http://localhost:3003/bad-redirect')
1818.end(function(err, res){
1819 err.message.should.equal('No location header for redirect');
1820 done();
1821});</code></pre></dd>
1822 <section class="suite">
1823 <h1>when relative</h1>
1824 <dl>
1825 <dt>should redirect to a sibling path</dt>
1826 <dd><pre><code>var redirects = [];
1827request
1828.get('http://localhost:3003/relative')
1829.on('redirect', function(res){
1830 redirects.push(res.headers.location);
1831})
1832.end(function(err, res){
1833 var arr = [];
1834 redirects.should.eql(['tobi']);
1835 res.text.should.equal('tobi');
1836 done();
1837});</code></pre></dd>
1838 <dt>should redirect to a parent path</dt>
1839 <dd><pre><code>var redirects = [];
1840request
1841.get('http://localhost:3003/relative/sub')
1842.on('redirect', function(res){
1843 redirects.push(res.headers.location);
1844})
1845.end(function(err, res){
1846 var arr = [];
1847 redirects.should.eql(['../tobi']);
1848 res.text.should.equal('tobi');
1849 done();
1850});</code></pre></dd>
1851 </dl>
1852 </section>
1853 </dl>
1854 </section>
1855 <section class="suite">
1856 <h1>req.redirects(n)</h1>
1857 <dl>
1858 <dt>should alter the default number of redirects to follow</dt>
1859 <dd><pre><code>var redirects = [];
1860request
1861.get('http://localhost:3003/')
1862.redirects(2)
1863.on('redirect', function(res){
1864 redirects.push(res.headers.location);
1865})
1866.end(function(err, res){
1867 var arr = [];
1868 assert(res.redirect, 'res.redirect');
1869 arr.push('/movies');
1870 arr.push('/movies/all');
1871 redirects.should.eql(arr);
1872 res.text.should.match(/Moved Temporarily|Found/);
1873 done();
1874});</code></pre></dd>
1875 </dl>
1876 </section>
1877 <section class="suite">
1878 <h1>on POST</h1>
1879 <dl>
1880 <dt>should redirect as GET</dt>
1881 <dd><pre><code>var redirects = [];
1882request
1883.post('http://localhost:3003/movie')
1884.send({ name: 'Tobi' })
1885.redirects(2)
1886.on('redirect', function(res){
1887 redirects.push(res.headers.location);
1888})
1889.end(function(err, res){
1890 var arr = [];
1891 arr.push('/movies/all/0');
1892 redirects.should.eql(arr);
1893 res.text.should.equal('first movie page');
1894 done();
1895});</code></pre></dd>
1896 </dl>
1897 </section>
1898 <section class="suite">
1899 <h1>on 303</h1>
1900 <dl>
1901 <dt>should redirect with same method</dt>
1902 <dd><pre><code>request
1903.put('http://localhost:3003/redirect-303')
1904.send({msg: &quot;hello&quot;})
1905.redirects(1)
1906.on('redirect', function(res) {
1907 res.headers.location.should.equal('/reply-method')
1908})
1909.end(function(err, res){
1910 res.text.should.equal('method=get');
1911 done();
1912})</code></pre></dd>
1913 </dl>
1914 </section>
1915 <section class="suite">
1916 <h1>on 307</h1>
1917 <dl>
1918 <dt>should redirect with same method</dt>
1919 <dd><pre><code>request
1920.put('http://localhost:3003/redirect-307')
1921.send({msg: &quot;hello&quot;})
1922.redirects(1)
1923.on('redirect', function(res) {
1924 res.headers.location.should.equal('/reply-method')
1925})
1926.end(function(err, res){
1927 res.text.should.equal('method=put');
1928 done();
1929})</code></pre></dd>
1930 </dl>
1931 </section>
1932 <section class="suite">
1933 <h1>on 308</h1>
1934 <dl>
1935 <dt>should redirect with same method</dt>
1936 <dd><pre><code>request
1937.put('http://localhost:3003/redirect-308')
1938.send({msg: &quot;hello&quot;})
1939.redirects(1)
1940.on('redirect', function(res) {
1941 res.headers.location.should.equal('/reply-method')
1942})
1943.end(function(err, res){
1944 res.text.should.equal('method=put');
1945 done();
1946})</code></pre></dd>
1947 </dl>
1948 </section>
1949 </dl>
1950 </section>
1951 <section class="suite">
1952 <h1>response</h1>
1953 <dl>
1954 <dt>should act as a readable stream</dt>
1955 <dd><pre><code>var req = request
1956 .get('http://localhost:3025')
1957 .buffer(false);
1958req.end(function(err,res){
1959 if (err) return done(err);
1960 var trackEndEvent = 0;
1961 var trackCloseEvent = 0;
1962 res.on('end',function(){
1963 trackEndEvent++;
1964 trackEndEvent.should.equal(1);
1965 trackCloseEvent.should.equal(0); // close should not have been called
1966 done();
1967 });
1968 res.on('close',function(){
1969 trackCloseEvent++;
1970 });
1971
1972 (function(){ res.pause() }).should.not.throw();
1973 (function(){ res.resume() }).should.not.throw();
1974 (function(){ res.destroy() }).should.not.throw();
1975});</code></pre></dd>
1976 </dl>
1977 </section>
1978 <section class="suite">
1979 <h1>.timeout(ms)</h1>
1980 <dl>
1981 <section class="suite">
1982 <h1>when timeout is exceeded</h1>
1983 <dl>
1984 <dt>should error</dt>
1985 <dd><pre><code>request
1986.get('http://localhost:3009/500')
1987.timeout(150)
1988.end(function(err, res){
1989 assert(err, 'expected an error');
1990 assert.equal('number', typeof err.timeout, 'expected an error with .timeout');
1991 assert.equal('ECONNABORTED', err.code, 'expected abort error code')
1992 done();
1993});</code></pre></dd>
1994 </dl>
1995 </section>
1996 </dl>
1997 </section>
1998 <section class="suite">
1999 <h1>res.toError()</h1>
2000 <dl>
2001 <dt>should return an Error</dt>
2002 <dd><pre><code>request
2003.get('http://localhost:' + server.address().port)
2004.end(function(err, res){
2005 var err = res.toError();
2006 assert.equal(err.status, 400);
2007 assert.equal(err.method, 'GET');
2008 assert.equal(err.path, '/');
2009 assert.equal(err.message, 'cannot GET / (400)');
2010 assert.equal(err.text, 'invalid json');
2011 done();
2012});</code></pre></dd>
2013 </dl>
2014 </section>
2015 <section class="suite">
2016 <h1>req.get()</h1>
2017 <dl>
2018 <dt>should set a default user-agent</dt>
2019 <dd><pre><code>request
2020.get('http://localhost:3345/ua')
2021.end(function(err, res){
2022 assert(res.headers);
2023 assert(res.headers['user-agent']);
2024 assert(/^node-superagent\/\d+\.\d+\.\d+$/.test(res.headers['user-agent']));
2025 done();
2026});</code></pre></dd>
2027 <dt>should be able to override user-agent</dt>
2028 <dd><pre><code>request
2029.get('http://localhost:3345/ua')
2030.set('User-Agent', 'foo/bar')
2031.end(function(err, res){
2032 assert(res.headers);
2033 assert.equal(res.headers['user-agent'], 'foo/bar');
2034 done();
2035});</code></pre></dd>
2036 <dt>should be able to wipe user-agent</dt>
2037 <dd><pre><code>request
2038.get('http://localhost:3345/ua')
2039.unset('User-Agent')
2040.end(function(err, res){
2041 assert(res.headers);
2042 assert.equal(res.headers['user-agent'], void 0);
2043 done();
2044});</code></pre></dd>
2045 </dl>
2046 </section>
2047 <section class="suite">
2048 <h1>utils.type(str)</h1>
2049 <dl>
2050 <dt>should return the mime type</dt>
2051 <dd><pre><code>utils.type('application/json; charset=utf-8')
2052 .should.equal('application/json');
2053utils.type('application/json')
2054 .should.equal('application/json');</code></pre></dd>
2055 </dl>
2056 </section>
2057 <section class="suite">
2058 <h1>utils.params(str)</h1>
2059 <dl>
2060 <dt>should return the field parameters</dt>
2061 <dd><pre><code>var str = 'application/json; charset=utf-8; foo = bar';
2062var obj = utils.params(str);
2063obj.charset.should.equal('utf-8');
2064obj.foo.should.equal('bar');
2065var str = 'application/json';
2066utils.params(str).should.eql({});</code></pre></dd>
2067 </dl>
2068 </section>
2069 <section class="suite">
2070 <h1>utils.parseLinks(str)</h1>
2071 <dl>
2072 <dt>should parse links</dt>
2073 <dd><pre><code>var str = '&lt;https://api.github.com/repos/visionmedia/mocha/issues?page=2&gt;; rel=&quot;next&quot;, &lt;https://api.github.com/repos/visionmedia/mocha/issues?page=5&gt;; rel=&quot;last&quot;';
2074var ret = utils.parseLinks(str);
2075ret.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2');
2076ret.last.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=5');</code></pre></dd>
2077 </dl>
2078 </section>
2079 </div>
2080 <a href="http://github.com/visionmedia/superagent"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png" alt="Fork me on GitHub"></a>
2081 </body>
2082</html>