Luke Childs
8 years ago
9 changed files with 336 additions and 339 deletions
@ -1,124 +1,121 @@ |
|||
const got = require('got') |
|||
const cacheManager = require('cache-manager') |
|||
const querystring = require('querystring') |
|||
const pkg = require('../package.json') |
|||
const expired = require('expired') |
|||
const deepAssign = require('deep-assign') |
|||
const querystring = require('querystring'); |
|||
const got = require('got'); |
|||
const cacheManager = require('cache-manager'); |
|||
const expired = require('expired'); |
|||
const deepAssign = require('deep-assign'); |
|||
const pkg = require('../package.json'); |
|||
|
|||
class Onionoo { |
|||
|
|||
// Constructor returns a new object so instance properties are private
|
|||
constructor (options = {}) { |
|||
// Set default options
|
|||
this.options = Object.assign({}, { |
|||
baseUrl: 'https://onionoo.torproject.org', |
|||
endpoints: [ |
|||
'summary', |
|||
'details', |
|||
'bandwidth', |
|||
'weights', |
|||
'clients', |
|||
'uptime' |
|||
] |
|||
}, options) |
|||
if (options.cache !== false) { |
|||
this.options.cache = cacheManager.caching(Object.assign({}, { |
|||
store: 'memory', |
|||
max: 500 |
|||
}, options.cache)) |
|||
} |
|||
|
|||
// Return object containing endpoint methods
|
|||
return this.options.endpoints.reduce((onionoo, endpoint) => { |
|||
onionoo[endpoint] = this.createEndpointMethod(endpoint) |
|||
|
|||
return onionoo |
|||
}, {}) |
|||
} |
|||
|
|||
// Returns a function to make requests to a given endpoint
|
|||
createEndpointMethod (endpoint) { |
|||
return options => { |
|||
// Build query string (don't encode ':' for search filters)
|
|||
const qs = querystring.encode(options).replace(/%3A/g, ':') |
|||
|
|||
// Build url
|
|||
let url = `${this.options.baseUrl}/${endpoint}` |
|||
url += qs ? `?${qs}` : '' |
|||
|
|||
// If caching is enabled, check for url in cache
|
|||
if (this.options.cache) { |
|||
return this.options.cache.get(url) |
|||
.then(cachedResult => { |
|||
let options = {} |
|||
|
|||
// If we have it cached
|
|||
if (cachedResult) { |
|||
// Return the cached entry if it's still valid
|
|||
if (!expired(cachedResult.headers)) { |
|||
return cachedResult |
|||
|
|||
// If it's stale, add last-modified date to headers
|
|||
} else if (cachedResult.headers['last-modified']) { |
|||
options.headers = { |
|||
'if-modified-since': cachedResult.headers['last-modified'] |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Make a request
|
|||
return this.makeRequest(url, options) |
|||
.then(response => { |
|||
// If we get a 304, fill in the body
|
|||
if (response.statusCode === 304) { |
|||
response.body = cachedResult.body |
|||
} |
|||
|
|||
// If we get a 200 or 304, cache it
|
|||
if ([200, 304].includes(response.statusCode)) { |
|||
this.options.cache.set(url, response) |
|||
} |
|||
|
|||
return response |
|||
}) |
|||
}) |
|||
|
|||
// If caching is disabled, just make the request
|
|||
} else { |
|||
return this.makeRequest(url) |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Returns a promise for a request
|
|||
makeRequest (url, options = {}) { |
|||
options = deepAssign({ |
|||
headers: { |
|||
'user-agent': `onionoo-node-client v${pkg.version} (${pkg.homepage})` |
|||
} |
|||
}, options) |
|||
|
|||
return got(url, options) |
|||
.catch(error => { |
|||
// Don't throw 304 responses
|
|||
if (error.statusCode === 304) { |
|||
return error.response |
|||
} else { |
|||
throw error |
|||
} |
|||
}) |
|||
.then(response => { |
|||
// Format response
|
|||
response = { |
|||
statusCode: response.statusCode, |
|||
statusMessage: response.statusMessage, |
|||
headers: response.headers, |
|||
body: response.body && JSON.parse(response.body) |
|||
} |
|||
|
|||
return response |
|||
}) |
|||
} |
|||
// Constructor returns a new object so instance properties are private
|
|||
constructor(options = {}) { |
|||
// Set default options
|
|||
this.options = Object.assign({}, { |
|||
baseUrl: 'https://onionoo.torproject.org', |
|||
endpoints: [ |
|||
'summary', |
|||
'details', |
|||
'bandwidth', |
|||
'weights', |
|||
'clients', |
|||
'uptime' |
|||
] |
|||
}, options); |
|||
if (options.cache !== false) { |
|||
this.options.cache = cacheManager.caching(Object.assign({}, { |
|||
store: 'memory', |
|||
max: 500 |
|||
}, options.cache)); |
|||
} |
|||
|
|||
// Return object containing endpoint methods
|
|||
return this.options.endpoints.reduce((onionoo, endpoint) => { |
|||
onionoo[endpoint] = this.createEndpointMethod(endpoint); |
|||
|
|||
return onionoo; |
|||
}, {}); |
|||
} |
|||
|
|||
// Returns a function to make requests to a given endpoint
|
|||
createEndpointMethod(endpoint) { |
|||
return options => { |
|||
// Build query string (don't encode ':' for search filters)
|
|||
const qs = querystring.encode(options).replace(/%3A/g, ':'); |
|||
|
|||
// Build url
|
|||
let url = `${this.options.baseUrl}/${endpoint}`; |
|||
url += qs ? `?${qs}` : ''; |
|||
|
|||
// If caching is enabled, check for url in cache
|
|||
if (this.options.cache) { |
|||
return this.options.cache.get(url) |
|||
.then(cachedResult => { |
|||
let options = {}; |
|||
|
|||
// If we have it cached
|
|||
if (cachedResult) { |
|||
// Return the cached entry if it's still valid
|
|||
if (!expired(cachedResult.headers)) { |
|||
return cachedResult; |
|||
|
|||
// If it's stale, add last-modified date to headers
|
|||
} else if (cachedResult.headers['last-modified']) { |
|||
options.headers = { |
|||
'if-modified-since': cachedResult.headers['last-modified'] |
|||
}; |
|||
} |
|||
} |
|||
|
|||
// Make a request
|
|||
return this.makeRequest(url, options) |
|||
.then(response => { |
|||
// If we get a 304, fill in the body
|
|||
if (response.statusCode === 304) { |
|||
response.body = cachedResult.body; |
|||
} |
|||
|
|||
// If we get a 200 or 304, cache it
|
|||
if ([200, 304].includes(response.statusCode)) { |
|||
this.options.cache.set(url, response); |
|||
} |
|||
|
|||
return response; |
|||
}); |
|||
}); |
|||
} |
|||
// If caching is disabled, just make the request
|
|||
return this.makeRequest(url); |
|||
}; |
|||
} |
|||
|
|||
// Returns a promise for a request
|
|||
makeRequest(url, options = {}) { |
|||
options = deepAssign({ |
|||
headers: { |
|||
'user-agent': `onionoo-node-client v${pkg.version} (${pkg.homepage})` |
|||
} |
|||
}, options); |
|||
|
|||
return got(url, options) |
|||
.catch(err => { |
|||
// Don't throw 304 responses
|
|||
if (err.statusCode === 304) { |
|||
return err.response; |
|||
} |
|||
throw err; |
|||
}) |
|||
.then(response => { |
|||
// Format response
|
|||
response = { |
|||
statusCode: response.statusCode, |
|||
statusMessage: response.statusMessage, |
|||
headers: response.headers, |
|||
body: response.body && JSON.parse(response.body) |
|||
}; |
|||
|
|||
return response; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
module.exports = Onionoo |
|||
module.exports = Onionoo; |
|||
|
@ -0,0 +1,19 @@ |
|||
import test from 'ava'; |
|||
import nock from 'nock'; |
|||
import Onionoo from '../'; |
|||
import data from './fixtures/data'; |
|||
|
|||
test('Can pass in custom endpoint', async t => { |
|||
const baseUrl = 'http://foo.com'; |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const onionoo = new Onionoo({baseUrl}); |
|||
|
|||
const scope = nock(baseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse); |
|||
|
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
}); |
@ -1,19 +0,0 @@ |
|||
import test from 'ava' |
|||
import nock from 'nock' |
|||
import data from './fixtures/data' |
|||
import Onionoo from '../' |
|||
|
|||
test('Can pass in custom endpoint', async t => { |
|||
const baseUrl = 'http://foo.com' |
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const onionoo = new Onionoo({ baseUrl }) |
|||
|
|||
const scope = nock(baseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse) |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
}) |
@ -1,133 +1,133 @@ |
|||
import test from 'ava' |
|||
import nock from 'nock' |
|||
import subSeconds from 'date-fns/sub_seconds' |
|||
import delay from 'delay' |
|||
import data from './fixtures/data' |
|||
import Onionoo from '../' |
|||
import test from 'ava'; |
|||
import nock from 'nock'; |
|||
import subSeconds from 'date-fns/sub_seconds'; |
|||
import delay from 'delay'; |
|||
import Onionoo from '../'; |
|||
import data from './fixtures/data'; |
|||
|
|||
test('Cache can be disabled', async t => { |
|||
const onionoo = new Onionoo({ cache: false }) |
|||
const onionoo = new Onionoo({cache: false}); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const responseHeaders = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=300' |
|||
} |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const responseHeaders = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=300' |
|||
}; |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
|
|||
const scope2 = nock(data.defaultBaseUrl) |
|||
const scope2 = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response2 = await onionoo[defaultEndpoint]() |
|||
const response2 = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response2.body, data.dummyResponse) |
|||
t.truthy(scope2.isDone()) |
|||
}) |
|||
t.deepEqual(response2.body, data.dummyResponse); |
|||
t.truthy(scope2.isDone()); |
|||
}); |
|||
|
|||
test('Responses with future max-age are cached', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const responseHeaders = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=300' |
|||
} |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const responseHeaders = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=300' |
|||
}; |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
|
|||
const cachedResponse = await onionoo[defaultEndpoint]() |
|||
const cachedResponse = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(cachedResponse.body, data.dummyResponse) |
|||
}) |
|||
t.deepEqual(cachedResponse.body, data.dummyResponse); |
|||
}); |
|||
|
|||
test('Responses older than max-age are not cached', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const responseHeaders = { |
|||
date: subSeconds(new Date(), 15).toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=10' |
|||
} |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const responseHeaders = { |
|||
date: subSeconds(new Date(), 15).toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=10' |
|||
}; |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
|
|||
const scope2 = nock(data.defaultBaseUrl) |
|||
const scope2 = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response2 = await onionoo[defaultEndpoint]() |
|||
const response2 = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response2.body, data.dummyResponse) |
|||
t.truthy(scope2.isDone()) |
|||
}) |
|||
t.deepEqual(response2.body, data.dummyResponse); |
|||
t.truthy(scope2.isDone()); |
|||
}); |
|||
|
|||
test('When expired, add last-modified date to headers and handle 304', async t => { |
|||
const onionoo = new Onionoo() |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const initialDate = new Date().toUTCString() |
|||
const responseHeaders = { |
|||
date: initialDate, |
|||
age: 0, |
|||
'cache-control': 'public, max-age=1', |
|||
'last-modified': initialDate |
|||
} |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const initialDate = new Date().toUTCString(); |
|||
const responseHeaders = { |
|||
date: initialDate, |
|||
age: 0, |
|||
'cache-control': 'public, max-age=1', |
|||
'last-modified': initialDate |
|||
}; |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse, responseHeaders) |
|||
.reply(200, data.dummyResponse, responseHeaders); |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
|
|||
const requestHeaders = { |
|||
'if-modified-since': initialDate |
|||
} |
|||
const responseHeaders304 = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=10', |
|||
'last-modified': initialDate |
|||
} |
|||
const requestHeaders = { |
|||
'if-modified-since': initialDate |
|||
}; |
|||
const responseHeaders304 = { |
|||
date: new Date().toUTCString(), |
|||
age: 0, |
|||
'cache-control': 'public, max-age=10', |
|||
'last-modified': initialDate |
|||
}; |
|||
|
|||
const scope2 = nock(data.defaultBaseUrl, { requestHeaders }) |
|||
const scope2 = nock(data.defaultBaseUrl, {requestHeaders}) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(304, null, responseHeaders304) |
|||
.reply(304, null, responseHeaders304); |
|||
|
|||
const response2 = await delay(2000).then(onionoo[defaultEndpoint]) |
|||
const response2 = await delay(2000).then(onionoo[defaultEndpoint]); |
|||
|
|||
t.deepEqual(response2.body, data.dummyResponse) |
|||
t.truthy(scope2.isDone()) |
|||
t.deepEqual(response2.body, data.dummyResponse); |
|||
t.truthy(scope2.isDone()); |
|||
|
|||
const cachedResponse = await onionoo[defaultEndpoint]() |
|||
const cachedResponse = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(cachedResponse.body, data.dummyResponse) |
|||
}) |
|||
t.deepEqual(cachedResponse.body, data.dummyResponse); |
|||
}); |
|||
|
@ -1,48 +1,48 @@ |
|||
import test from 'ava' |
|||
import nock from 'nock' |
|||
import data from './fixtures/data' |
|||
import Onionoo from '../' |
|||
import test from 'ava'; |
|||
import nock from 'nock'; |
|||
import Onionoo from '../'; |
|||
import data from './fixtures/data'; |
|||
|
|||
test('Onionoo instance contains default endpoints', t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
t.deepEqual(Object.keys(onionoo), data.defaultEndpoints) |
|||
}) |
|||
t.deepEqual(Object.keys(onionoo), data.defaultEndpoints); |
|||
}); |
|||
|
|||
test('Default endpoint makes correct request', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const scope = nock(data.defaultBaseUrl) |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(200, data.dummyResponse) |
|||
.reply(200, data.dummyResponse); |
|||
|
|||
const response = await onionoo[defaultEndpoint]() |
|||
const response = await onionoo[defaultEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
}) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
|
|||
test('Can pass in custom endpoint array', t => { |
|||
const endpoints = [ |
|||
'foo', |
|||
'bar' |
|||
] |
|||
const onionoo = new Onionoo({ endpoints }) |
|||
const endpoints = [ |
|||
'foo', |
|||
'bar' |
|||
]; |
|||
const onionoo = new Onionoo({endpoints}); |
|||
|
|||
t.deepEqual(Object.keys(onionoo), endpoints) |
|||
}) |
|||
t.deepEqual(Object.keys(onionoo), endpoints); |
|||
}); |
|||
|
|||
test('Custom endpoint makes correct request', async t => { |
|||
const customEndpoint = 'foo' |
|||
const onionoo = new Onionoo({ endpoints: [customEndpoint] }) |
|||
const customEndpoint = 'foo'; |
|||
const onionoo = new Onionoo({endpoints: [customEndpoint]}); |
|||
|
|||
const scope = nock(data.defaultBaseUrl) |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${customEndpoint}`) |
|||
.reply(200, data.dummyResponse) |
|||
.reply(200, data.dummyResponse); |
|||
|
|||
const response = await onionoo[customEndpoint]() |
|||
const response = await onionoo[customEndpoint](); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
}) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
|
@ -1,48 +1,48 @@ |
|||
import test from 'ava' |
|||
import nock from 'nock' |
|||
import data from './fixtures/data' |
|||
import Onionoo from '../' |
|||
import test from 'ava'; |
|||
import nock from 'nock'; |
|||
import Onionoo from '../'; |
|||
import data from './fixtures/data'; |
|||
|
|||
test('Handle HTML responses for errors', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const scope = nock(data.defaultBaseUrl) |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(400, data.dummy400Response) |
|||
.reply(400, data.dummy400Response); |
|||
|
|||
try { |
|||
await onionoo[defaultEndpoint]() |
|||
} catch (e) { |
|||
t.deepEqual(e.response.body, data.dummy400Response) |
|||
} |
|||
try { |
|||
await onionoo[defaultEndpoint](); |
|||
} catch (err) { |
|||
t.deepEqual(err.response.body, data.dummy400Response); |
|||
} |
|||
|
|||
t.truthy(scope.isDone()) |
|||
}) |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
|
|||
test('Throw useful errors for HTTP response codes', async t => { |
|||
const onionoo = new Onionoo() |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const responseCodes = { |
|||
400: 'Bad Request', |
|||
404: 'Not Found', |
|||
500: 'Internal Server Error', |
|||
503: 'Service Unavailable' |
|||
} |
|||
|
|||
for (const responseCode in responseCodes) { |
|||
const scope = nock(data.defaultBaseUrl) |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const responseCodes = { |
|||
400: 'Bad Request', |
|||
404: 'Not Found', |
|||
500: 'Internal Server Error', |
|||
503: 'Service Unavailable' |
|||
}; |
|||
|
|||
Object.keys(responseCodes).forEach(async responseCode => { |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}`) |
|||
.reply(responseCode) |
|||
|
|||
try { |
|||
await onionoo[defaultEndpoint]() |
|||
} catch (e) { |
|||
t.is(e.message, `Response code ${responseCode} (${responseCodes[responseCode]})`) |
|||
t.is(e.statusCode, parseInt(responseCode, 10)) |
|||
t.is(e.statusMessage, responseCodes[responseCode]) |
|||
} |
|||
t.truthy(scope.isDone()) |
|||
} |
|||
}) |
|||
.reply(responseCode); |
|||
|
|||
try { |
|||
await onionoo[defaultEndpoint](); |
|||
} catch (err) { |
|||
t.is(err.message, `Response code ${responseCode} (${responseCodes[responseCode]})`); |
|||
t.is(err.statusCode, parseInt(responseCode, 10)); |
|||
t.is(err.statusMessage, responseCodes[responseCode]); |
|||
} |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
}); |
|||
|
@ -1,32 +1,32 @@ |
|||
import test from 'ava' |
|||
import nock from 'nock' |
|||
import data from './fixtures/data' |
|||
import Onionoo from '../' |
|||
import test from 'ava'; |
|||
import nock from 'nock'; |
|||
import Onionoo from '../'; |
|||
import data from './fixtures/data'; |
|||
|
|||
test('Query string is built correctly', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const scope = nock(data.defaultBaseUrl) |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}?foo=bar`) |
|||
.reply(200, data.dummyResponse) |
|||
.reply(200, data.dummyResponse); |
|||
|
|||
const response = await onionoo[defaultEndpoint]({ foo: 'bar' }) |
|||
const response = await onionoo[defaultEndpoint]({foo: 'bar'}); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
}) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
|
|||
test('":" char isn\'t url encoded so filters work', async t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
const defaultEndpoint = data.defaultEndpoints[0] |
|||
const scope = nock(data.defaultBaseUrl) |
|||
const defaultEndpoint = data.defaultEndpoints[0]; |
|||
const scope = nock(data.defaultBaseUrl) |
|||
.get(`/${defaultEndpoint}?foo=key:value`) |
|||
.reply(200, data.dummyResponse) |
|||
.reply(200, data.dummyResponse); |
|||
|
|||
const response = await onionoo[defaultEndpoint]({ foo: 'key:value' }) |
|||
const response = await onionoo[defaultEndpoint]({foo: 'key:value'}); |
|||
|
|||
t.deepEqual(response.body, data.dummyResponse) |
|||
t.truthy(scope.isDone()) |
|||
}) |
|||
t.deepEqual(response.body, data.dummyResponse); |
|||
t.truthy(scope.isDone()); |
|||
}); |
|||
|
@ -1,33 +1,33 @@ |
|||
import test from 'ava' |
|||
import Onionoo from '../' |
|||
import test from 'ava'; |
|||
import Onionoo from '../'; |
|||
|
|||
test('Onionoo is a function', t => { |
|||
t.is(typeof Onionoo, 'function') |
|||
}) |
|||
t.is(typeof Onionoo, 'function'); |
|||
}); |
|||
|
|||
test('Onionoo cannot be invoked without \'new\'', t => { |
|||
t.throws(() => Onionoo()) |
|||
t.notThrows(() => new Onionoo()) |
|||
}) |
|||
t.throws(() => Onionoo()); // eslint-disable-line new-cap
|
|||
t.notThrows(() => new Onionoo()); |
|||
}); |
|||
|
|||
test('Onionoo instance is an object', t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
t.is(typeof onionoo, 'object') |
|||
}) |
|||
t.is(typeof onionoo, 'object'); |
|||
}); |
|||
|
|||
test('Onionoo instance contains endpoint methods', t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
Object.keys(onionoo).forEach(endpoint => { |
|||
t.is(typeof onionoo[endpoint], 'function') |
|||
}) |
|||
}) |
|||
Object.keys(onionoo).forEach(endpoint => { |
|||
t.is(typeof onionoo[endpoint], 'function'); |
|||
}); |
|||
}); |
|||
|
|||
test('Endpoint methods return promise', t => { |
|||
const onionoo = new Onionoo() |
|||
const onionoo = new Onionoo(); |
|||
|
|||
Object.keys(onionoo).forEach(endpoint => { |
|||
t.true(onionoo[endpoint]() instanceof Promise) |
|||
}) |
|||
}) |
|||
Object.keys(onionoo).forEach(endpoint => { |
|||
t.true(onionoo[endpoint]() instanceof Promise); |
|||
}); |
|||
}); |
|||
|
Loading…
Reference in new issue