test.html 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082
  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');
  274. req.on('request', function(request){
  275. assert.equal(req, request);
  276. done();
  277. });
  278. req.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. });
  320. req.on('abort', done);
  321. setTimeout(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');
  628. req.set('Content-Type', 'application/json');
  629. req.write('{&quot;name&quot;').should.be.a.boolean;
  630. req.write(':&quot;tobi&quot;}').should.be.a.boolean;
  631. req.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;
  642. stream.buf = '';
  643. stream.writable = true;
  644. stream.write = function(chunk){
  645. this.buf += chunk;
  646. };
  647. stream.end = function(){
  648. this.buf.should.equal('{&quot;name&quot;:&quot;tobi&quot;}');
  649. done();
  650. };
  651. request
  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');
  700. req.agent().should.equal(false);
  701. done();</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');
  709. var ret = req.agent(undefined);
  710. ret.should.equal(req);
  711. assert.strictEqual(req.agent(), undefined);
  712. done();</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');
  720. var req = request.get('http://localhost:5000/echo');
  721. var agent = new http.Agent();
  722. var ret = req.agent(agent);
  723. ret.should.equal(req);
  724. req.agent().should.equal(agent)
  725. done();</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');
  756. var img = fs.readFileSync(__dirname + '/fixtures/test.png');
  757. img = decoder.write(img);
  758. request
  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');
  771. request
  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});
  1019. agent
  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;
  1292. var total = 0;
  1293. request
  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. });
  1415. setTimeout(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');
  1423. var redirects = [];
  1424. var 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');
  1446. var stream = fs.createReadStream('test/node/fixtures/user.json');
  1447. req.type('json');
  1448. req.on('response', function(res){
  1449. res.body.should.eql({ name: 'tobi' });
  1450. done();
  1451. });
  1452. stream.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');
  1455. var req = request.get('http://localhost:3025');
  1456. req.type('json');
  1457. req.on('end', function(){
  1458. JSON.parse(fs.readFileSync('test/node/fixtures/tmp.json', 'utf8')).should.eql({ name: 'tobi' });
  1459. done();
  1460. });
  1461. req.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);
  1537. request
  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 = [];
  1741. request
  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 = [];
  1797. var query = [];
  1798. request
  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 = [];
  1827. request
  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 = [];
  1840. request
  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 = [];
  1860. request
  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 = [];
  1882. request
  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);
  1958. req.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. (function(){ res.pause() }).should.not.throw();
  1972. (function(){ res.resume() }).should.not.throw();
  1973. (function(){ res.destroy() }).should.not.throw();
  1974. });</code></pre></dd>
  1975. </dl>
  1976. </section>
  1977. <section class="suite">
  1978. <h1>.timeout(ms)</h1>
  1979. <dl>
  1980. <section class="suite">
  1981. <h1>when timeout is exceeded</h1>
  1982. <dl>
  1983. <dt>should error</dt>
  1984. <dd><pre><code>request
  1985. .get('http://localhost:3009/500')
  1986. .timeout(150)
  1987. .end(function(err, res){
  1988. assert(err, 'expected an error');
  1989. assert.equal('number', typeof err.timeout, 'expected an error with .timeout');
  1990. assert.equal('ECONNABORTED', err.code, 'expected abort error code')
  1991. done();
  1992. });</code></pre></dd>
  1993. </dl>
  1994. </section>
  1995. </dl>
  1996. </section>
  1997. <section class="suite">
  1998. <h1>res.toError()</h1>
  1999. <dl>
  2000. <dt>should return an Error</dt>
  2001. <dd><pre><code>request
  2002. .get('http://localhost:' + server.address().port)
  2003. .end(function(err, res){
  2004. var err = res.toError();
  2005. assert.equal(err.status, 400);
  2006. assert.equal(err.method, 'GET');
  2007. assert.equal(err.path, '/');
  2008. assert.equal(err.message, 'cannot GET / (400)');
  2009. assert.equal(err.text, 'invalid json');
  2010. done();
  2011. });</code></pre></dd>
  2012. </dl>
  2013. </section>
  2014. <section class="suite">
  2015. <h1>req.get()</h1>
  2016. <dl>
  2017. <dt>should set a default user-agent</dt>
  2018. <dd><pre><code>request
  2019. .get('http://localhost:3345/ua')
  2020. .end(function(err, res){
  2021. assert(res.headers);
  2022. assert(res.headers['user-agent']);
  2023. assert(/^node-superagent\/\d+\.\d+\.\d+$/.test(res.headers['user-agent']));
  2024. done();
  2025. });</code></pre></dd>
  2026. <dt>should be able to override user-agent</dt>
  2027. <dd><pre><code>request
  2028. .get('http://localhost:3345/ua')
  2029. .set('User-Agent', 'foo/bar')
  2030. .end(function(err, res){
  2031. assert(res.headers);
  2032. assert.equal(res.headers['user-agent'], 'foo/bar');
  2033. done();
  2034. });</code></pre></dd>
  2035. <dt>should be able to wipe user-agent</dt>
  2036. <dd><pre><code>request
  2037. .get('http://localhost:3345/ua')
  2038. .unset('User-Agent')
  2039. .end(function(err, res){
  2040. assert(res.headers);
  2041. assert.equal(res.headers['user-agent'], void 0);
  2042. done();
  2043. });</code></pre></dd>
  2044. </dl>
  2045. </section>
  2046. <section class="suite">
  2047. <h1>utils.type(str)</h1>
  2048. <dl>
  2049. <dt>should return the mime type</dt>
  2050. <dd><pre><code>utils.type('application/json; charset=utf-8')
  2051. .should.equal('application/json');
  2052. utils.type('application/json')
  2053. .should.equal('application/json');</code></pre></dd>
  2054. </dl>
  2055. </section>
  2056. <section class="suite">
  2057. <h1>utils.params(str)</h1>
  2058. <dl>
  2059. <dt>should return the field parameters</dt>
  2060. <dd><pre><code>var str = 'application/json; charset=utf-8; foo = bar';
  2061. var obj = utils.params(str);
  2062. obj.charset.should.equal('utf-8');
  2063. obj.foo.should.equal('bar');
  2064. var str = 'application/json';
  2065. utils.params(str).should.eql({});</code></pre></dd>
  2066. </dl>
  2067. </section>
  2068. <section class="suite">
  2069. <h1>utils.parseLinks(str)</h1>
  2070. <dl>
  2071. <dt>should parse links</dt>
  2072. <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;';
  2073. var ret = utils.parseLinks(str);
  2074. ret.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2');
  2075. ret.last.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=5');</code></pre></dd>
  2076. </dl>
  2077. </section>
  2078. </div>
  2079. <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>
  2080. </body>
  2081. </html>