Skip to content

Commit

Permalink
Merge pull request #139 from naugtur/bjoerge-align-json-option-with-r…
Browse files Browse the repository at this point in the history
…equest

Align json option with request, improved to include input from #134 comments
  • Loading branch information
naugtur authored Nov 20, 2016
2 parents dc8f008 + 2d98b73 commit b7f760e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 17 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ type XhrOptions = String | {
method: String?,
timeout: Number?,
headers: Object?,
body: String?,
json: Object?,
body: String? | Object?,
json: Boolean? | Object?,
username: String?,
password: String?,
withCredentials: Boolean?,
Expand Down Expand Up @@ -148,6 +148,8 @@ Pass in body to be send across the [`XMLHttpRequest`][3].
Generally should be a string. But anything that's valid as
a parameter to [`XMLHttpRequest.send`][1] should work (Buffer for file, etc.).
If `options.json` is `true`, then this must be a JSON-serializable object. `options.body` is passed to `JSON.stringify` and sent.
### `options.uri` or `options.url`
The uri to send a request to. Passed to [`XMLHttpRequest.open`][2]. `options.url` and `options.uri` are aliases for each other.
Expand All @@ -163,11 +165,11 @@ Number of miliseconds to wait for response. Defaults to 0 (no timeout). Ignored
### `options.json`
A valid JSON serializable value to be send to the server. If this
is set then we serialize the value and use that as the body.
We also set the Content-Type to `"application/json"`.
Set to `true` to send request as `application/json` (see `options.body`) and parse response from JSON.
For backwards compatibility `options.json` can also be a valid JSON-serializable value to be sent to the server. Additionally the response body is still parsed as JSON
Additionally the response body is parsed as JSON
For sending booleans as JSON body see FAQ
### `options.withCredentials`
Expand Down Expand Up @@ -197,9 +199,11 @@ Pass an `XMLHttpRequest` object (or something that acts like one) to use instead
- How do I send an object or array as POST body?
- `options.body` should be a string. You need to serialize your object before passing to `xhr` for sending.
- To serialize to JSON you can use
`options.json` instead of `options.body` for convenience - then `xhr` will do the serialization and set content-type accordingly.
`options.json:true` with `options.body` for convenience - then `xhr` will do the serialization and set content-type accordingly.
- Where's stream API? `.pipe()` etc.
- Not implemented. You can't reasonably have that in the browser.
- Why can't I send `"true"` as body by passing it as `options.json` anymore?
- Accepting `true` as a value was a bug. Despite what `JSON.stringify` does, the string `"true"` is not valid JSON. If you're sending booleans as JSON, please consider wrapping them in an object or array to save yourself from more trouble in the future. To bring back the old behavior, hardcode `options.json` to `true` and set `options.body` to your boolean value.
- How do I add an `onprogress` listener?
- use `beforeSend` function for non-standard things that are browser specific. In this case:
```js
Expand All @@ -211,7 +215,6 @@ xhr({
})
```
## Mocking Requests
You can override the constructor used to create new requests for testing. When you're making a new request:
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function _createXHR(options) {
headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
if (method !== "GET" && method !== "HEAD") {
headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
body = JSON.stringify(options.json)
body = JSON.stringify(options.json === true ? body : options.json)
}
}

Expand Down
37 changes: 32 additions & 5 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ test("[func] Returns http error responses like npm's request (cross-domain)", fu
if (!window.XDomainRequest) {
xhr({
uri: "http://www.mocky.io/v2/55a02d63265126221a94f025",
useXDR: true
}, function(err, resp, body) {
assert.ifError(err, "no err")
assert.equal(resp.statusCode, 404)
Expand All @@ -55,18 +54,18 @@ test("[func] Returns a falsy body for 204 responses", function(assert) {
test("[func] Calls the callback at most once even if error is thrown issue #127", function(assert) {
//double call happened in chrome
var count = 0;
setTimeout(function(){
setTimeout(function() {
assert.ok(count <= 1, "expected at most one call")
assert.end()
},100)
try{
}, 100)
try {
xhr({
uri: "instanterror://foo"
}, function(err, resp, body) {
count++;
throw Error("dummy error")
})
} catch(e){}
} catch (e) {}
})

test("[func] Times out to an error ", function(assert) {
Expand Down Expand Up @@ -189,6 +188,34 @@ test("xhr[method] get, put, post, patch with url shorthands", function(assert) {
})
})

test("[func] sends options.body as json body when options.json === true", function(assert) {
xhr.post("/mock/echo", {
json: true,
body: {
foo: "bar"
}
}, function(err, resp, body) {
assert.equal(resp.rawRequest.headers["Content-Type"], "application/json")
assert.deepEqual(body, {
foo: "bar"
})
assert.end()
})
})

test("[func] sends options.json as body when it's not a boolean", function(assert) {
xhr.post("/mock/echo", {
json: {
foo: "bar"
}
}, function(err, resp, body) {
assert.equal(resp.rawRequest.headers["Content-Type"], "application/json")
assert.deepEqual(body, {
foo: "bar"
})
assert.end()
})
})

test("xhr[method] get, put, post, patch with url shorthands and options", function(assert) {
var i = 0
Expand Down
9 changes: 6 additions & 3 deletions test/mock-server.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
module.exports = function (req, res) {
console.log('mock:',req.url)
module.exports = function(req, res) {
console.log('mock:', req.url)
if (req.url === '/mock/200ok') {
res.statusCode = 200
res.end('')
} else if (req.url === '/mock/no-content') {
res.statusCode = 204
res.end('')
} else if (req.url === '/mock/echo') {
res.statusCode = 200
req.pipe(res)
} else if (req.url === '/mock/timeout') {
setTimeout(function() {
res.statusCode = 200
res.end()
}, 100)
}
}
}

0 comments on commit b7f760e

Please sign in to comment.