ava-http
v1.0.0
Published
Async HTTP request wrapper
Downloads
1,352
Maintainers
Readme
AVA-http
Async HTTP requests.
AVA-http is a wrapper around the Request-Promise library, making it simpler to initiate HTTP requests.
It was made for succint API testing within AVA, but it can be used anywhere.
Installation
npm install --save-dev ava-http
Usage
The generic HTTP methods are included: [get
, post
, put
, delete
].
Each of these, used within the context of an AVA test, will return a Promise
that can be await
ed, yield
ed, or then
/catch
'd.
Erroneous responses will always return the full Response
object and should be caught with .catch()
.
Successful responses will return the payload
(aka, response.body
) by default.
If you would also like the full Response
object, exchange your method
for methodResponse
:
http.get
==>http.getResponse
http.post
==>http.postResponse
http.put
==>http.putResponse
http.del
==>http.delResponse
API
get(url[, options])
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
getResponse(url[, options])
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
post(url[, options])
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
postResponse(url[, options])
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
put(url[, options])
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
putResponse(url[, options])
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
del(url[, options])
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
delResponse(url[, options])
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
Options
form
Type:
object
Default:
{}
An object of key:value
pairs of formdata that will be urlencoded before reaching the server.
The request's headers
will automatically include 'content-type': 'application/x-www-form-urlencoded'
.
This simulates sending an HTML form via normal means.
body
Type:
object
Default:
{}
The payload data to be sent to the server. Leave json
as true
to automatically stringify as JSON.
headers
Type:
object
Default:
{}
The request headers to send.
params
Type:
object
Default:
{}
An alias of qs
.
qs
Type:
object
Default:
{}
The query string to append to the URL. See this example.
json
Type:
boolean
Default:
true
Whether or not the response body should be parsed as JSON.
transform
Type:
function
Default:
null
Transform the response into a custom value with which the promise is resolved. See here for info.
AVA
Setup
You must have AVA installed already.
import test from 'ava';
import http from 'ava-http';
test('foo should succeed', t => {
const res = await http.get('http://localhost/posts');
t.true(typeof res === 'object'); // json object by default
t.deepEqual(res, {expected: 'output'}); // deepEqual comparison
});
test('bar should error', t => {
http.post('http://localhost/posts').catch(err => {
t.is(err.statusCode, 400);
t.deepEqual(err.response.body, {error: 'message'});
});
});
Examples
Thennables
test('thennable', async t => {
http.get('http://localhost').then(res => {
t.deepEqual(res, {expected: 'output'});
});
});
Async Support
test('async/await', async t => {
t.deepEqual(await http.get('http://localhost'), {expected: 'output'});
});
Generator Support
test('generator/yield', function * (t) {
t.deepEqual(yield http.get('http://localhost'), {expected: 'output'});
});
Response Headers
By default, successful responses will only yield their payloads. If you need/want to test a status code, for example, this will suffice:
test('response headers', async t => {
const res = await http.getResponse('http://localhost');
console.log('these are the headers: ', res.headers);
t.is(res.statusCode, 200);
});
Expecting Errors
In order to successfully expect and catch a Response Error, the test must be asserted witin the Promise's .catch()
.
For more information, please check out Request-Promise's excellent documentation on the Promise API.
test('404 error is thrown', async t => {
http.get('http://localhost').catch(err => t.is(err.statusCode, 404));
});
Posting JSON
test('post json object', async t => {
const body = {some: 'data'};
t.deepEqual(await http.post('http://localhost', {body}), {expected: 'output'});
});
// or, to also assert a statusCode...
test('post json object, assert status', async t => {
const body = {some: 'data'};
const res = await http.postResponse('http://localhost', {body});
t.is(res.statusCode, 201);
t.deepEqual(res.response.body, {expected: 'output'});
});
Posting as a HTML Form
All data within the form
object will be urlencoded
, just as any normal <form>
would!
test('post like a form', async t => {
const form = {some: 'data'}; // will be urlencoded
t.deepEqual(await http.post('http://localhost', {form}), {expected: 'output'});
});
Updating an Item
test('update an item', async t => {
const body = {some: 'data'};
t.deepEqual(await http.put('http://localhost/items/2', {body}), {expected: 'output'});
});
Deleting an Item
test('delete an item', async t => {
const res = await http.delResponse('http://localhost/items/2');
t.is(res.statusCode, 200);
});
// expecting an error...
test('delete is unauthorized', async t => {
http.del('http://localhost/items/2').catch(err => t.is(err.statusCode, 401));
});
Pass an Authorization Token (eg, JWT)
test('delete is authorized with token', async t => {
const headers = {
'Authorization': 'Bearer 1234567890'
};
t.deepEqual(await http.del('http://localhost/items/2', {headers}), {expected: 'output'});
});
Passing Query String Parameters
test('get item with parameters', async t => {
const params = {
token: 'xxxxx xxxxx' // -> uri + '?token=xxxxx%20xxxxx'
};
t.deepEqual(await http.get('http://localhost', {params}), {expected: 'output'});
});
Goals
Ideally, AVA-http is the asynchronous, node-equivalent of PHPUnit. This means that similar, custom assertions will be added into AVA's Test class (as opposed to exporting an http
wrapper, as it currently stands). Methods will/should be as follows:
t.jsonEquals
t.jsonContains
t.jsonStructure
t.responseOk
t.responseNotOk
t.responseCode
t.responseType
t.headersEqual
t.headersContain
An ideal test setup may look like this:
test(async t => {
t.responseOk(await get(url)); // no error
});
test(async t => {
const body = {sent: 'data'};
t.jsonContains(await post(url, {body}), {message: 'success'});
});
test(async t => {
t.jsonEquals(await get(url), {exact: 'match'});
});
test(async => {
t.responseCode(await get(url), 301);
});
test(async => {
t.headersContain(await get(url), {'Cache-Control': 'max-age=21600'});
});
TODOs
- [ ] Define a complete Micro test server, with routing
- [ ] Start-up test server on
test.before()
- [ ] Cleanup/Remove all
const url = await ...
within tests
License
MIT © Luke Edwards et al