UNPKG

superagent

Version:

elegant & feature rich browser / node HTTP with a fluent API

1,587 lines (1,586 loc) 167 kB
<!DOCTYPE html> <html> <head> <meta charset="utf8"> <title>SuperAgent — elegant API for AJAX in Node and browsers</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/3.0.0/tocbot.css"> <link rel="stylesheet" href="docs/style.css"> </head> <body> <ul id="menu"></ul> <div id="content"> <section class="suite"> <h1>Agent</h1> <dl> <dt>should remember defaults</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } let called = 0; let event_called = 0; const agent = request .agent() .accept(&#x27;json&#x27;) .use(() =&#x3E; { called++; }) .once(&#x27;request&#x27;, () =&#x3E; { event_called++; }) .query({ hello: &#x27;world&#x27; }) .set(&#x27;X-test&#x27;, &#x27;testing&#x27;); assert.equal(0, called); assert.equal(0, event_called); return agent .get(&#x60;${base}/echo&#x60;) .then(res =&#x3E; { assert.equal(1, called); assert.equal(1, event_called); assert.equal(&#x27;application/json&#x27;, res.headers.accept); assert.equal(&#x27;testing&#x27;, res.headers[&#x27;x-test&#x27;]); return agent.get(&#x60;${base}/querystring&#x60;); }) .then(res =&#x3E; { assert.equal(2, called); assert.equal(2, event_called); assert.deepEqual({ hello: &#x27;world&#x27; }, res.body); });</code></pre></dd> </dl> </section> <section class="suite"> <h1>request</h1> <dl> <section class="suite"> <h1>res.statusCode</h1> <dl> <dt>should set statusCode</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;, (err, res) =&#x3E; { try { assert.strictEqual(res.statusCode, 200); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>should allow the send shorthand</h1> <dl> <dt>with callback in the method call</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;, (err, res) =&#x3E; { assert.equal(res.status, 200); done(); }); }</code></pre></dd> <dt>with data in the method call</dt> <dd><pre><code>done =&#x3E; { request.post(&#x60;${uri}/echo&#x60;, { foo: &#x27;bar&#x27; }).end((err, res) =&#x3E; { assert.equal(&#x27;{&#x22;foo&#x22;:&#x22;bar&#x22;}&#x27;, res.text); done(); }); }</code></pre></dd> <dt>with callback and data in the method call</dt> <dd><pre><code>done =&#x3E; { request.post(&#x60;${uri}/echo&#x60;, { foo: &#x27;bar&#x27; }, (err, res) =&#x3E; { assert.equal(&#x27;{&#x22;foo&#x22;:&#x22;bar&#x22;}&#x27;, res.text); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>with a callback</h1> <dl> <dt>should invoke .end()</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;, (err, res) =&#x3E; { try { assert.equal(res.status, 200); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>.end()</h1> <dl> <dt>should issue a request</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;).end((err, res) =&#x3E; { try { assert.equal(res.status, 200); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>is optional with a promise</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } return request .get(&#x60;${uri}/login&#x60;) .then(res =&#x3E; res.status) .then() .then(status =&#x3E; { assert.equal(200, status, &#x27;Real promises pass results through&#x27;); });</code></pre></dd> <dt>called only once with a promise</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } const req = request.get(&#x60;${uri}/unique&#x60;); return Promise.all([req, req, req]).then(results =&#x3E; { results.forEach(item =&#x3E; { assert.equal( item.body, results[0].body, &#x27;It should keep returning the same result after being called once&#x27; ); }); });</code></pre></dd> </dl> </section> <section class="suite"> <h1>res.error</h1> <dl> <dt>ok</dt> <dd><pre><code>done =&#x3E; { let calledErrorEvent = false; let calledOKHandler = false; request .get(&#x60;${uri}/error&#x60;) .ok(res =&#x3E; { assert.strictEqual(500, res.status); calledOKHandler = true; return true; }) .on(&#x27;error&#x27;, err =&#x3E; { calledErrorEvent = true; }) .end((err, res) =&#x3E; { try { assert.ifError(err); assert.strictEqual(res.status, 500); assert(!calledErrorEvent); assert(calledOKHandler); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should should be an Error object</dt> <dd><pre><code>done =&#x3E; { let calledErrorEvent = false; request .get(&#x60;${uri}/error&#x60;) .on(&#x27;error&#x27;, err =&#x3E; { assert.strictEqual(err.status, 500); calledErrorEvent = true; }) .end((err, res) =&#x3E; { try { if (NODE) { res.error.message.should.equal(&#x27;cannot GET /error (500)&#x27;); } else { res.error.message.should.equal(&#x60;cannot GET ${uri}/error (500)&#x60;); } assert.strictEqual(res.error.status, 500); assert(err, &#x27;should have an error for 500&#x27;); assert.equal(err.message, &#x27;Internal Server Error&#x27;); assert(calledErrorEvent); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>with .then() promise</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } return request.get(&#x60;${uri}/error&#x60;).then( () =&#x3E; { assert.fail(); }, err =&#x3E; { assert.equal(err.message, &#x27;Internal Server Error&#x27;); } );</code></pre></dd> <dt>with .ok() returning false</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } return request .get(&#x60;${uri}/echo&#x60;) .ok(() =&#x3E; false) .then( () =&#x3E; { assert.fail(); }, err =&#x3E; { assert.equal(200, err.response.status); assert.equal(err.message, &#x27;OK&#x27;); } );</code></pre></dd> <dt>with .ok() throwing an Error</dt> <dd><pre><code>if (typeof Promise === &#x27;undefined&#x27;) { return; } return request .get(&#x60;${uri}/echo&#x60;) .ok(() =&#x3E; { throw new Error(&#x27;boom&#x27;); }) .then( () =&#x3E; { assert.fail(); }, err =&#x3E; { assert.equal(200, err.response.status); assert.equal(err.message, &#x27;boom&#x27;); } );</code></pre></dd> </dl> </section> <section class="suite"> <h1>res.header</h1> <dl> <dt>should be an object</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;).end((err, res) =&#x3E; { try { assert.equal(&#x27;Express&#x27;, res.header[&#x27;x-powered-by&#x27;]); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>set headers</h1> <dl> <dt>should only set headers for ownProperties of header</dt> <dd><pre><code>done =&#x3E; { try { request .get(&#x60;${uri}/echo-headers&#x60;) .set(&#x27;valid&#x27;, &#x27;ok&#x27;) .end((err, res) =&#x3E; { if ( !err &#x26;&#x26; res.body &#x26;&#x26; res.body.valid &#x26;&#x26; !res.body.hasOwnProperty(&#x27;invalid&#x27;) ) { return done(); } done(err || new Error(&#x27;fail&#x27;)); }); } catch (err) { done(err); } }</code></pre></dd> </dl> </section> <section class="suite"> <h1>res.charset</h1> <dl> <dt>should be set when present</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;).end((err, res) =&#x3E; { try { res.charset.should.equal(&#x27;utf-8&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>res.statusType</h1> <dl> <dt>should provide the first digit</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;).end((err, res) =&#x3E; { try { assert(!err, &#x27;should not have an error for success responses&#x27;); assert.equal(200, res.status); assert.equal(2, res.statusType); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>res.type</h1> <dl> <dt>should provide the mime-type void of params</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/login&#x60;).end((err, res) =&#x3E; { try { res.type.should.equal(&#x27;text/html&#x27;); res.charset.should.equal(&#x27;utf-8&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.set(field, val)</h1> <dl> <dt>should set the header field</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .set(&#x27;X-Foo&#x27;, &#x27;bar&#x27;) .set(&#x27;X-Bar&#x27;, &#x27;baz&#x27;) .end((err, res) =&#x3E; { try { assert.equal(&#x27;bar&#x27;, res.header[&#x27;x-foo&#x27;]); assert.equal(&#x27;baz&#x27;, res.header[&#x27;x-bar&#x27;]); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.set(obj)</h1> <dl> <dt>should set the header fields</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .set({ &#x27;X-Foo&#x27;: &#x27;bar&#x27;, &#x27;X-Bar&#x27;: &#x27;baz&#x27; }) .end((err, res) =&#x3E; { try { assert.equal(&#x27;bar&#x27;, res.header[&#x27;x-foo&#x27;]); assert.equal(&#x27;baz&#x27;, res.header[&#x27;x-bar&#x27;]); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.type(str)</h1> <dl> <dt>should set the Content-Type</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;text/x-foo&#x27;) .end((err, res) =&#x3E; { try { res.header[&#x27;content-type&#x27;].should.equal(&#x27;text/x-foo&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should map &#x22;json&#x22;</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;{&#x22;a&#x22;: 1}&#x27;) .end((err, res) =&#x3E; { try { res.should.be.json(); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should map &#x22;html&#x22;</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;html&#x27;) .end((err, res) =&#x3E; { try { res.header[&#x27;content-type&#x27;].should.equal(&#x27;text/html&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.accept(str)</h1> <dl> <dt>should set Accept</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/echo&#x60;) .accept(&#x27;text/x-foo&#x27;) .end((err, res) =&#x3E; { try { res.header.accept.should.equal(&#x27;text/x-foo&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should map &#x22;json&#x22;</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/echo&#x60;) .accept(&#x27;json&#x27;) .end((err, res) =&#x3E; { try { res.header.accept.should.equal(&#x27;application/json&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should map &#x22;xml&#x22;</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/echo&#x60;) .accept(&#x27;xml&#x27;) .end((err, res) =&#x3E; { try { // Mime module keeps changing this :( assert( res.header.accept == &#x27;application/xml&#x27; || res.header.accept == &#x27;text/xml&#x27; ); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should map &#x22;html&#x22;</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/echo&#x60;) .accept(&#x27;html&#x27;) .end((err, res) =&#x3E; { try { res.header.accept.should.equal(&#x27;text/html&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.send(str)</h1> <dl> <dt>should write the string</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;) .end((err, res) =&#x3E; { try { res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.send(Object)</h1> <dl> <dt>should default to json</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { try { res.should.be.json(); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <section class="suite"> <h1>when called several times</h1> <dl> <dt>should merge the objects</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .send({ age: 1 }) .end((err, res) =&#x3E; { try { res.should.be.json(); if (NODE) { res.buffered.should.be.true(); } res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;,&#x22;age&#x22;:1}&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>.end(fn)</h1> <dl> <dt>should check arity</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { try { assert.ifError(err); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should emit request</dt> <dd><pre><code>done =&#x3E; { const req = request.post(&#x60;${uri}/echo&#x60;); req.on(&#x27;request&#x27;, request =&#x3E; { assert.equal(req, request); done(); }); req.end(); }</code></pre></dd> <dt>should emit response</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .on(&#x27;response&#x27;, res =&#x3E; { res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); }) .end(); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>.then(fulfill, reject)</h1> <dl> <dt>should support successful fulfills with .then(fulfill)</dt> <dd><pre><code>done =&#x3E; { if (typeof Promise === &#x27;undefined&#x27;) { return done(); } request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .then(res =&#x3E; { res.type.should.equal(&#x27;application/json&#x27;); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); }); }</code></pre></dd> <dt>should reject an error with .then(null, reject)</dt> <dd><pre><code>done =&#x3E; { if (typeof Promise === &#x27;undefined&#x27;) { return done(); } request.get(&#x60;${uri}/error&#x60;).then(null, err =&#x3E; { assert.equal(err.status, 500); assert.equal(err.response.text, &#x27;boom&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>.catch(reject)</h1> <dl> <dt>should reject an error with .catch(reject)</dt> <dd><pre><code>done =&#x3E; { if (typeof Promise === &#x27;undefined&#x27;) { return done(); } request.get(&#x60;${uri}/error&#x60;).catch(err =&#x3E; { assert.equal(err.status, 500); assert.equal(err.response.text, &#x27;boom&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>.abort()</h1> <dl> <dt>should abort the request</dt> <dd><pre><code>done =&#x3E; { const req = request.get(&#x60;${uri}/delay/3000&#x60;); req.end((err, res) =&#x3E; { try { assert(false, &#x27;should not complete the request&#x27;); } catch (err2) { done(err2); } }); req.on(&#x27;error&#x27;, error =&#x3E; { done(error); }); req.on(&#x27;abort&#x27;, done); setTimeout(() =&#x3E; { req.abort(); }, 500); }</code></pre></dd> <dt>should abort the promise</dt> <dd><pre><code>const req = request.get(&#x60;${uri}/delay/3000&#x60;); setTimeout(() =&#x3E; { req.abort(); }, 10); return req.then( () =&#x3E; { assert.fail(&#x27;should not complete the request&#x27;); }, err =&#x3E; { assert.equal(&#x27;ABORTED&#x27;, err.code); } );</code></pre></dd> <dt>should allow chaining .abort() several times</dt> <dd><pre><code>done =&#x3E; { const req = request.get(&#x60;${uri}/delay/3000&#x60;); req.end((err, res) =&#x3E; { try { assert(false, &#x27;should not complete the request&#x27;); } catch (err2) { done(err2); } }); // This also verifies only a single &#x27;done&#x27; event is emitted req.on(&#x27;abort&#x27;, done); setTimeout(() =&#x3E; { req .abort() .abort() .abort(); }, 1000); }</code></pre></dd> <dt>should not allow abort then end</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/delay/3000&#x60;) .abort() .end((err, res) =&#x3E; { done(err ? undefined : new Error(&#x27;Expected abort error&#x27;)); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.toJSON()</h1> <dl> <dt>should describe the request</dt> <dd><pre><code>done =&#x3E; { const req = request.post(&#x60;${uri}/echo&#x60;).send({ foo: &#x27;baz&#x27; }); req.end((err, res) =&#x3E; { try { const json = req.toJSON(); assert.equal(&#x27;POST&#x27;, json.method); assert(/\/echo$/.test(json.url)); assert.equal(&#x27;baz&#x27;, json.data.foo); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.options()</h1> <dl> <dt>should allow request body</dt> <dd><pre><code>done =&#x3E; { request .options(&#x60;${uri}/options/echo/body&#x60;) .send({ foo: &#x27;baz&#x27; }) .end((err, res) =&#x3E; { try { assert.equal(err, null); assert.strictEqual(res.body.foo, &#x27;baz&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.sortQuery()</h1> <dl> <dt>nop with no querystring</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/url&#x60;) .sortQuery() .end((err, res) =&#x3E; { try { assert.equal(res.text, &#x27;/url&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should sort the request querystring</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/url&#x60;) .query(&#x27;search=Manny&#x27;) .query(&#x27;order=desc&#x27;) .sortQuery() .end((err, res) =&#x3E; { try { assert.equal(res.text, &#x27;/url?order=desc&#x26;search=Manny&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should allow disabling sorting</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/url&#x60;) .query(&#x27;search=Manny&#x27;) .query(&#x27;order=desc&#x27;) .sortQuery() // take default of true .sortQuery(false) // override it in later call .end((err, res) =&#x3E; { try { assert.equal(res.text, &#x27;/url?search=Manny&#x26;order=desc&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should sort the request querystring using customized function</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/url&#x60;) .query(&#x27;name=Nick&#x27;) .query(&#x27;search=Manny&#x27;) .query(&#x27;order=desc&#x27;) .sortQuery((a, b) =&#x3E; a.length - b.length) .end((err, res) =&#x3E; { try { assert.equal(res.text, &#x27;/url?name=Nick&#x26;order=desc&#x26;search=Manny&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>req.set(&#x22;Content-Type&#x22;, contentType)</h1> <dl> <dt>should work with just the contentType component</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .set(&#x27;Content-Type&#x27;, &#x27;application/json&#x27;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { assert(!err); done(); }); }</code></pre></dd> <dt>should work with the charset component</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .set(&#x27;Content-Type&#x27;, &#x27;application/json; charset=utf-8&#x27;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { assert(!err); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.send(Object) as &#x22;form&#x22;</h1> <dl> <section class="suite"> <h1>with req.type() set to form</h1> <dl> <dt>should send x-www-form-urlencoded data</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${base}/echo&#x60;) .type(&#x27;form&#x27;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { res.header[&#x27;content-type&#x27;].should.equal( &#x27;application/x-www-form-urlencoded&#x27; ); res.text.should.equal(&#x27;name=tobi&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>when called several times</h1> <dl> <dt>should merge the objects</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${base}/echo&#x60;) .type(&#x27;form&#x27;) .send({ name: { first: &#x27;tobi&#x27;, last: &#x27;holowaychuk&#x27; } }) .send({ age: &#x27;1&#x27; }) .end((err, res) =&#x3E; { res.header[&#x27;content-type&#x27;].should.equal( &#x27;application/x-www-form-urlencoded&#x27; ); res.text.should.equal( &#x27;name%5Bfirst%5D=tobi&#x26;name%5Blast%5D=holowaychuk&#x26;age=1&#x27; ); done(); }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>req.attach</h1> <dl> <dt>ignores null file</dt> <dd><pre><code>done =&#x3E; { request .post(&#x27;/echo&#x27;) .attach(&#x27;image&#x27;, null) .end((err, res) =&#x3E; { done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.field</h1> <dl> <dt>allow bools</dt> <dd><pre><code>done =&#x3E; { if (!formDataSupported) { return done(); } request .post(&#x60;${base}/formecho&#x60;) .field(&#x27;bools&#x27;, true) .field(&#x27;strings&#x27;, &#x27;true&#x27;) .end((err, res) =&#x3E; { assert.ifError(err); assert.deepStrictEqual(res.body, { bools: &#x27;true&#x27;, strings: &#x27;true&#x27; }); done(); }); }</code></pre></dd> <dt>allow objects</dt> <dd><pre><code>done =&#x3E; { if (!formDataSupported) { return done(); } request .post(&#x60;${base}/formecho&#x60;) .field({ bools: true, strings: &#x27;true&#x27; }) .end((err, res) =&#x3E; { assert.ifError(err); assert.deepStrictEqual(res.body, { bools: &#x27;true&#x27;, strings: &#x27;true&#x27; }); done(); }); }</code></pre></dd> <dt>works with arrays in objects</dt> <dd><pre><code>done =&#x3E; { if (!formDataSupported) { return done(); } request .post(&#x60;${base}/formecho&#x60;) .field({ numbers: [1, 2, 3] }) .end((err, res) =&#x3E; { assert.ifError(err); assert.deepStrictEqual(res.body, { numbers: [&#x27;1&#x27;, &#x27;2&#x27;, &#x27;3&#x27;] }); done(); }); }</code></pre></dd> <dt>works with arrays</dt> <dd><pre><code>done =&#x3E; { if (!formDataSupported) { return done(); } request .post(&#x60;${base}/formecho&#x60;) .field(&#x27;letters&#x27;, [&#x27;a&#x27;, &#x27;b&#x27;, &#x27;c&#x27;]) .end((err, res) =&#x3E; { assert.ifError(err); assert.deepStrictEqual(res.body, { letters: [&#x27;a&#x27;, &#x27;b&#x27;, &#x27;c&#x27;] }); done(); }); }</code></pre></dd> <dt>throw when empty</dt> <dd><pre><code>should.throws(() =&#x3E; { request.post(&#x60;${base}/echo&#x60;).field(); }, /name/); should.throws(() =&#x3E; { request.post(&#x60;${base}/echo&#x60;).field(&#x27;name&#x27;); }, /val/);</code></pre></dd> <dt>cannot be mixed with send()</dt> <dd><pre><code>assert.throws(() =&#x3E; { request .post(&#x27;/echo&#x27;) .field(&#x27;form&#x27;, &#x27;data&#x27;) .send(&#x27;hi&#x27;); }); assert.throws(() =&#x3E; { request .post(&#x27;/echo&#x27;) .send(&#x27;hi&#x27;) .field(&#x27;form&#x27;, &#x27;data&#x27;); });</code></pre></dd> </dl> </section> <section class="suite"> <h1>req.send(Object) as &#x22;json&#x22;</h1> <dl> <dt>should default to json</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .end((err, res) =&#x3E; { res.should.be.json(); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;}&#x27;); done(); }); }</code></pre></dd> <dt>should work with arrays</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send([1, 2, 3]) .end((err, res) =&#x3E; { res.should.be.json(); res.text.should.equal(&#x27;[1,2,3]&#x27;); done(); }); }</code></pre></dd> <dt>should work with value null</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;null&#x27;) .end((err, res) =&#x3E; { res.should.be.json(); assert.strictEqual(res.body, null); done(); }); }</code></pre></dd> <dt>should work with value false</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;false&#x27;) .end((err, res) =&#x3E; { res.should.be.json(); res.body.should.equal(false); done(); }); }</code></pre></dd> <dt>should work with value 0</dt> <dd><pre><code>done =&#x3E; { // fails in IE9 request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;0&#x27;) .end((err, res) =&#x3E; { res.should.be.json(); res.body.should.equal(0); done(); }); }</code></pre></dd> <dt>should work with empty string value</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .type(&#x27;json&#x27;) .send(&#x27;&#x22;&#x22;&#x27;) .end((err, res) =&#x3E; { res.should.be.json(); res.body.should.equal(&#x27;&#x27;); done(); }); }</code></pre></dd> <dt>should work with GET</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${uri}/echo&#x60;) .send({ tobi: &#x27;ferret&#x27; }) .end((err, res) =&#x3E; { try { res.should.be.json(); res.text.should.equal(&#x27;{&#x22;tobi&#x22;:&#x22;ferret&#x22;}&#x27;); ({ tobi: &#x27;ferret&#x27; }.should.eql(res.body)); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should work with vendor MIME type</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .set(&#x27;Content-Type&#x27;, &#x27;application/vnd.example+json&#x27;) .send({ name: &#x27;vendor&#x27; }) .end((err, res) =&#x3E; { res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;vendor&#x22;}&#x27;); ({ name: &#x27;vendor&#x27; }.should.eql(res.body)); done(); }); }</code></pre></dd> <section class="suite"> <h1>when called several times</h1> <dl> <dt>should merge the objects</dt> <dd><pre><code>done =&#x3E; { request .post(&#x60;${uri}/echo&#x60;) .send({ name: &#x27;tobi&#x27; }) .send({ age: 1 }) .end((err, res) =&#x3E; { res.should.be.json(); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;tobi&#x22;,&#x22;age&#x22;:1}&#x27;); ({ name: &#x27;tobi&#x27;, age: 1 }.should.eql(res.body)); done(); }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>res.body</h1> <dl> <section class="suite"> <h1>application/json</h1> <dl> <dt>should parse the body</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/json&#x60;).end((err, res) =&#x3E; { res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;manny&#x22;}&#x27;); res.body.should.eql({ name: &#x27;manny&#x27; }); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>HEAD requests</h1> <dl> <dt>should not throw a parse error</dt> <dd><pre><code>done =&#x3E; { request.head(&#x60;${uri}/json&#x60;).end((err, res) =&#x3E; { try { assert.strictEqual(err, null); assert.strictEqual(res.text, undefined); assert.strictEqual(Object.keys(res.body).length, 0); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>Invalid JSON response</h1> <dl> <dt>should return the raw response</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/invalid-json&#x60;).end((err, res) =&#x3E; { assert.deepEqual( err.rawResponse, &#x22;)]}&#x27;, {&#x27;header&#x27;:{&#x27;code&#x27;:200,&#x27;text&#x27;:&#x27;OK&#x27;,&#x27;version&#x27;:&#x27;1.0&#x27;},&#x27;data&#x27;:&#x27;some data&#x27;}&#x22; ); done(); }); }</code></pre></dd> <dt>should return the http status code</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/invalid-json-forbidden&#x60;).end((err, res) =&#x3E; { assert.equal(err.statusCode, 403); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>No content</h1> <dl> <dt>should not throw a parse error</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/no-content&#x60;).end((err, res) =&#x3E; { try { assert.strictEqual(err, null); assert.strictEqual(res.text, &#x27;&#x27;); assert.strictEqual(Object.keys(res.body).length, 0); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>application/json+hal</h1> <dl> <dt>should parse the body</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/json-hal&#x60;).end((err, res) =&#x3E; { if (err) return done(err); res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;hal 5000&#x22;}&#x27;); res.body.should.eql({ name: &#x27;hal 5000&#x27; }); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>vnd.collection+json</h1> <dl> <dt>should parse the body</dt> <dd><pre><code>done =&#x3E; { request.get(&#x60;${uri}/collection-json&#x60;).end((err, res) =&#x3E; { res.text.should.equal(&#x27;{&#x22;name&#x22;:&#x22;chewbacca&#x22;}&#x27;); res.body.should.eql({ name: &#x27;chewbacca&#x27; }); done(); }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>request</h1> <dl> <section class="suite"> <h1>on redirect</h1> <dl> <dt>should retain header fields</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${base}/header&#x60;) .set(&#x27;X-Foo&#x27;, &#x27;bar&#x27;) .end((err, res) =&#x3E; { try { assert(res.body); res.body.should.have.property(&#x27;x-foo&#x27;, &#x27;bar&#x27;); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should preserve timeout across redirects</dt> <dd><pre><code>done =&#x3E; { request .get(&#x60;${base}/movies/random&#x60;) .timeout(250) .end((err, res) =&#x3E; { try { assert(err instanceof Error, &#x27;expected an error&#x27;); err.should.have.property(&#x27;timeout&#x27;, 250); done(); } catch (err2) { done(err2); } }); }</code></pre></dd> <dt>should successfully redirect after retry on error</dt> <dd><pre><code>done =&#x3E; { const id = Math.random() * 1000000 * Date.now(); request .get(&#x60;${base}/error/redirect/${id}&#x60;) .retry(2) .end((err, res) =&#x3E; { assert(res.ok, &#x27;response should be ok&#x27;); assert(res.text, &#x27;first movie page&#x27;); done(); }); }</code></pre></dd> <dt>should preserve retries across redirects</dt> <dd><pre><code>done =&#x3E; { const id = Math.random() * 1000000 * Date.now(); request .get(&#x60;${base}/error/redirect-error${id}&#x60;) .retry(2) .end((err, res) =&#x3E; { assert(err, &#x27;expected an error&#x27;); assert.equal(2, err.retries, &#x27;expected an error with .retries&#x27;); assert.equal(500, err.status, &#x27;expected an error status of 500&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>on 303</h1> <dl> <dt>should redirect with same method</dt> <dd><pre><code>done =&#x3E; { request .put(&#x60;${base}/redirect-303&#x60;) .send({ msg: &#x27;hello&#x27; }) .redirects(1) .on(&#x27;redirect&#x27;, res =&#x3E; { res.headers.location.should.equal(&#x27;/reply-method&#x27;); }) .end((err, res) =&#x3E; { if (err) { done(err); return; } res.text.should.equal(&#x27;method=get&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>on 307</h1> <dl> <dt>should redirect with same method</dt> <dd><pre><code>done =&#x3E; { if (isMSIE) return done(); // IE9 broken request .put(&#x60;${base}/redirect-307&#x60;) .send({ msg: &#x27;hello&#x27; }) .redirects(1) .on(&#x27;redirect&#x27;, res =&#x3E; { res.headers.location.should.equal(&#x27;/reply-method&#x27;); }) .end((err, res) =&#x3E; { if (err) { done(err); return; } res.text.should.equal(&#x27;method=put&#x27;); done(); }); }</code></pre></dd> </dl> </section> <section class="suite"> <h1>on 308</h1> <dl> <dt>should redirect with same method</dt> <dd><pre><code>done =&#x3E; { if (isMSIE) return done(); // IE9 broken request .put(&#x60;${base}/redirect-308&#x60;) .send({ msg: &#x27;hello&#x27; }) .redirects(1) .on(&#x27;redirect&#x27;, res =&#x3E; { res.headers.location.should.equal(&#x27;/reply-method&#x27;); }) .end((err, res) =&#x3E; { if (err) { done(err); return; } res.text.should.equal(&#x27;method=put&#x27;); done(); }); }</code></pre></dd> </dl> </section> </dl> </section> <section class="suite"> <h1>request</h1> <dl> <dt>Request inheritance</dt> <dd><pre><code>assert(request.get(&#x60;${uri}/&#x60;) instanceof request.Request);</code></pre></dd> <dt>request() simple GET without callback</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x27;test/test.request.js&#x27;).end(); next(); }</code></pre></dd> <dt>request() simple GET</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/ok&#x60;).end((err, res) =&#x3E; { try { assert(res instanceof request.Response, &#x27;respond with Response&#x27;); assert(res.ok, &#x27;response should be ok&#x27;); assert(res.text, &#x27;res.text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() simple HEAD</dt> <dd><pre><code>next =&#x3E; { request.head(&#x60;${uri}/ok&#x60;).end((err, res) =&#x3E; { try { assert(res instanceof request.Response, &#x27;respond with Response&#x27;); assert(res.ok, &#x27;response should be ok&#x27;); assert(!res.text, &#x27;res.text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 5xx</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/error&#x60;).end((err, res) =&#x3E; { try { assert(err); assert.equal(err.message, &#x27;Internal Server Error&#x27;); assert(!res.ok, &#x27;response should not be ok&#x27;); assert(res.error, &#x27;response should be an error&#x27;); assert(!res.clientError, &#x27;response should not be a client error&#x27;); assert(res.serverError, &#x27;response should be a server error&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 4xx</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/notfound&#x60;).end((err, res) =&#x3E; { try { assert(err); assert.equal(err.message, &#x27;Not Found&#x27;); assert(!res.ok, &#x27;response should not be ok&#x27;); assert(res.error, &#x27;response should be an error&#x27;); assert(res.clientError, &#x27;response should be a client error&#x27;); assert(!res.serverError, &#x27;response should not be a server error&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 404 Not Found</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/notfound&#x60;).end((err, res) =&#x3E; { try { assert(err); assert(res.notFound, &#x27;response should be .notFound&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 400 Bad Request</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/bad-request&#x60;).end((err, res) =&#x3E; { try { assert(err); assert(res.badRequest, &#x27;response should be .badRequest&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 401 Bad Request</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/unauthorized&#x60;).end((err, res) =&#x3E; { try { assert(err); assert(res.unauthorized, &#x27;response should be .unauthorized&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 406 Not Acceptable</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/not-acceptable&#x60;).end((err, res) =&#x3E; { try { assert(err); assert(res.notAcceptable, &#x27;response should be .notAcceptable&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() GET 204 No Content</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/no-content&#x60;).end((err, res) =&#x3E; { try { assert.ifError(err); assert(res.noContent, &#x27;response should be .noContent&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() DELETE 204 No Content</dt> <dd><pre><code>next =&#x3E; { request(&#x27;DELETE&#x27;, &#x60;${uri}/no-content&#x60;).end((err, res) =&#x3E; { try { assert.ifError(err); assert(res.noContent, &#x27;response should be .noContent&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() header parsing</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/notfound&#x60;).end((err, res) =&#x3E; { try { assert(err); assert.equal(&#x27;text/html; charset=utf-8&#x27;, res.header[&#x27;content-type&#x27;]); assert.equal(&#x27;Express&#x27;, res.header[&#x27;x-powered-by&#x27;]); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>request() .status</dt> <dd><pre><code>next =&#x3E; { request(&#x27;GET&#x27;, &#x60;${uri}/notfound&#x60;).end((err, res) =&#x3E; { try { assert(err); assert.equal(404, res.status, &#x27;response .status&#x27;); assert.equal(4, res.statusType, &#x27;response .statusType&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>get()</dt> <dd><pre><code>next =&#x3E; { request.get(&#x60;${uri}/notfound&#x60;).end((err, res) =&#x3E; { try { assert(err); assert.equal(404, res.status, &#x27;response .status&#x27;); assert.equal(4, res.statusType, &#x27;response .statusType&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>put()</dt> <dd><pre><code>next =&#x3E; { request.put(&#x60;${uri}/user/12&#x60;).end((err, res) =&#x3E; { try { assert.equal(&#x27;updated&#x27;, res.text, &#x27;response text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>put().send()</dt> <dd><pre><code>next =&#x3E; { request .put(&#x60;${uri}/user/13/body&#x60;) .send({ user: &#x27;new&#x27; }) .end((err, res) =&#x3E; { try { assert.equal(&#x27;received new&#x27;, res.text, &#x27;response text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>post()</dt> <dd><pre><code>next =&#x3E; { request.post(&#x60;${uri}/user&#x60;).end((err, res) =&#x3E; { try { assert.equal(&#x27;created&#x27;, res.text, &#x27;response text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>del()</dt> <dd><pre><code>next =&#x3E; { request.del(&#x60;${uri}/user/12&#x60;).end((err, res) =&#x3E; { try { assert.equal(&#x27;deleted&#x27;, res.text, &#x27;response text&#x27;); next(); } catch (err2) { next(err2); } }); }</code></pre></dd> <dt>delete()</dt> <dd><pre><code>next =&#x3E; { request.delete(&#x60;${uri}/user/12&#x60;).end((err, res) =&#x3E; { try {