small refactor and add tests

This commit is contained in:
manolodewiner 2018-08-30 12:26:14 +02:00
parent 11892a1f6b
commit f5debab03a
4 changed files with 101 additions and 33 deletions

View File

@ -2,9 +2,13 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0
import { Promise } from 'es6-promise'
import {
Promise
} from 'es6-promise'
import fetchPonyfill from 'fetch-ponyfill'
import { vsprintf } from 'sprintf-js'
import {
vsprintf
} from 'sprintf-js'
import formatText from './format_text'
import stringifyAsQueryParam from './stringify_as_query_param'
@ -12,6 +16,46 @@ import stringifyAsQueryParam from './stringify_as_query_param'
const fetch = fetchPonyfill(Promise)
/**
* @private
* Timeout function following https://github.com/github/fetch/issues/175#issuecomment-284787564
* @param {integer} obj Source object
* @param {Promise} filter Array of key names to select or function to invoke per iteration
* @return {Object} TimeoutError if the time was consumed, otherwise the Promise will be resolved
*/
function timeout(ms, promise) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const errorObject = {
message: 'TimeoutError'
}
reject(new Error(errorObject))
}, ms)
promise.then(resolve, reject)
})
}
/**
* @private
* @param {Promise} res Source object
* @return {Promise} Promise that will resolve with the response if its status was 2xx;
* otherwise rejects with the response
*/
function handleResponse(res) {
// If status is not a 2xx (based on Response.ok), assume it's an error
// See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
if (!(res && res.ok)) {
const errorObject = {
message: 'HTTP Error: Requested page not reachable',
status: `${res.status} ${res.statusText}`,
requestURI: res.url
}
throw errorObject
}
return res
}
/**
* @private
* imported from https://github.com/bigchaindb/js-utility-belt/
@ -36,37 +80,16 @@ const fetch = fetchPonyfill(Promise)
* decamelized into snake case first.
* @param {*[]|Object} config.urlTemplateSpec Format spec to use to expand the url (see sprintf).
* @param {*} config.* All other options are passed through to fetch.
* @param {integer} requestTimeout Timeout for a single request
*
* @return {Promise} Promise that will resolve with the response if its status was 2xx;
* otherwise rejects with the response
* @return {Promise} If requestTimeout the timeout function will be called. Otherwise resolve the
* Promise with the handleResponse function
*/
const timeout = (ms, promise) => new Promise((resolve, reject) => {
setTimeout(() => {
const errorObject = {
message: 'TimeoutError'
}
reject(new Error(errorObject))
}, ms)
return promise.then(resolve, reject)
})
const handleResponse = (res) => {
// If status is not a 2xx (based on Response.ok), assume it's an error
// See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
if (!(res && res.ok)) {
const errorObject = {
message: 'HTTP Error: Requested page not reachable',
status: `${res.status} ${res.statusText}`,
requestURI: res.url
}
throw errorObject
}
return res
}
export default function baseRequest(url, {
jsonBody, query, urlTemplateSpec, ...fetchConfig
jsonBody,
query,
urlTemplateSpec,
...fetchConfig
} = {}, requestTimeout) {
let expandedUrl = url

View File

@ -12,7 +12,7 @@ const DEFAULT_REQUEST_CONFIG = {
}
const BACKOFF_DELAY = 500 // 0.5 seconds
const ERROR = 'HTTP Error: Requested page not reachable'
const ERROR_FROM_SERVER = 'HTTP Error: Requested page not reachable'
/**
* @private
* Small wrapper around js-utility-belt's request that provides url resolving,
@ -87,7 +87,7 @@ export default class Request {
if (!this.connectionError) {
this.retries = 0
this.backoffTime = null
} else if (this.connectionError.message === ERROR) {
} else if (this.connectionError.message === ERROR_FROM_SERVER) {
// If status is not a 2xx (based on Response.ok), throw error
this.retries = 0
this.backoffTime = null

View File

@ -3,7 +3,21 @@
// Code is Apache-2.0 and docs are CC-BY-4.0
import test from 'ava'
import baseRequest from '../../src/baseRequest'
import rewire from 'rewire'
const baseRequestFile = rewire('../../src/baseRequest.js')
const baseRequest = baseRequestFile.__get__('baseRequest')
const handleResponse = baseRequestFile.__get__('handleResponse')
test('HandleResponse does not throw error for response ok', t => {
const testObj = {
ok: true
}
const expected = testObj
const actual = handleResponse(testObj)
t.deepEqual(actual, expected)
})
test('baseRequest test query and vsprint', async t => {
const target = {

View File

@ -0,0 +1,31 @@
// Copyright BigchainDB GmbH and BigchainDB contributors
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0
import test from 'ava'
import Connection from '../../src/connection'
const conn = new Connection()
test('Ensure that BackoffTimedelta works properly', t => {
const req = conn.transport.pickConnection()
req.backoffTime = Date.now() + 50
const target = req.getBackoffTimedelta()
// The value should be close to 50
t.is(target > 45, true)
})
test('Ensure that updateBackoffTime throws and error on TimeoutError', async t => {
const req = conn.transport.pickConnection()
const target = {
message: 'TimeoutError'
}
req.connectionError = target
const error = t.throws(() => {
req.updateBackoffTime()
})
t.deepEqual(target, error)
})