request
- should set statusCode
request .get(uri + '/login', function(err, res){ assert.strictEqual(res.statusCode, 200); done(); })
- with callback in the method call
request .get(uri + '/login', function(err, res) { assert.equal(res.status, 200); done(); });
- with data in the method call
request .post(uri + '/echo', { foo: 'bar' }) .end(function(err, res) { assert.equal('{"foo":"bar"}', res.text); done(); });
- with callback and data in the method call
request .post(uri + '/echo', { foo: 'bar' }, function(err, res) { assert.equal('{"foo":"bar"}', res.text); done(); });
- should invoke .end()
request .get(uri + '/login', function(err, res){ assert.equal(res.status, 200); done(); })
- should issue a request
request .get(uri + '/login') .end(function(err, res){ assert.equal(res.status, 200); done(); });
- is optional with a promise
if ('undefined' === typeof Promise) { return; } return request.get(uri + '/login') .then(function(res) { return res.status; }) .then() .then(function(status) { assert.equal(200, status, "Real promises pass results through"); });
- called only once with a promise
if ('undefined' === typeof Promise) { return; } var req = request.get(uri + '/unique'); return Promise.all([req, req, req]) .then(function(results){ results.forEach(function(item){ assert.equal(item.body, results[0].body, "It should keep returning the same result after being called once"); }); });
- should should be an Error object
var calledErrorEvent = false; request .get(uri + '/error') .on('error', function(err){ assert.strictEqual(err.status, 500); calledErrorEvent = true; }) .end(function(err, res){ if (NODE) { res.error.message.should.equal('cannot GET /error (500)'); } else { res.error.message.should.equal('cannot GET ' + uri + '/error (500)'); } assert.strictEqual(res.error.status, 500); assert(err, 'should have an error for 500'); assert.equal(err.message, 'Internal Server Error'); assert(calledErrorEvent); done(); });
- with .then() promise
if ('undefined' === typeof Promise) { return; } return request .get(uri + '/error') .then(function(){ assert.fail(); }, function(err){ assert.equal(err.message, 'Internal Server Error'); });
- should be an object
request .get(uri + '/login') .end(function(err, res){ assert.equal('Express', res.header['x-powered-by']); done(); });
- should be set when present
request .get(uri + '/login') .end(function(err, res){ res.charset.should.equal('utf-8'); done(); });
- should provide the first digit
request .get(uri + '/login') .end(function(err, res){ assert(!err, 'should not have an error for success responses'); assert.equal(200, res.status); assert.equal(2, res.statusType); done(); });
- should provide the mime-type void of params
request .get(uri + '/login') .end(function(err, res){ res.type.should.equal('text/html'); res.charset.should.equal('utf-8'); done(); });
- should set the header field
request .post(uri + '/echo') .set('X-Foo', 'bar') .set('X-Bar', 'baz') .end(function(err, res){ assert.equal('bar', res.header['x-foo']); assert.equal('baz', res.header['x-bar']); done(); })
- should set the header fields
request .post(uri + '/echo') .set({ 'X-Foo': 'bar', 'X-Bar': 'baz' }) .end(function(err, res){ assert.equal('bar', res.header['x-foo']); assert.equal('baz', res.header['x-bar']); done(); })
- should set the Content-Type
request .post(uri + '/echo') .type('text/x-foo') .end(function(err, res){ res.header['content-type'].should.equal('text/x-foo'); done(); });
- should map "json"
request .post(uri + '/echo') .type('json') .send('{"a": 1}') .end(function(err, res){ res.should.be.json(); done(); });
- should map "html"
request .post(uri + '/echo') .type('html') .end(function(err, res){ res.header['content-type'].should.equal('text/html'); done(); });
- should set Accept
request .get(uri + '/echo') .accept('text/x-foo') .end(function(err, res){ res.header['accept'].should.equal('text/x-foo'); done(); });
- should map "json"
request .get(uri + '/echo') .accept('json') .end(function(err, res){ res.header['accept'].should.equal('application/json'); done(); });
- should map "xml"
request .get(uri + '/echo') .accept('xml') .end(function(err, res){ res.header['accept'].should.equal('application/xml'); done(); });
- should map "html"
request .get(uri + '/echo') .accept('html') .end(function(err, res){ res.header['accept'].should.equal('text/html'); done(); });
- should write the string
request .post(uri + '/echo') .type('json') .send('{"name":"tobi"}') .end(function(err, res){ res.text.should.equal('{"name":"tobi"}'); done(); });
- should default to json
request .post(uri + '/echo') .send({ name: 'tobi' }) .end(function(err, res){ res.should.be.json(); res.text.should.equal('{"name":"tobi"}'); done(); });
- should merge the objects
request .post(uri + '/echo') .send({ name: 'tobi' }) .send({ age: 1 }) .end(function(err, res){ res.should.be.json(); if (NODE) { res.buffered.should.be.true; } res.text.should.equal('{"name":"tobi","age":1}'); done(); });
- should check arity
request .post(uri + '/echo') .send({ name: 'tobi' }) .end(function(err, res){ assert.equal(null, err); res.text.should.equal('{"name":"tobi"}'); done(); });
- should emit request
var req = request.post(uri + '/echo'); req.on('request', function(request){ assert.equal(req, request); done(); }); req.end();
- should emit response
request .post(uri + '/echo') .send({ name: 'tobi' }) .on('response', function(res){ res.text.should.equal('{"name":"tobi"}'); done(); }) .end();
- should support successful fulfills with .then(fulfill)
if ('undefined' === typeof Promise) { return done(); } request .post(uri + '/echo') .send({ name: 'tobi' }) .then(function(res) { res.text.should.equal('{"name":"tobi"}'); done(); })
- should reject an error with .then(null, reject)
if ('undefined' === typeof Promise) { return done(); } request .get(uri + '/error') .then(null, function(err) { assert.equal(err.status, 500); assert.equal(err.response.text, 'boom'); done(); })
- should reject an error with .catch(reject)
if ('undefined' === typeof Promise) { return done(); } request .get(uri + '/error') .catch(function(err) { assert.equal(err.status, 500); assert.equal(err.response.text, 'boom'); done(); })
- should abort the request
var req = request .get(uri + '/delay/3000') .end(function(err, res){ assert(false, 'should not complete the request'); }); req.on('abort', done); setTimeout(function() { req.abort(); }, 1000);
- should allow chaining .abort() several times
var req = request .get(uri + '/delay/3000') .end(function(err, res){ assert(false, 'should not complete the request'); }); // This also verifies only a single 'done' event is emitted req.on('abort', done); setTimeout(function() { req.abort().abort().abort(); }, 1000);
- should describe the request
var req = request .post(uri + '/echo') .send({ foo: 'baz' }) .end(function(err, res){ var json = req.toJSON(); assert.equal('POST', json.method); assert(/\/echo$/.test(json.url)); assert.equal('baz', json.data.foo); done(); });
- should allow request body
request.options(uri + '/options/echo/body') .send({ foo: 'baz' }) .end(function(err, res){ assert.equal(err, null); assert.strictEqual(res.body.foo, 'baz'); done(); });
res.statusCode
should allow the send shorthand
with a callback
.end()
res.error
res.header
res.charset
res.statusType
res.type
req.set(field, val)
req.set(obj)
req.type(str)
req.accept(str)
req.send(str)
req.send(Object)
when called several times
.end(fn)
.then(fulfill, reject)
.catch(reject)
.abort()
req.toJSON()
req.options()
req.set("Content-Type", contentType)
- should work with just the contentType component
request .post(uri + '/echo') .set('Content-Type', 'application/json') .send({ name: 'tobi' }) .end(function(err, res){ assert(!err); done(); });
- should work with the charset component
request .post(uri + '/echo') .set('Content-Type', 'application/json; charset=utf-8') .send({ name: 'tobi' }) .end(function(err, res){ assert(!err); done(); });
req.send(Object) as "form"
- should send x-www-form-urlencoded data
request .post(base + '/echo') .type('form') .send({ name: 'tobi' }) .end(function(err, res){ res.header['content-type'].should.equal('application/x-www-form-urlencoded'); res.text.should.equal('name=tobi'); done(); });
- should merge the objects
request .post(base + '/echo') .type('form') .send({ name: { first: 'tobi', last: 'holowaychuk' } }) .send({ age: '1' }) .end(function(err, res){ res.header['content-type'].should.equal('application/x-www-form-urlencoded'); res.text.should.equal('name%5Bfirst%5D=tobi&name%5Blast%5D=holowaychuk&age=1'); done(); });
with req.type() set to form
when called several times
req.field
- throw when empty
should.throws(function(){ request .post(base + '/echo') .field() }, /name/); should.throws(function(){ request .post(base + '/echo') .field('name') }, /val/);
req.send(Object) as "json"
- should default to json
request .post(uri + '/echo') .send({ name: 'tobi' }) .end(function(err, res){ res.should.be.json(); res.text.should.equal('{"name":"tobi"}'); done(); });
- should work with arrays
request .post(uri + '/echo') .send([1,2,3]) .end(function(err, res){ res.should.be.json(); res.text.should.equal('[1,2,3]'); done(); });
- should work with value null
request .post(uri + '/echo') .type('json') .send('null') .end(function(err, res){ res.should.be.json(); assert.strictEqual(res.body, null); done(); });
- should work with value false
request .post(uri + '/echo') .type('json') .send('false') .end(function(err, res){ res.should.be.json(); res.body.should.equal(false); done(); });
- should work with value 0
// fails in IE9 request .post(uri + '/echo') .type('json') .send('0') .end(function(err, res){ res.should.be.json(); res.body.should.equal(0); done(); });
- should work with empty string value
request .post(uri + '/echo') .type('json') .send('""') .end(function(err, res){ res.should.be.json(); res.body.should.equal(""); done(); });
- should work with GET
request .get(uri + '/echo') .send({ tobi: 'ferret' }) .end(function(err, res){ res.should.be.json(); res.text.should.equal('{"tobi":"ferret"}'); ({"tobi":"ferret"}).should.eql(res.body); done(); });
- should work with vendor MIME type
request .post(uri + '/echo') .set('Content-Type', 'application/vnd.example+json') .send({ name: 'vendor' }) .end(function(err, res){ res.text.should.equal('{"name":"vendor"}'); ({"name":"vendor"}).should.eql(res.body); done(); });
- should merge the objects
request .post(uri + '/echo') .send({ name: 'tobi' }) .send({ age: 1 }) .end(function(err, res){ res.should.be.json(); res.text.should.equal('{"name":"tobi","age":1}'); ({"name":"tobi","age":1}).should.eql(res.body); done(); });
when called several times
res.body
- should parse the body
request .get(uri + '/json') .end(function(err, res){ res.text.should.equal('{"name":"manny"}'); res.body.should.eql({ name: 'manny' }); done(); });
- should not throw a parse error
request .head(uri + '/json') .end(function(err, res){ assert.strictEqual(err, null); assert.strictEqual(res.text, undefined) assert.strictEqual(Object.keys(res.body).length, 0) done(); });
- should return the raw response
request .get(uri + '/invalid-json') .end(function(err, res){ assert.deepEqual(err.rawResponse, ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}"); done(); });
- should return the http status code
request .get(uri + '/invalid-json-forbidden') .end(function(err, res){ assert.equal(err.statusCode, 403); done(); });
- should not throw a parse error
request .get(uri + '/no-content') .end(function(err, res){ assert.strictEqual(err, null); assert.strictEqual(res.text, ''); assert.strictEqual(Object.keys(res.body).length, 0); done(); });
- should parse the body
request .get(uri + '/json-hal') .end(function(err, res){ if (err) return done(err); res.text.should.equal('{"name":"hal 5000"}'); res.body.should.eql({ name: 'hal 5000' }); done(); });
- should parse the body
request .get(uri + '/collection-json') .end(function(err, res){ res.text.should.equal('{"name":"chewbacca"}'); res.body.should.eql({ name: 'chewbacca' }); done(); });
application/json
HEAD requests
Invalid JSON response
No content
application/json+hal
vnd.collection+json
request
- should retain header fields
request .get(base + '/header') .set('X-Foo', 'bar') .end(function(err, res){ try { assert(res.body); res.body.should.have.property('x-foo', 'bar'); done(); } catch(err) { done(err); } });
- should preserve timeout across redirects
request .get(base + '/movies/random') .timeout(250) .end(function(err, res){ try { assert(err instanceof Error, 'expected an error'); err.should.have.property('timeout', 250); done(); } catch(err) { done(err); } });
- should redirect with same method
request .put(base + '/redirect-303') .send({msg: "hello"}) .redirects(1) .on('redirect', function(res) { res.headers.location.should.equal('/reply-method') }) .end(function(err, res){ res.text.should.equal('method=get'); done(); })
- should redirect with same method
if (isMSIE) return done(); // IE9 broken request .put(base + '/redirect-307') .send({msg: "hello"}) .redirects(1) .on('redirect', function(res) { res.headers.location.should.equal('/reply-method') }) .end(function(err, res){ res.text.should.equal('method=put'); done(); })
- should redirect with same method
if (isMSIE) return done(); // IE9 broken request .put(base + '/redirect-308') .send({msg: "hello"}) .redirects(1) .on('redirect', function(res) { res.headers.location.should.equal('/reply-method') }) .end(function(err, res){ res.text.should.equal('method=put'); done(); })
on redirect
on 303
on 307
on 308
request
- Request inheritance
assert(request.get(uri + '/') instanceof request.Request);
- request() simple GET without callback
request('GET', 'test/test.request.js').end(); next();
- request() simple GET
request('GET', uri + '/ok').end(function(err, res){ assert(res instanceof request.Response, 'respond with Response'); assert(res.ok, 'response should be ok'); assert(res.text, 'res.text'); next(); });
- request() simple HEAD
request.head(uri + '/ok').end(function(err, res){ assert(res instanceof request.Response, 'respond with Response'); assert(res.ok, 'response should be ok'); assert(!res.text, 'res.text'); next(); });
- request() GET 5xx
request('GET', uri + '/error').end(function(err, res){ assert(err); assert.equal(err.message, 'Internal Server Error'); assert(!res.ok, 'response should not be ok'); assert(res.error, 'response should be an error'); assert(!res.clientError, 'response should not be a client error'); assert(res.serverError, 'response should be a server error'); next(); });
- request() GET 4xx
request('GET', uri + '/notfound').end(function(err, res){ assert(err); assert.equal(err.message, 'Not Found'); assert(!res.ok, 'response should not be ok'); assert(res.error, 'response should be an error'); assert(res.clientError, 'response should be a client error'); assert(!res.serverError, 'response should not be a server error'); next(); });
- request() GET 404 Not Found
request('GET', uri + '/notfound').end(function(err, res){ assert(err); assert(res.notFound, 'response should be .notFound'); next(); });
- request() GET 400 Bad Request
request('GET', uri + '/bad-request').end(function(err, res){ assert(err); assert(res.badRequest, 'response should be .badRequest'); next(); });
- request() GET 401 Bad Request
request('GET', uri + '/unauthorized').end(function(err, res){ assert(err); assert(res.unauthorized, 'response should be .unauthorized'); next(); });
- request() GET 406 Not Acceptable
request('GET', uri + '/not-acceptable').end(function(err, res){ assert(err); assert(res.notAcceptable, 'response should be .notAcceptable'); next(); });
- request() GET 204 No Content
request('GET', uri + '/no-content').end(function(err, res){ assert.ifError(err); assert(res.noContent, 'response should be .noContent'); next(); });
- request() DELETE 204 No Content
request('DELETE', uri + '/no-content').end(function(err, res){ assert.ifError(err); assert(res.noContent, 'response should be .noContent'); next(); });
- request() header parsing
request('GET', uri + '/notfound').end(function(err, res){ assert(err); assert.equal('text/html; charset=utf-8', res.header['content-type']); assert.equal('Express', res.header['x-powered-by']); next(); });
- request() .status
request('GET', uri + '/notfound').end(function(err, res){ assert(err); assert.equal(404, res.status, 'response .status'); assert.equal(4, res.statusType, 'response .statusType'); next(); });
- get()
request.get( uri + '/notfound').end(function(err, res){ assert(err); assert.equal(404, res.status, 'response .status'); assert.equal(4, res.statusType, 'response .statusType'); next(); });
- put()
request.put(uri + '/user/12').end(function(err, res){ assert.equal('updated', res.text, 'response text'); next(); });
- post()
request.post(uri + '/user').end(function(err, res){ assert.equal('created', res.text, 'response text'); next(); });
- del()
request.del(uri + '/user/12').end(function(err, res){ assert.equal('deleted', res.text, 'response text'); next(); });
- delete()
request.delete(uri + '/user/12').end(function(err, res){ assert.equal('deleted', res.text, 'response text'); next(); });
- post() data
request.post(uri + '/todo/item') .type('application/octet-stream') .send('tobi') .end(function(err, res){ assert.equal('added "tobi"', res.text, 'response text'); next(); });
- request .type()
request .post(uri + '/user/12/pet') .type('urlencoded') .send('pet=tobi') .end(function(err, res){ assert.equal('added pet "tobi"', res.text, 'response text'); next(); });
- request .type() with alias
request .post(uri + '/user/12/pet') .type('application/x-www-form-urlencoded') .send('pet=tobi') .end(function(err, res){ assert.equal('added pet "tobi"', res.text, 'response text'); next(); });
- request .get() with no data or callback
request.get(uri + '/echo-header/content-type'); next();
- request .send() with no data only
request.post(uri + '/user/5/pet').type('urlencoded').send('pet=tobi'); next();
- request .send() with callback only
request .get(uri + '/echo-header/accept') .set('Accept', 'foo/bar') .end(function(err, res){ assert.equal('foo/bar', res.text); next(); });
- request .accept() with json
request .get(uri + '/echo-header/accept') .accept('json') .end(function(err, res){ assert.equal('application/json', res.text); next(); });
- request .accept() with application/json
request .get(uri + '/echo-header/accept') .accept('application/json') .end(function(err, res){ assert.equal('application/json', res.text); next(); });
- request .accept() with xml
request .get(uri + '/echo-header/accept') .accept('xml') .end(function(err, res){ assert.equal('application/xml', res.text, res.text); next(); });
- request .accept() with application/xml
request .get(uri + '/echo-header/accept') .accept('application/xml') .end(function(err, res){ assert.equal('application/xml', res.text); next(); });
- request .end()
request .get(uri + '/echo-header/content-type') .set('Content-Type', 'text/plain') .send('wahoo') .end(function(err, res){ assert.equal('text/plain', res.text); next(); });
- request .send()
request .get(uri + '/echo-header/content-type') .set('Content-Type', 'text/plain') .send('wahoo') .end(function(err, res){ assert.equal('text/plain', res.text); next(); });
- request .set()
request .get(uri + '/echo-header/content-type') .set('Content-Type', 'text/plain') .send('wahoo') .end(function(err, res){ assert.equal('text/plain', res.text); next(); });
- request .set(object)
request .get(uri + '/echo-header/content-type') .set({ 'Content-Type': 'text/plain' }) .send('wahoo') .end(function(err, res){ assert.equal('text/plain', res.text); next(); });
- POST urlencoded
request .post(uri + '/pet') .type('urlencoded') .send({ name: 'Manny', species: 'cat' }) .end(function(err, res){ assert.equal('added Manny the cat', res.text); next(); });
- POST json
request .post(uri + '/pet') .type('json') .send({ name: 'Manny', species: 'cat' }) .end(function(err, res){ assert.equal('added Manny the cat', res.text); next(); });
- POST json array
request .post(uri + '/echo') .send([1,2,3]) .end(function(err, res){ assert.equal('application/json', res.header['content-type'].split(';')[0]); assert.equal('[1,2,3]', res.text); next(); });
- POST json default
request .post(uri + '/pet') .send({ name: 'Manny', species: 'cat' }) .end(function(err, res){ assert.equal('added Manny the cat', res.text); next(); });
- POST json contentType charset
request .post(uri + '/echo') .set('Content-Type', 'application/json; charset=UTF-8') .send({ data: ['data1', 'data2'] }) .end(function(err, res){ assert.equal('{"data":["data1","data2"]}', res.text); next(); });
- POST json contentType vendor
request .post(uri + '/echo') .set('Content-Type', 'application/vnd.example+json') .send({ data: ['data1', 'data2'] }) .end(function(err, res){ assert.equal('{"data":["data1","data2"]}', res.text); next(); });
- POST multiple .send() calls
request .post(uri + '/pet') .send({ name: 'Manny' }) .send({ species: 'cat' }) .end(function(err, res){ assert.equal('added Manny the cat', res.text); next(); });
- POST multiple .send() strings
request .post(uri + '/echo') .send('user[name]=tj') .send('user[email]=tj@vision-media.ca') .end(function(err, res){ assert.equal('application/x-www-form-urlencoded', res.header['content-type'].split(';')[0]); assert.equal(res.text, 'user[name]=tj&user[email]=tj@vision-media.ca') next(); })
- POST with no data
request .post(uri + '/empty-body') .send().end(function(err, res){ assert.ifError(err); assert(res.noContent, 'response should be .noContent'); next(); });
- GET .type
request .get(uri + '/pets') .end(function(err, res){ assert.equal('application/json', res.type); next(); });
- GET Content-Type params
request .get(uri + '/text') .end(function(err, res){ assert.equal('utf-8', res.charset); next(); });
- GET json
request .get(uri + '/pets') .end(function(err, res){ assert.deepEqual(res.body, ['tobi', 'loki', 'jane']); next(); });
- GET x-www-form-urlencoded
request .get(uri + '/foo') .end(function(err, res){ assert.deepEqual(res.body, { foo: 'bar' }); next(); });
- GET shorthand
request.get(uri + '/foo', function(err, res){ assert.equal('foo=bar', res.text); next(); });
- POST shorthand
request.post(uri + '/user/0/pet', { pet: 'tobi' }, function(err, res){ assert.equal('added pet "tobi"', res.text); next(); });
- POST shorthand without callback
request.post(uri + '/user/0/pet', { pet: 'tobi' }).end(function(err, res){ assert.equal('added pet "tobi"', res.text); next(); });
- GET querystring object with array
request .get(uri + '/querystring') .query({ val: ['a', 'b', 'c'] }) .end(function(err, res){ assert.deepEqual(res.body, { val: ['a', 'b', 'c'] }); next(); });
- GET querystring object with array and primitives
request .get(uri + '/querystring') .query({ array: ['a', 'b', 'c'], string: 'foo', number: 10 }) .end(function(err, res){ assert.deepEqual(res.body, { array: ['a', 'b', 'c'], string: 'foo', number: 10 }); next(); });
- GET querystring object with two arrays
request .get(uri + '/querystring') .query({ array1: ['a', 'b', 'c'], array2: [1, 2, 3]}) .end(function(err, res){ assert.deepEqual(res.body, { array1: ['a', 'b', 'c'], array2: [1, 2, 3]}); next(); });
- GET querystring object
request .get(uri + '/querystring') .query({ search: 'Manny' }) .end(function(err, res){ assert.deepEqual(res.body, { search: 'Manny' }); next(); });
- GET querystring append original
request .get(uri + '/querystring?search=Manny') .query({ range: '1..5' }) .end(function(err, res){ assert.deepEqual(res.body, { search: 'Manny', range: '1..5' }); next(); });
- GET querystring multiple objects
request .get(uri + '/querystring') .query({ search: 'Manny' }) .query({ range: '1..5' }) .query({ order: 'desc' }) .end(function(err, res){ assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); next(); });
- GET querystring with strings
request .get(uri + '/querystring') .query('search=Manny') .query('range=1..5') .query('order=desc') .end(function(err, res){ assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); next(); });
- GET querystring with strings and objects
request .get(uri + '/querystring') .query('search=Manny') .query({ order: 'desc', range: '1..5' }) .end(function(err, res){ assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); next(); });
- request(method, url)
request('GET', uri + '/foo').end(function(err, res){ assert.equal('bar', res.body.foo); next(); });
- request(url)
request(uri + '/foo').end(function(err, res){ assert.equal('bar', res.body.foo); next(); });
- request(url, fn)
request(uri + '/foo', function(err, res){ assert.equal('bar', res.body.foo); next(); });
- req.timeout(ms)
var req = request .get(uri + '/delay/3000') .timeout(1000) .end(function(err, res){ assert(err, 'error missing'); assert.equal(1000, err.timeout, 'err.timeout missing'); assert.equal('timeout of 1000ms exceeded', err.message, 'err.message incorrect'); assert.equal(null, res); assert(req.timedout, true); next(); })
- req.timeout(ms) with redirect
var req = request .get(uri + '/delay/const') .timeout(1000) .end(function(err, res) { assert(err, 'error missing'); assert.equal(1000, err.timeout, 'err.timeout missing'); assert.equal('timeout of 1000ms exceeded', err.message, 'err.message incorrect'); assert.equal(null, res); assert(req.timedout, true); next(); });
- request event
request .get(uri + '/foo') .on('request', function(req){ assert.equal(uri + '/foo', req.url); next(); }) .end();
- response event
request .get(uri + '/foo') .on('response', function(res){ assert.equal('bar', res.body.foo); next(); }) .end();
- response should set statusCode
request .get(uri + '/ok', function(err, res){ assert.strictEqual(res.statusCode, 200); next(); })
- req.toJSON()
request .get(uri + '/ok') .end(function(err, res){ var j = (res.request || res.req).toJSON(); ['url', 'method', 'data', 'headers'].forEach(function(prop){ assert(j.hasOwnProperty(prop)); }); next(); });
request
- should use plugin success
var now = '' + Date.now(); function uuid(req){ req.set('X-UUID', now); return req; } function prefix(req){ req.url = uri + req.url return req; } request .get('/echo') .use(uuid) .use(prefix) .end(function(err, res){ assert.strictEqual(res.statusCode, 200); assert.equal(res.get('X-UUID'), now); done(); })
use
request
- should gain a session on POST
agent3 .post(base + '/signin') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); should.not.exist(res.headers['set-cookie']); res.text.should.containEql('dashboard'); done(); });
- should start with empty session (set cookies)
agent1 .get(base + '/dashboard') .end(function(err, res) { should.exist(err); res.should.have.status(401); should.exist(res.headers['set-cookie']); done(); });
- should gain a session (cookies already set)
agent1 .post(base + '/signin') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); should.not.exist(res.headers['set-cookie']); res.text.should.containEql('dashboard'); done(); });
- should persist cookies across requests
agent1 .get(base + '/dashboard') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); done(); });
- should have the cookie set in the end callback
agent4 .post(base + '/setcookie') .end(function(err, res) { agent4 .get(base + '/getcookie') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); assert.strictEqual(res.text, 'jar'); done(); }); });
- should not share cookies
agent2 .get(base + '/dashboard') .end(function(err, res) { should.exist(err); res.should.have.status(401); done(); });
- should not lose cookies between agents
agent1 .get(base + '/dashboard') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); done(); });
- should be able to follow redirects
agent1 .get(base) .end(function(err, res) { should.not.exist(err); res.should.have.status(200); res.text.should.containEql('dashboard'); done(); });
- should be able to post redirects
agent1 .post(base + '/redirect') .send({ foo: 'bar', baz: 'blaaah' }) .end(function(err, res) { should.not.exist(err); res.should.have.status(200); res.text.should.containEql('simple'); res.redirects.should.eql([base + '/simple']); done(); });
- should be able to limit redirects
agent1 .get(base) .redirects(0) .end(function(err, res) { should.exist(err); res.should.have.status(302); res.redirects.should.eql([]); res.header.location.should.equal('/dashboard'); done(); });
- should be able to create a new session (clear cookie)
agent1 .post(base + '/signout') .end(function(err, res) { should.not.exist(err); res.should.have.status(200); should.exist(res.headers['set-cookie']); done(); });
- should regenerate with an empty session
agent1 .get(base + '/dashboard') .end(function(err, res) { should.exist(err); res.should.have.status(401); should.not.exist(res.headers['set-cookie']); done(); });
persistent agent
Basic auth
- should set Authorization
request .get('http://tobi:learnboost@localhost:' + server.address().port + '/basic-auth') .end(function(err, res){ res.status.should.equal(200); done(); });
- should set Authorization
request .get(base + '/basic-auth') .auth('tobi', 'learnboost') .end(function(err, res){ res.status.should.equal(200); done(); });
- should set authorization
request .get(base + '/basic-auth/again') .auth('tobi') .end(function(err, res){ res.status.should.eql(200); done(); });
when credentials are present in url
req.auth(user, pass)
req.auth(user + ":" + pass)
[node] request
- should preserve the encoding of the url
request .get('http://localhost:5000/url?a=(b%29') .end(function(err, res){ assert.equal('/url?a=(b%29', res.text); done(); })
- should format the url
request .get(url.parse('http://localhost:5000/login')) .end(function(err, res){ assert(res.ok); done(); })
- should default to http
request .get('localhost:5000/login') .end(function(err, res){ assert.equal(res.status, 200); done(); })
- should describe the response
request .post('http://localhost:5000/echo') .send({ foo: 'baz' }) .end(function(err, res){ var obj = res.toJSON(); assert.equal('object', typeof obj.header); assert.equal('object', typeof obj.req); assert.equal(200, obj.status); assert.equal('{"foo":"baz"}', obj.text); done(); });
- should default to an empty object
request .get('http://localhost:5000/login') .end(function(err, res){ res.links.should.eql({}); done(); })
- should parse the Link header field
request .get('http://localhost:5000/links') .end(function(err, res){ res.links.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2'); done(); })
- should remove the header field
request .post('http://localhost:5000/echo') .unset('User-Agent') .end(function(err, res){ assert.equal(void 0, res.header['user-agent']); done(); })
- should set/get header fields case-insensitively
var r = request.post('http://localhost:5000/echo'); r.set('MiXeD', 'helloes'); assert.strictEqual(r.get('mixed'), 'helloes');
- should unset header fields case-insensitively
var r = request.post('http://localhost:5000/echo'); r.set('MiXeD', 'helloes'); r.unset('MIXED'); assert.strictEqual(r.get('mixed'), undefined);
- should write the given data
var req = request.post('http://localhost:5000/echo'); req.set('Content-Type', 'application/json'); req.write('{"name"').should.be.a.boolean; req.write(':"tobi"}').should.be.a.boolean; req.end(function(err, res){ res.text.should.equal('{"name":"tobi"}'); done(); });
- should pipe the response to the given stream
var stream = new EventEmitter; stream.buf = ''; stream.writable = true; stream.write = function(chunk){ this.buf += chunk; }; stream.end = function(){ this.buf.should.equal('{"name":"tobi"}'); done(); }; request .post('http://localhost:5000/echo') .send('{"name":"tobi"}') .pipe(stream);
- should enable buffering
request .get('http://localhost:5000/custom') .buffer() .end(function(err, res){ assert.equal(null, err); assert.equal('custom stuff', res.text); assert(res.buffered); done(); });
- should disable buffering
request .post('http://localhost:5000/echo') .type('application/x-dog') .send('hello this is dog') .buffer(false) .end(function(err, res){ assert.equal(null, err); assert.equal(null, res.text); res.body.should.eql({}); var buf = ''; res.setEncoding('utf8'); res.on('data', function(chunk){ buf += chunk }); res.on('end', function(){ buf.should.equal('hello this is dog'); done(); }); });
- should not throw an error when using the client-side "withCredentials" method
request .get('http://localhost:5000/custom') .withCredentials() .end(function(err, res){ assert.equal(null, err); done(); });
- should return the defaut agent
var req = request.post('http://localhost:5000/echo'); req.agent().should.equal(false); done();
- should set an agent to undefined and ensure it is chainable
var req = request.get('http://localhost:5000/echo'); var ret = req.agent(undefined); ret.should.equal(req); assert.strictEqual(req.agent(), undefined); done();
- should set passed agent
var http = require('http'); var req = request.get('http://localhost:5000/echo'); var agent = new http.Agent(); var ret = req.agent(agent); ret.should.equal(req); req.agent().should.equal(agent) done();
- should disable buffering
request .post('http://localhost:5000/echo') .type('application/x-dog') .send('hello this is dog') .end(function(err, res){ assert.equal(null, err); assert.equal(null, res.text); res.body.should.eql({}); var buf = ''; res.setEncoding('utf8'); res.buffered.should.be.false; res.on('data', function(chunk){ buf += chunk }); res.on('end', function(){ buf.should.equal('hello this is dog'); done(); }); });
- should be set to the byte length of a non-buffer object
var decoder = new StringDecoder('utf8'); var img = fs.readFileSync(__dirname + '/fixtures/test.png'); img = decoder.write(img); request .post('http://localhost:5000/echo') .type('application/x-image') .send(img) .buffer(false) .end(function(err, res){ assert.equal(null, err); assert(!res.buffered); assert.equal(res.header['content-length'], Buffer.byteLength(img)); done(); });
- should be set to the length of a buffer object
var img = fs.readFileSync(__dirname + '/fixtures/test.png'); request .post('http://localhost:5000/echo') .type('application/x-image') .send(img) .buffer(true) .end(function(err, res){ assert.equal(null, err); assert(res.buffered); assert.equal(res.header['content-length'], img.length); done(); });
with an url
with an object
without a schema
res.toJSON()
res.links
req.unset(field)
case-insensitive
req.write(str)
req.pipe(stream)
.buffer()
.buffer(false)
.withCredentials()
.agent()
.agent(undefined)
.agent(new http.Agent())
with a content type other than application/json or text/*
content-length
exports
- should expose Part
request.Part.should.be.a.function;
- should expose .protocols
Object.keys(request.protocols) .should.eql(['http:', 'https:']);
- should expose .serialize
Object.keys(request.serialize) .should.eql(['application/x-www-form-urlencoded', 'application/json']);
- should expose .parse
Object.keys(request.parse) .should.eql(['application/x-www-form-urlencoded', 'application/json', 'text', 'image']);
flags
- should set res.error and res.clientError
request .get(base + '/notfound') .end(function(err, res){ assert(err); assert(!res.ok, 'response should not be ok'); assert(res.error, 'response should be an error'); assert(res.clientError, 'response should be a client error'); assert(!res.serverError, 'response should not be a server error'); done(); });
- should set res.error and res.serverError
request .get(base + '/error') .end(function(err, res){ assert(err); assert(!res.ok, 'response should not be ok'); assert(!res.notFound, 'response should not be notFound'); assert(res.error, 'response should be an error'); assert(!res.clientError, 'response should not be a client error'); assert(res.serverError, 'response should be a server error'); done(); });
- should res.notFound
request .get(base + '/notfound') .end(function(err, res){ assert(err); assert(res.notFound, 'response should be .notFound'); done(); });
- should set req.badRequest
request .get(base + '/bad-request') .end(function(err, res){ assert(err); assert(res.badRequest, 'response should be .badRequest'); done(); });
- should set res.unauthorized
request .get(base + '/unauthorized') .end(function(err, res){ assert(err); assert(res.unauthorized, 'response should be .unauthorized'); done(); });
- should set res.notAcceptable
request .get(base + '/not-acceptable') .end(function(err, res){ assert(err); assert(res.notAcceptable, 'response should be .notAcceptable'); done(); });
- should set res.noContent
request .get(base + '/no-content') .end(function(err, res){ assert(!err); assert(res.noContent, 'response should be .noContent'); done(); });
with 4xx response
with 5xx response
with 404 Not Found
with 400 Bad Request
with 401 Bad Request
with 406 Not Acceptable
with 204 No Content
req.send(String)
- should default to "form"
request .post(base + '/echo') .send('user[name]=tj') .send('user[email]=tj@vision-media.ca') .end(function(err, res){ res.header['content-type'].should.equal('application/x-www-form-urlencoded'); res.body.should.eql({ user: { name: 'tj', email: 'tj@vision-media.ca' } }); done(); })
res.body
- should parse the body
request .get(base + '/form-data') .end(function(err, res){ res.text.should.equal('pet[name]=manny'); res.body.should.eql({ pet: { name: 'manny' }}); done(); });
application/x-www-form-urlencoded
https
- should give a good response
request .get(testEndpoint) .ca(ca) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); done(); })
- should be able to make multiple requests without redefining the certificate
var agent = request.agent({ca: ca}); agent .get(testEndpoint) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); agent .get(url.parse(testEndpoint)) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); done(); }) })
- should give a good response with client certificates and CA
request .get(testEndpoint) .ca(ca) .key(key) .cert(cert) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); done(); })
- should be able to make multiple requests without redefining the certificates
var agent = request.agent({ca: ca, key: key, cert: cert}); agent .get(testEndpoint) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); agent .get(url.parse(testEndpoint)) .end(function(err, res){ assert(res.ok); assert.strictEqual('Safe and secure!', res.text); done(); }) })
certificate authority
request
.agent
client certificates
request
.agent
res.body
- should parse the body
request .get(base + '/image') .end(function(err, res){ (res.body.length - img.length).should.equal(0); done(); });
image/png
zlib
- should deflate the content
request .get(base) .end(function(err, res) { res.should.have.status(200); res.text.should.equal(subject); res.headers['content-length'].should.be.below(subject.length); done(); });
- should ignore trailing junk
request .get(base + '/junk') .end(function(err, res) { res.should.have.status(200); res.text.should.equal(subject); done(); });
- should ignore missing data
request .get(base + '/chopped') .end(function(err, res) { assert.equal(undefined, err); res.should.have.status(200); res.text.should.startWith(subject); done(); });
- should handle corrupted responses
request .get(base + '/corrupt') .end(function(err, res) { assert(err, 'missing error'); assert(!res, 'response should not be defined'); done(); });
- should handle no content with gzip header
request .get(base + '/nocontent') .end(function(err, res) { assert.ifError(err); assert(res); res.should.have.status(204); res.text.should.equal(''); res.headers.should.not.have.property('content-length'); done(); });
- should emit buffers
request .get(base + '/binary') .end(function(err, res) { res.should.have.status(200); res.headers['content-length'].should.be.below(subject.length); res.on('data', function(chunk) { chunk.should.have.length(subject.length); }); res.on('end', done); });
without encoding set
Request
- should use the custom filename
request .post(base + '/echo') .attach('document', 'test/node/fixtures/user.html', 'doc.html') .end(function(err, res){ if (err) return done(err); var html = res.files.document; html.name.should.equal('doc.html'); html.type.should.equal('text/html'); read(html.path).should.equal('<h1>name</h1>'); done(); })
- should fire progress event
var loaded = 0; var total = 0; var uploadEventWasFired = false; request .post(base + '/echo') .attach('document', 'test/node/fixtures/user.html') .on('progress', function (event) { total = event.total; loaded = event.loaded; if (event.direction === 'upload') { uploadEventWasFired = true; } }) .end(function(err, res){ if (err) return done(err); var html = res.files.document; html.name.should.equal('user.html'); html.type.should.equal('text/html'); read(html.path).should.equal('<h1>name</h1>'); total.should.equal(223); loaded.should.equal(223); uploadEventWasFired.should.equal(true); done(); })
- filesystem errors should be caught
request .post(base + '/echo') .attach('filedata', 'test/node/fixtures/non-existent-file.ext') .on('error', function(err) { err.code.should.equal('ENOENT') err.path.should.equal('test/node/fixtures/non-existent-file.ext') done() }) .end(function (err, res) { done(new Error("Request should have been aborted earlier!")) })
- should set a multipart field value
request.post(base + '/echo') .field('first-name', 'foo') .field('last-name', 'bar') .end(function(err, res) { if(err) done(err); res.should.be.ok; res.body['first-name'].should.equal('foo'); res.body['last-name'].should.equal('bar'); done(); });
- should set multiple multipart fields
request.post(base + '/echo') .field({ 'first-name': 'foo', 'last-name': 'bar' }) .end(function(err, res) { if(err) done(err); res.should.be.ok; res.body['first-name'].should.equal('foo'); res.body['last-name'].should.equal('bar'); done(); });
#attach(name, path, filename)
#field(name, val)
#field(object)
with network error
- should error
request .get('http://localhost:' + this.port + '/') .end(function(err, res){ assert(err, 'expected an error'); done(); });
request
- should start with 200
request .get(base) .end(function(err, res){ res.should.have.status(200) res.text.should.match(/^\d+$/); ts = +res.text; done(); });
- should then be 304
request .get(base) .set('If-Modified-Since', new Date(ts).toUTCString()) .end(function(err, res){ res.should.have.status(304) // res.text.should.be.empty done(); });
not modified
req.parse(fn)
- should take precedence over default parsers
request .get(base + '/manny') .parse(request.parse['application/json']) .end(function(err, res){ assert(res.ok); assert.equal('{"name":"manny"}', res.text); assert.equal('manny', res.body.name); done(); });
- should be the only parser
request .get(base + '/image') .parse(function(res, fn) { res.on('data', function() {}); }) .end(function(err, res){ assert(res.ok); assert.strictEqual(res.text, undefined); res.body.should.eql({}); done(); });
- should emit error if parser throws
request .get(base + '/manny') .parse(function() { throw new Error('I am broken'); }) .on('error', function(err) { err.message.should.equal('I am broken'); done(); }) .end();
- should emit error if parser returns an error
request .get(base + '/manny') .parse(function(res, fn) { fn(new Error('I am broken')); }) .on('error', function(err) { err.message.should.equal('I am broken'); done(); }) .end()
- should not emit error on chunked json
request .get(base + '/chunked-json') .end(function(err){ assert(!err); done(); });
- should not emit error on aborted chunked json
var req = request .get(base + '/chunked-json') .end(function(err){ assert(!err); done(); }); setTimeout(function(){req.abort()},50);
pipe on redirect
- should follow Location
var stream = fs.createWriteStream(destPath); var redirects = []; var req = request .get(base) .on('redirect', function (res) { redirects.push(res.headers.location); }) stream.on('finish', function () { redirects.should.eql(['/movies', '/movies/all', '/movies/all/0']); fs.readFileSync(destPath, 'utf8').should.eql('first movie page'); done(); }); req.pipe(stream);
request pipe
- should act as a writable stream
var req = request.post(base); var stream = fs.createReadStream('test/node/fixtures/user.json'); req.type('json'); req.on('response', function(res){ res.body.should.eql({ name: 'tobi' }); done(); }); stream.pipe(req);
- should act as a readable stream
var stream = fs.createWriteStream(destPath); var responseCalled = false; var req = request.get(base); req.type('json'); req.on('response', function(res){ res.should.have.status(200); responseCalled = true; }); stream.on('finish', function(){ JSON.parse(fs.readFileSync(destPath, 'utf8')).should.eql({ name: 'tobi' }); responseCalled.should.be.true(); done(); }); req.pipe(stream);
req.query(String)
- should support passing in a string
request .del(base) .query('name=t%F6bi') .end(function(err, res){ res.body.should.eql({ name: 't%F6bi' }); done(); });
- should work with url query-string and string for query
request .del(base + '/?name=tobi') .query('age=2%20') .end(function(err, res){ res.body.should.eql({ name: 'tobi', age: '2 ' }); done(); });
- should support compound elements in a string
request .del(base) .query('name=t%F6bi&age=2') .end(function(err, res){ res.body.should.eql({ name: 't%F6bi', age: '2' }); done(); });
- should work when called multiple times with a string
request .del(base) .query('name=t%F6bi') .query('age=2%F6') .end(function(err, res){ res.body.should.eql({ name: 't%F6bi', age: '2%F6' }); done(); });
- should work with normal `query` object and query string
request .del(base) .query('name=t%F6bi') .query({ age: '2' }) .end(function(err, res){ res.body.should.eql({ name: 't%F6bi', age: '2' }); done(); });
req.query(Object)
- should construct the query-string
request .del(base) .query({ name: 'tobi' }) .query({ order: 'asc' }) .query({ limit: ['1', '2'] }) .end(function(err, res){ res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] }); done(); });
- should not error on dates
var date = new Date(0); request .del(base) .query({ at: date }) .end(function(err, res){ assert.equal(date.toISOString(), res.body.at); done(); });
- should work after setting header fields
request .del(base) .set('Foo', 'bar') .set('Bar', 'baz') .query({ name: 'tobi' }) .query({ order: 'asc' }) .query({ limit: ['1', '2'] }) .end(function(err, res){ res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] }); done(); });
- should append to the original query-string
request .del(base + '/?name=tobi') .query({ order: 'asc' }) .end(function(err, res) { res.body.should.eql({ name: 'tobi', order: 'asc' }); done(); });
- should retain the original query-string
request .del(base + '/?name=tobi') .end(function(err, res) { res.body.should.eql({ name: 'tobi' }); done(); });
- should keep only keys with null querystring values
request .del(base + '/url') .query({ nil: null }) .end(function(err, res) { res.text.should.equal('/url?nil'); done(); });
- query-string should be sent on pipe
var req = request.put(base + '/?name=tobi'); var stream = fs.createReadStream('test/node/fixtures/user.json'); req.on('response', function(res){ res.body.should.eql({ name: 'tobi' }); done(); }); stream.pipe(req);
request.get
- should follow Location with a GET request
var req = request .get(base + '/test-301') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .get(base + '/test-302') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .get(base + '/test-303') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .get(base + '/test-307') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .get(base + '/test-308') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
on 301 redirect
on 302 redirect
on 303 redirect
on 307 redirect
on 308 redirect
request.post
- should follow Location with a GET request
var req = request .post(base + '/test-301') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .post(base + '/test-302') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a GET request
var req = request .post(base + '/test-303') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('GET'); done(); });
- should follow Location with a POST request
var req = request .post(base + '/test-307') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('POST'); done(); });
- should follow Location with a POST request
var req = request .post(base + '/test-308') .redirects(1) .end(function(err, res){ req.req._headers.host.should.eql('localhost:' + server2.address().port + ''); res.status.should.eql(200); res.text.should.eql('POST'); done(); });
on 301 redirect
on 302 redirect
on 303 redirect
on 307 redirect
on 308 redirect
request
- should follow Location
var redirects = []; request .get(base) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; arr.push('/movies'); arr.push('/movies/all'); arr.push('/movies/all/0'); redirects.should.eql(arr); res.text.should.equal('first movie page'); done(); } catch(err) { done(err); } });
- should not follow on HEAD by default
var redirects = []; request.head(base) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { redirects.should.eql([]); res.status.should.equal(302); done(); } catch(err) { done(err); } });
- should follow on HEAD when redirects are set
var redirects = []; request.head(base) .redirects(10) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; arr.push('/movies'); arr.push('/movies/all'); arr.push('/movies/all/0'); redirects.should.eql(arr); assert(!res.text); done(); } catch(err) { done(err); } });
- should remove Content-* fields
request .post(base + '/header') .type('txt') .set('X-Foo', 'bar') .set('X-Bar', 'baz') .send('hey') .end(function(err, res){ try { assert(res.body); res.body.should.have.property('x-foo', 'bar'); res.body.should.have.property('x-bar', 'baz'); res.body.should.not.have.property('content-type'); res.body.should.not.have.property('content-length'); res.body.should.not.have.property('transfer-encoding'); done(); } catch(err) { done(err); } });
- should retain cookies
request .get(base + '/header') .set('Cookie', 'foo=bar;') .end(function(err, res){ try { assert(res.body); res.body.should.have.property('cookie', 'foo=bar;'); done(); } catch(err) { done(err); } });
- should not resend query parameters
var redirects = []; var query = []; request .get(base + '/?foo=bar') .on('redirect', function(res){ query.push(res.headers.query); redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; arr.push('/movies'); arr.push('/movies/all'); arr.push('/movies/all/0'); redirects.should.eql(arr); res.text.should.equal('first movie page'); query.should.eql(['{"foo":"bar"}', '{}', '{}']); res.headers.query.should.eql('{}'); done(); } catch(err) { done(err); } });
- should handle no location header
request .get(base + '/bad-redirect') .end(function(err, res){ try { err.message.should.equal('No location header for redirect'); done(); } catch(err) { done(err); } });
- should redirect to a sibling path
var redirects = []; request .get(base + '/relative') .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { redirects.should.eql(['tobi']); res.text.should.equal('tobi'); done(); } catch(err) { done(err); } });
- should redirect to a parent path
var redirects = []; request .get(base + '/relative/sub') .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { redirects.should.eql(['../tobi']); res.text.should.equal('tobi'); done(); } catch(err) { done(err); } });
- should alter the default number of redirects to follow
var redirects = []; request .get(base) .redirects(2) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; assert(res.redirect, 'res.redirect'); arr.push('/movies'); arr.push('/movies/all'); redirects.should.eql(arr); res.text.should.match(/Moved Temporarily|Found/); done(); } catch(err) { done(err); } });
- should redirect as GET
var redirects = []; request .post(base + '/movie') .send({ name: 'Tobi' }) .redirects(2) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; arr.push('/movies/all/0'); redirects.should.eql(arr); res.text.should.equal('first movie page'); done(); } catch(err) { done(err); } });
- should redirect as GET
var redirects = []; request .post(base + '/movie') .type('form') .field('name', 'Tobi') .redirects(2) .on('redirect', function(res){ redirects.push(res.headers.location); }) .end(function(err, res){ try { var arr = []; arr.push('/movies/all/0'); redirects.should.eql(arr); res.text.should.equal('first movie page'); done(); } catch(err) { done(err); } });
on redirect
when relative
req.redirects(n)
on POST
on POST using multipart/form-data
response
- should act as a readable stream
var req = request .get(base) .buffer(false); req.end(function(err,res){ if (err) return done(err); var trackEndEvent = 0; var trackCloseEvent = 0; res.on('end',function(){ trackEndEvent++; trackEndEvent.should.equal(1); trackCloseEvent.should.equal(0); // close should not have been called done(); }); res.on('close',function(){ trackCloseEvent++; }); (function(){ res.pause() }).should.not.throw(); (function(){ res.resume() }).should.not.throw(); (function(){ res.destroy() }).should.not.throw(); });
.timeout(ms)
- should error
request .get(base + '/500') .timeout(150) .end(function(err, res){ assert(err, 'expected an error'); assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); assert.equal('ECONNABORTED', err.code, 'expected abort error code') done(); });
when timeout is exceeded
res.toError()
- should return an Error
request .get(base) .end(function(err, res){ var err = res.toError(); assert.equal(err.status, 400); assert.equal(err.method, 'GET'); assert.equal(err.path, '/'); assert.equal(err.message, 'cannot GET / (400)'); assert.equal(err.text, 'invalid json'); done(); });
[unix-sockets] http
- path: / (root)
request .get(base + '/') .end(function(err, res) { assert(res.ok); assert.strictEqual('root ok!', res.text); done(); });
- path: /request/path
request .get(base + '/request/path') .end(function(err, res) { assert(res.ok); assert.strictEqual('request path ok!', res.text); done(); });
request
[unix-sockets] https
- path: / (root)
request .get(base + '/') .ca(cert) .end(function(err, res) { assert(res.ok); assert.strictEqual('root ok!', res.text); done(); });
- path: /request/path
request .get(base + '/request/path') .ca(cert) .end(function(err, res) { assert(res.ok); assert.strictEqual('request path ok!', res.text); done(); });
request
req.get()
- should set a default user-agent
request .get(base + '/ua') .end(function(err, res){ assert(res.headers); assert(res.headers['user-agent']); assert(/^node-superagent\/\d+\.\d+\.\d+(?:-[a-z]+\.\d+|$)/.test(res.headers['user-agent'])); done(); });
- should be able to override user-agent
request .get(base + '/ua') .set('User-Agent', 'foo/bar') .end(function(err, res){ assert(res.headers); assert.equal(res.headers['user-agent'], 'foo/bar'); done(); });
- should be able to wipe user-agent
request .get(base + '/ua') .unset('User-Agent') .end(function(err, res){ assert(res.headers); assert.equal(res.headers['user-agent'], void 0); done(); });
utils.type(str)
- should return the mime type
utils.type('application/json; charset=utf-8') .should.equal('application/json'); utils.type('application/json') .should.equal('application/json');
utils.params(str)
- should return the field parameters
var str = 'application/json; charset=utf-8; foo = bar'; var obj = utils.params(str); obj.charset.should.equal('utf-8'); obj.foo.should.equal('bar'); var str = 'application/json'; utils.params(str).should.eql({});
utils.parseLinks(str)
- should parse links
var str = '<https://api.github.com/repos/visionmedia/mocha/issues?page=2>; rel="next", <https://api.github.com/repos/visionmedia/mocha/issues?page=5>; rel="last"'; var ret = utils.parseLinks(str); ret.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2'); ret.last.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=5');