Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Futuristic test runner... for HTTP or API endpoints.
AVA is a fantastic "next gen" test-runner. Hopefully you've heard about it...
Its intention, as far as I understand, is to test code & modules within a node
environment.
So, out of the box, AVA does not support testing anything in browser
environment.
This package aims to bridge that gap (at least a little bit) by extending AVA's Test
class with HTTP methods.
And, in typcical AVA-fahion, you can use these HTTP methods with promise, generator, and async function support. :)
Note: To use
ava-http
, you must haveava
installed already.
npm install --save-dev ava-http
// package.json
{
"name": "awesome-package",
"scripts": {
"test": "ava"
},
"devDependencies": {
"ava": "^0.11.0",
"ava-http": "^0.1.0"
}
}
Since AVA-http is a clean extension of AVA, you can simply import test
from ava-http
instead of ava
. Everything will work as expected.
import test from 'ava-http';
// Normal AVA test
test('foo', t => {
// ...
t.pass();
});
// AVA-http test
test('bar', async t => {
const expected = /*...*/;
const res = await t.context.http.get('http://google.com');
t.true(typeof res === 'object');
t.same(res, expected);
});
npm test
Please see AVA's docs for full information.
It is required to include babel-core/register
in your AVA config.
{
"ava": {
"require": ["babel-core/register"]
}
}
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.
Unfortunately, for now, the only way to inject custom methods into AVA/Test is through a context
property.
This means that AVA-http's methods must be accessed as such:
test('test name here', async t => {
t.context.http.get(url, //...
t.context.http.post(url, //...
t.context.http.put(url, //...
t.context.http.del(url, //...
});
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
:
t.context.http.get
==> t.context.http.getResponse
t.context.http.post
==> t.context.http.postResponse
t.context.http.put
==> t.context.http.putResponse
t.context.http.del
==> t.context.http.delResponse
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
url
:string
options
:object
Returns: Promise
On resolve success, returns payload
. On error, returns full Response
object.
url
:string
options
:object
Returns: Promise
Always returns full Response
object.
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.
Type:
object
Default: {}
The payload data to be sent to the server. Leave json
as true
to automatically stringify as JSON.
Type:
object
Default: {}
The request headers to send.
Type:
object
Default: {}
An alias of qs
.
Type:
object
Default: {}
The query string to append to the URL. See this example.
Type:
boolean
Default: true
Whether or not the response body should be parsed as JSON.
Type:
function
Default: null
Transform the response into a custom value with which the promise is resolved. See here for info.
test('thennable', async t => {
t.context.http.get('http://localhost').then(res => {
t.same(res, {expected: 'output'});
});
});
test('async/await', async t => {
const res = await t.context.http.get('http://localhost');
t.same(res, {expected: 'output'});
});
test('generator/yield', function * (t) {
const res = yield t.context.http.get('http://localhost');
t.same(res, {expected: 'output'});
});
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 t.context.http.getResponse('http://localhost');
console.log('these are the headers: ', res.headers);
t.same(res.statusCode, 200);
});
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 => {
t.context.http.get('http://localhost').catch(err => {
t.same(err.statusCode, 404);
});
});
test('post json object', async t => {
const body = {some: 'data'};
const res = await t.context.http.post('http://localhost', {body});
t.same(res, {expected: 'output'});
});
// or, to also assert a statusCode...
test('post json object, assert status', async t => {
const body = {some: 'data'};
const res = await t.context.http.postResponse('http://localhost', {body});
t.same(res.statusCode, 201);
t.same(res.response.body, {expected: 'output'});
});
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
const res = await t.context.http.post('http://localhost', {form});
t.same(res, {expected: 'output'});
});
test('update an item', async t => {
const body = {some: 'data'};
const res = await t.context.http.put('http://localhost/items/2', {body});
t.same(res, {expected: 'output'});
});
test('delete an item', async t => {
const res = await t.context.http.delResponse('http://localhost/items/2');
t.same(res.statusCode, 200);
});
// expecting an error...
test('delete is unauthorized', async t => {
t.context.http.del('http://localhost/items/2').catch(err => {
t.same(err.statusCode, 401);
});
});
test('delete is authorized with token', async t => {
const headers = {
'Authorization': 'Bearer 1234567890'
};
const res = t.context.http.del('http://localhost/items/2', {headers});
t.same(res, {expected: 'output'});
});
test('get item with parameters', async t => {
const params = {
token: 'xxxxx xxxxx' // -> uri + '?token=xxxxx%20xxxxx'
};
const res = t.context.http.get('http://localhost', {params});
t.same(res, {expected: 'output'});
});
AVA/Test
&& embed methods before export -- no more context
. (not possible atm).This will make for ideal test syntax:
test('name of test', t => { t.get(url).then(); });
- [ ] Define a complete Micro test server, with routing
- [ ] Start-up test server on `test.before()`
- [ ] Cleanup/Remove all `const url = await ...` within tests
<div align="center">
<br>
<br>
<br>
<img src="https://cdn.rawgit.com/sindresorhus/ava/fe1cea1ca3d2c8518c0cc39ec8be592beab90558/media/logo.svg" width="200" alt="AVA">
<br>
<br>
</div>
## License
MIT © [Luke Edwards](https://lukeed.com) et [al](https://github.com/lukeed/ava-http/graphs/contributors)
FAQs
Async HTTP request wrapper
We found that ava-http demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.