From 0abd9509333415e9f20dc2e7a038c39aaeac9e3d Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Wed, 11 Oct 2023 16:57:58 +0530 Subject: [PATCH 1/2] fix: :bug: error message fix on refresh token error --- lib/core/concurrency-queue.js | 6 +- lib/stack/roles/index.js | 2 - test/unit/concurrency-Queue-test.js | 648 ++++++++++++++-------------- 3 files changed, 337 insertions(+), 319 deletions(-) diff --git a/lib/core/concurrency-queue.js b/lib/core/concurrency-queue.js index 21e3fef3..321383af 100644 --- a/lib/core/concurrency-queue.js +++ b/lib/core/concurrency-queue.js @@ -147,13 +147,13 @@ export function ConcurrencyQueue ({ axios, config }) { axios.httpClientParams.headers.authtoken = token.authtoken this.config.authtoken = token.authtoken } - }).catch(() => { + }).catch((error) => { this.queue.forEach(queueItem => { queueItem.reject({ errorCode: '401', - errorMessage: 'Unable to refresh token', + errorMessage: (error instanceof Error) ? error.message : error, code: 'Unauthorized', - message: 'Request failed with status code 401', + message: 'Unable to refresh token', name: 'Token Error', config: queueItem.request }) diff --git a/lib/stack/roles/index.js b/lib/stack/roles/index.js index 31ff38eb..483440ad 100644 --- a/lib/stack/roles/index.js +++ b/lib/stack/roles/index.js @@ -1,7 +1,5 @@ import cloneDeep from 'lodash/cloneDeep' import { create, update, deleteEntity, fetch, query, fetchAll } from '../../entity' -import ContentstackCollection from '../../contentstackCollection' -import error from '../../core/contentstackError' /** * A role is a collection of permissions that will be applicable to all the users who are assigned this role. Read more about Roles. * @namespace Role diff --git a/test/unit/concurrency-Queue-test.js b/test/unit/concurrency-Queue-test.js index 8d52fa7e..767d248f 100644 --- a/test/unit/concurrency-Queue-test.js +++ b/test/unit/concurrency-Queue-test.js @@ -163,326 +163,346 @@ describe('Concurrency queue test', () => { .catch(done) }) - it('Initialize with bad axios instance', done => { - try { - new ConcurrencyQueue({ axios: undefined }) - expect.fail('Undefined axios should fail') - } catch (error) { - expect(error.message).to.be.equal('Axios instance is not present') - done() - } - }) - - it('Initialization with default config test', done => { - const queue = makeConcurrencyQueue() - expect(queue.config.maxRequests).to.be.equal(5) - expect(queue.config.retryLimit).to.be.equal(5) - expect(queue.config.retryDelay).to.be.equal(300) - expect(queue.queue.length).to.be.equal(0) - expect(queue.running.length).to.be.equal(0) - expect(queue.interceptors.request).to.be.equal(0) - expect(queue.interceptors.response).to.be.equal(0) - done() - }) - - it('Initialization with custom config test', done => { - const queue = makeConcurrencyQueue({ maxRequests: 20, retryLimit: 2, retryDelay: 1000 }) - expect(queue.config.maxRequests).to.be.equal(20) - expect(queue.config.retryLimit).to.be.equal(2) - expect(queue.config.retryDelay).to.be.equal(1000) - expect(queue.queue.length).to.be.equal(0) - expect(queue.running.length).to.be.equal(0) - done() - }) - - it('Detach interceptors test', done => { - const queue = makeConcurrencyQueue({ maxRequests: 20 }) - queue.detach() - expect(queue.config.maxRequests).to.be.equal(20) - expect(queue.config.retryLimit).to.be.equal(5) - expect(queue.config.retryDelay).to.be.equal(300) - expect(queue.interceptors.request).to.be.equal(null) - expect(queue.interceptors.response).to.be.equal(null) - done() - }) - - it('Initialization with custom config negative value test', done => { - try { - makeConcurrencyQueue({ maxRequests: -10 }) - expect.fail('Negative concurrency queue should fail') - } catch (error) { - expect(error.message).to.be.equal('Concurrency Manager Error: minimum concurrent requests is 1') - done() - } - }) - - it('Initialization with custom config retry limit negative value test', done => { - try { - makeConcurrencyQueue({ retryLimit: -10 }) - expect.fail('Negative retry limit should fail') - } catch (error) { - expect(error.message).to.be.equal('Retry Policy Error: minimum retry limit is 1') - done() - } - }) - - it('Initialization with custom config retry delay value test', done => { - try { - makeConcurrencyQueue({ retryDelay: 10 }) - expect.fail('Retry delay should be min 300ms') - } catch (error) { - expect(error.message).to.be.equal('Retry Policy Error: minimum retry delay for requests is 300') - done() - } - }) - - it('Concurrency with 100 passing requests Queue tests', done => { - Promise.all(sequence(100).map(() => api.get('/testReq'))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(objects.length).to.be.equal(100) - done() - }) - .catch(done) - }) - - it('Concurrency with 100 failing requests retry on error false tests', done => { - Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(objects.length).to.be.equal(100) - done() - }) - .catch(done) - }) - - it('Concurrency with 10 timeout requests', done => { - const client = Axios.create({ - baseURL: `${host}:${port}` - }) - const concurrency = new ConcurrencyQueue({ axios: client, config: { retryOnError: true, timeout: 250 } }) - client.get('http://localhost:4444/timeout', { - timeout: 250 - }).then(function (res) { - expect(res).to.be.equal(null) - done() - }).catch(function (err) { - concurrency.detach() - expect(err.response.status).to.be.equal(408) - expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') - done() - }).catch(done) - }) - it('Concurrency with 10 timeout requests retry', done => { - retryDelayOptionsStub.returns(5000) - const client = Axios.create({ - baseURL: `${host}:${port}` - }) - const concurrency = new ConcurrencyQueue({ axios: client, config: { retryCondition: (error) => { - if (error.response.status === 408) { - return true - } - return false - }, - logHandler: logHandlerStub, - retryDelayOptions: { - base: retryDelayOptionsStub() - }, - retryLimit: 2, - retryOnError: true, timeout: 250 } }) - client.get('http://localhost:4444/timeout', { - timeout: 250 - }).then(function (res) { - expect(res).to.be.equal(null) - done() - }).catch(function (err) { - concurrency.detach() - expect(err.response.status).to.be.equal(408) - expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') - done() - }).catch(done) - }) - - it('Concurrency with 100 failing requests retry on error with no retry condition tests', done => { - reconfigureQueue({ retryCondition: (error) => false }) - Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(0) - expect(objects.length).to.be.equal(100) - done() - }) - .catch(done) - }) - - it('Concurrency with 10 failing requests with retry tests', done => { - reconfigureQueue() - Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(50) - expect(objects.length).to.be.equal(10) - done() - }) - .catch(done) - }) - - it('Concurrency with 10 rate limit requests Queue tests', done => { - reconfigureQueue() - Promise.all(sequence(10).map(() => wrapPromise(api.get('/ratelimit')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(50) - expect(objects.length).to.be.equal(10) - done() - }) - .catch(done) - }) - - it('Concurrency with 10 asset upload with rate limit error', done => { - reconfigureQueue() - const fuc = (pathcontent) => { - return () => { - const formData = new FormData() - const uploadStream = createReadStream(path.join(__dirname, '../api/mock/upload.html')) - formData.append('asset[upload]', uploadStream) - return formData - } - } - - Promise.all(sequence(10).map(() => wrapPromise(api.post('/assetUpload', fuc())))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(10) - expect(objects.length).to.be.equal(10) - done() - }) - .catch(done) - }) - - it('Concurrency with 20 request and 1 rate limit request tests', done => { - reconfigureQueue() - Promise.all( - [ - ...wrapPromiseInArray(api.get('/testReq'), 5), - ...wrapPromiseInArray(api.get('/ratelimit'), 1), - ...wrapPromiseInArray(api.get('/testReq'), 15) - ] - ) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(5) - expect(objects.length).to.be.equal(21) - done() - }) - .catch(done) - }) - - it('Concurrency with 20 request and 1 rate limit request tests', done => { - reconfigureQueue({ retryOnError: false }) - Promise.all(sequence(20).map(() => wrapPromise(api.get('/timeout')))) - .then((responses) => { - expect.fail('Should not get response') - }) - .catch(done) - setTimeout(() => { - concurrencyQueue.clear() - expect(concurrencyQueue.queue.length).to.equal(0) - done() - }, 1000) - }) - - it('Concurrency retry on custome backoff test', done => { - reconfigureQueue({ - retryCondition: retryConditionStub, - retryDelayOptions: { - customBackoff: retryDelayOptionsStub - } - }) - - retryConditionStub.returns(true) - retryDelayOptionsStub.onCall(0).returns(200) - retryDelayOptionsStub.onCall(1).returns(300) - retryDelayOptionsStub.onCall(2).returns(-1) - retryDelayOptionsStub.returns(200) - Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(45) - expect(objects.length).to.be.equal(10) - done() - }) - .catch(done) - }) - - it('Concurrency retry delay with base request test', done => { - retryConditionStub.returns(true) - retryDelayOptionsStub.returns(200) - - reconfigureQueue({ - retryCondition: retryConditionStub, - retryDelayOptions: { - base: retryDelayOptionsStub() + it('should give passed error message when refreshToken function fails', done => { + const axios = client({ + baseURL: `${host}:${port}`, + authorization: 'Bearer ', + logHandler: logHandlerStub, + refreshToken: () => { + return new Promise((resolve, reject) => { + reject(new Error('Rejected in Promise')) + }) } }) - - Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - .then((responses) => { - return responses.map(r => r.data) - }) - .then(objects => { - expect(logHandlerStub.callCount).to.be.equal(50) - expect(objects.length).to.be.equal(10) - done() - }) - .catch(done) - }) - - it('Concurrency update authorization to not pass authtoken', done => { - api.get('/fail', { headers: { authorization: 'authorization' } }) - .then((response) => { - expect(response).to.equal(undefined) - done() - }) - .catch((error) => { - expect(error.config.headers.authtoken).to.equal(undefined) - expect(error.config.headers.authorization).to.equal('authorization') + Promise.all(sequence(3).map(() => axios.axiosInstance.get('/unauthorized'))) + .catch(err => { + expect(err.errorCode).to.equal('401') + expect(err.errorMessage).to.equal('Rejected in Promise') + expect(err.message).to.equal('Unable to refresh token') done() }) - .catch(done) }) - it('Request to fail with no response', done => { - reconfigureQueue() - const mock = new MockAdapter(api) - mock.onGet('/netError').networkError() - api.get('/netError') - .then((response) => { - expect(response).to.equal(undefined) - done() - }) - .catch((error) => { - expect(error.esponse).to.equal(undefined) - done() - }) - .catch(done) - }) + // it('Initialize with bad axios instance', done => { + // try { + // new ConcurrencyQueue({ axios: undefined }) + // expect.fail('Undefined axios should fail') + // } catch (error) { + // expect(error.message).to.be.equal('Axios instance is not present') + // done() + // } + // }) + + // it('Initialization with default config test', done => { + // const queue = makeConcurrencyQueue() + // expect(queue.config.maxRequests).to.be.equal(5) + // expect(queue.config.retryLimit).to.be.equal(5) + // expect(queue.config.retryDelay).to.be.equal(300) + // expect(queue.queue.length).to.be.equal(0) + // expect(queue.running.length).to.be.equal(0) + // expect(queue.interceptors.request).to.be.equal(0) + // expect(queue.interceptors.response).to.be.equal(0) + // done() + // }) + + // it('Initialization with custom config test', done => { + // const queue = makeConcurrencyQueue({ maxRequests: 20, retryLimit: 2, retryDelay: 1000 }) + // expect(queue.config.maxRequests).to.be.equal(20) + // expect(queue.config.retryLimit).to.be.equal(2) + // expect(queue.config.retryDelay).to.be.equal(1000) + // expect(queue.queue.length).to.be.equal(0) + // expect(queue.running.length).to.be.equal(0) + // done() + // }) + + // it('Detach interceptors test', done => { + // const queue = makeConcurrencyQueue({ maxRequests: 20 }) + // queue.detach() + // expect(queue.config.maxRequests).to.be.equal(20) + // expect(queue.config.retryLimit).to.be.equal(5) + // expect(queue.config.retryDelay).to.be.equal(300) + // expect(queue.interceptors.request).to.be.equal(null) + // expect(queue.interceptors.response).to.be.equal(null) + // done() + // }) + + // it('Initialization with custom config negative value test', done => { + // try { + // makeConcurrencyQueue({ maxRequests: -10 }) + // expect.fail('Negative concurrency queue should fail') + // } catch (error) { + // expect(error.message).to.be.equal('Concurrency Manager Error: minimum concurrent requests is 1') + // done() + // } + // }) + + // it('Initialization with custom config retry limit negative value test', done => { + // try { + // makeConcurrencyQueue({ retryLimit: -10 }) + // expect.fail('Negative retry limit should fail') + // } catch (error) { + // expect(error.message).to.be.equal('Retry Policy Error: minimum retry limit is 1') + // done() + // } + // }) + + // it('Initialization with custom config retry delay value test', done => { + // try { + // makeConcurrencyQueue({ retryDelay: 10 }) + // expect.fail('Retry delay should be min 300ms') + // } catch (error) { + // expect(error.message).to.be.equal('Retry Policy Error: minimum retry delay for requests is 300') + // done() + // } + // }) + + // it('Concurrency with 100 passing requests Queue tests', done => { + // Promise.all(sequence(100).map(() => api.get('/testReq'))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(objects.length).to.be.equal(100) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 100 failing requests retry on error false tests', done => { + // Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(objects.length).to.be.equal(100) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 10 timeout requests', done => { + // const client = Axios.create({ + // baseURL: `${host}:${port}` + // }) + // const concurrency = new ConcurrencyQueue({ axios: client, config: { retryOnError: true, timeout: 250 } }) + // client.get('http://localhost:4444/timeout', { + // timeout: 250 + // }).then(function (res) { + // expect(res).to.be.equal(null) + // done() + // }).catch(function (err) { + // concurrency.detach() + // expect(err.response.status).to.be.equal(408) + // expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') + // done() + // }).catch(done) + // }) + // it('Concurrency with 10 timeout requests retry', done => { + // retryDelayOptionsStub.returns(5000) + // const client = Axios.create({ + // baseURL: `${host}:${port}` + // }) + // const concurrency = new ConcurrencyQueue({ axios: client, config: { retryCondition: (error) => { + // if (error.response.status === 408) { + // return true + // } + // return false + // }, + // logHandler: logHandlerStub, + // retryDelayOptions: { + // base: retryDelayOptionsStub() + // }, + // retryLimit: 2, + // retryOnError: true, timeout: 250 } }) + // client.get('http://localhost:4444/timeout', { + // timeout: 250 + // }).then(function (res) { + // expect(res).to.be.equal(null) + // done() + // }).catch(function (err) { + // concurrency.detach() + // expect(err.response.status).to.be.equal(408) + // expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') + // done() + // }).catch(done) + // }) + + // it('Concurrency with 100 failing requests retry on error with no retry condition tests', done => { + // reconfigureQueue({ retryCondition: (error) => false }) + // Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(0) + // expect(objects.length).to.be.equal(100) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 10 failing requests with retry tests', done => { + // reconfigureQueue() + // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(50) + // expect(objects.length).to.be.equal(10) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 10 rate limit requests Queue tests', done => { + // reconfigureQueue() + // Promise.all(sequence(10).map(() => wrapPromise(api.get('/ratelimit')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(50) + // expect(objects.length).to.be.equal(10) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 10 asset upload with rate limit error', done => { + // reconfigureQueue() + // const fuc = (pathcontent) => { + // return () => { + // const formData = new FormData() + // const uploadStream = createReadStream(path.join(__dirname, '../api/mock/upload.html')) + // formData.append('asset[upload]', uploadStream) + // return formData + // } + // } + + // Promise.all(sequence(10).map(() => wrapPromise(api.post('/assetUpload', fuc())))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(10) + // expect(objects.length).to.be.equal(10) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 20 request and 1 rate limit request tests', done => { + // reconfigureQueue() + // Promise.all( + // [ + // ...wrapPromiseInArray(api.get('/testReq'), 5), + // ...wrapPromiseInArray(api.get('/ratelimit'), 1), + // ...wrapPromiseInArray(api.get('/testReq'), 15) + // ] + // ) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(5) + // expect(objects.length).to.be.equal(21) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency with 20 request and 1 rate limit request tests', done => { + // reconfigureQueue({ retryOnError: false }) + // Promise.all(sequence(20).map(() => wrapPromise(api.get('/timeout')))) + // .then((responses) => { + // expect.fail('Should not get response') + // }) + // .catch(done) + // setTimeout(() => { + // concurrencyQueue.clear() + // expect(concurrencyQueue.queue.length).to.equal(0) + // done() + // }, 1000) + // }) + + // it('Concurrency retry on custome backoff test', done => { + // reconfigureQueue({ + // retryCondition: retryConditionStub, + // retryDelayOptions: { + // customBackoff: retryDelayOptionsStub + // } + // }) + + // retryConditionStub.returns(true) + // retryDelayOptionsStub.onCall(0).returns(200) + // retryDelayOptionsStub.onCall(1).returns(300) + // retryDelayOptionsStub.onCall(2).returns(-1) + // retryDelayOptionsStub.returns(200) + // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(45) + // expect(objects.length).to.be.equal(10) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency retry delay with base request test', done => { + // retryConditionStub.returns(true) + // retryDelayOptionsStub.returns(200) + + // reconfigureQueue({ + // retryCondition: retryConditionStub, + // retryDelayOptions: { + // base: retryDelayOptionsStub() + // } + // }) + + // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + // .then((responses) => { + // return responses.map(r => r.data) + // }) + // .then(objects => { + // expect(logHandlerStub.callCount).to.be.equal(50) + // expect(objects.length).to.be.equal(10) + // done() + // }) + // .catch(done) + // }) + + // it('Concurrency update authorization to not pass authtoken', done => { + // api.get('/fail', { headers: { authorization: 'authorization' } }) + // .then((response) => { + // expect(response).to.equal(undefined) + // done() + // }) + // .catch((error) => { + // expect(error.config.headers.authtoken).to.equal(undefined) + // expect(error.config.headers.authorization).to.equal('authorization') + // done() + // }) + // .catch(done) + // }) + + // it('Request to fail with no response', done => { + // reconfigureQueue() + // const mock = new MockAdapter(api) + // mock.onGet('/netError').networkError() + // api.get('/netError') + // .then((response) => { + // expect(response).to.equal(undefined) + // done() + // }) + // .catch((error) => { + // expect(error.esponse).to.equal(undefined) + // done() + // }) + // .catch(done) + // }) }) function makeConcurrencyQueue (config) { From ea0468475616139e55551afc0c766853702548cc Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Wed, 11 Oct 2023 17:36:55 +0530 Subject: [PATCH 2/2] refactor: uncommented unit test cases --- test/unit/concurrency-Queue-test.js | 640 ++++++++++++++-------------- 1 file changed, 320 insertions(+), 320 deletions(-) diff --git a/test/unit/concurrency-Queue-test.js b/test/unit/concurrency-Queue-test.js index 767d248f..04a6fb58 100644 --- a/test/unit/concurrency-Queue-test.js +++ b/test/unit/concurrency-Queue-test.js @@ -183,326 +183,326 @@ describe('Concurrency queue test', () => { }) }) - // it('Initialize with bad axios instance', done => { - // try { - // new ConcurrencyQueue({ axios: undefined }) - // expect.fail('Undefined axios should fail') - // } catch (error) { - // expect(error.message).to.be.equal('Axios instance is not present') - // done() - // } - // }) - - // it('Initialization with default config test', done => { - // const queue = makeConcurrencyQueue() - // expect(queue.config.maxRequests).to.be.equal(5) - // expect(queue.config.retryLimit).to.be.equal(5) - // expect(queue.config.retryDelay).to.be.equal(300) - // expect(queue.queue.length).to.be.equal(0) - // expect(queue.running.length).to.be.equal(0) - // expect(queue.interceptors.request).to.be.equal(0) - // expect(queue.interceptors.response).to.be.equal(0) - // done() - // }) - - // it('Initialization with custom config test', done => { - // const queue = makeConcurrencyQueue({ maxRequests: 20, retryLimit: 2, retryDelay: 1000 }) - // expect(queue.config.maxRequests).to.be.equal(20) - // expect(queue.config.retryLimit).to.be.equal(2) - // expect(queue.config.retryDelay).to.be.equal(1000) - // expect(queue.queue.length).to.be.equal(0) - // expect(queue.running.length).to.be.equal(0) - // done() - // }) - - // it('Detach interceptors test', done => { - // const queue = makeConcurrencyQueue({ maxRequests: 20 }) - // queue.detach() - // expect(queue.config.maxRequests).to.be.equal(20) - // expect(queue.config.retryLimit).to.be.equal(5) - // expect(queue.config.retryDelay).to.be.equal(300) - // expect(queue.interceptors.request).to.be.equal(null) - // expect(queue.interceptors.response).to.be.equal(null) - // done() - // }) - - // it('Initialization with custom config negative value test', done => { - // try { - // makeConcurrencyQueue({ maxRequests: -10 }) - // expect.fail('Negative concurrency queue should fail') - // } catch (error) { - // expect(error.message).to.be.equal('Concurrency Manager Error: minimum concurrent requests is 1') - // done() - // } - // }) - - // it('Initialization with custom config retry limit negative value test', done => { - // try { - // makeConcurrencyQueue({ retryLimit: -10 }) - // expect.fail('Negative retry limit should fail') - // } catch (error) { - // expect(error.message).to.be.equal('Retry Policy Error: minimum retry limit is 1') - // done() - // } - // }) - - // it('Initialization with custom config retry delay value test', done => { - // try { - // makeConcurrencyQueue({ retryDelay: 10 }) - // expect.fail('Retry delay should be min 300ms') - // } catch (error) { - // expect(error.message).to.be.equal('Retry Policy Error: minimum retry delay for requests is 300') - // done() - // } - // }) - - // it('Concurrency with 100 passing requests Queue tests', done => { - // Promise.all(sequence(100).map(() => api.get('/testReq'))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(objects.length).to.be.equal(100) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 100 failing requests retry on error false tests', done => { - // Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(objects.length).to.be.equal(100) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 10 timeout requests', done => { - // const client = Axios.create({ - // baseURL: `${host}:${port}` - // }) - // const concurrency = new ConcurrencyQueue({ axios: client, config: { retryOnError: true, timeout: 250 } }) - // client.get('http://localhost:4444/timeout', { - // timeout: 250 - // }).then(function (res) { - // expect(res).to.be.equal(null) - // done() - // }).catch(function (err) { - // concurrency.detach() - // expect(err.response.status).to.be.equal(408) - // expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') - // done() - // }).catch(done) - // }) - // it('Concurrency with 10 timeout requests retry', done => { - // retryDelayOptionsStub.returns(5000) - // const client = Axios.create({ - // baseURL: `${host}:${port}` - // }) - // const concurrency = new ConcurrencyQueue({ axios: client, config: { retryCondition: (error) => { - // if (error.response.status === 408) { - // return true - // } - // return false - // }, - // logHandler: logHandlerStub, - // retryDelayOptions: { - // base: retryDelayOptionsStub() - // }, - // retryLimit: 2, - // retryOnError: true, timeout: 250 } }) - // client.get('http://localhost:4444/timeout', { - // timeout: 250 - // }).then(function (res) { - // expect(res).to.be.equal(null) - // done() - // }).catch(function (err) { - // concurrency.detach() - // expect(err.response.status).to.be.equal(408) - // expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') - // done() - // }).catch(done) - // }) - - // it('Concurrency with 100 failing requests retry on error with no retry condition tests', done => { - // reconfigureQueue({ retryCondition: (error) => false }) - // Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(0) - // expect(objects.length).to.be.equal(100) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 10 failing requests with retry tests', done => { - // reconfigureQueue() - // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(50) - // expect(objects.length).to.be.equal(10) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 10 rate limit requests Queue tests', done => { - // reconfigureQueue() - // Promise.all(sequence(10).map(() => wrapPromise(api.get('/ratelimit')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(50) - // expect(objects.length).to.be.equal(10) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 10 asset upload with rate limit error', done => { - // reconfigureQueue() - // const fuc = (pathcontent) => { - // return () => { - // const formData = new FormData() - // const uploadStream = createReadStream(path.join(__dirname, '../api/mock/upload.html')) - // formData.append('asset[upload]', uploadStream) - // return formData - // } - // } - - // Promise.all(sequence(10).map(() => wrapPromise(api.post('/assetUpload', fuc())))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(10) - // expect(objects.length).to.be.equal(10) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 20 request and 1 rate limit request tests', done => { - // reconfigureQueue() - // Promise.all( - // [ - // ...wrapPromiseInArray(api.get('/testReq'), 5), - // ...wrapPromiseInArray(api.get('/ratelimit'), 1), - // ...wrapPromiseInArray(api.get('/testReq'), 15) - // ] - // ) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(5) - // expect(objects.length).to.be.equal(21) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency with 20 request and 1 rate limit request tests', done => { - // reconfigureQueue({ retryOnError: false }) - // Promise.all(sequence(20).map(() => wrapPromise(api.get('/timeout')))) - // .then((responses) => { - // expect.fail('Should not get response') - // }) - // .catch(done) - // setTimeout(() => { - // concurrencyQueue.clear() - // expect(concurrencyQueue.queue.length).to.equal(0) - // done() - // }, 1000) - // }) - - // it('Concurrency retry on custome backoff test', done => { - // reconfigureQueue({ - // retryCondition: retryConditionStub, - // retryDelayOptions: { - // customBackoff: retryDelayOptionsStub - // } - // }) - - // retryConditionStub.returns(true) - // retryDelayOptionsStub.onCall(0).returns(200) - // retryDelayOptionsStub.onCall(1).returns(300) - // retryDelayOptionsStub.onCall(2).returns(-1) - // retryDelayOptionsStub.returns(200) - // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(45) - // expect(objects.length).to.be.equal(10) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency retry delay with base request test', done => { - // retryConditionStub.returns(true) - // retryDelayOptionsStub.returns(200) - - // reconfigureQueue({ - // retryCondition: retryConditionStub, - // retryDelayOptions: { - // base: retryDelayOptionsStub() - // } - // }) - - // Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) - // .then((responses) => { - // return responses.map(r => r.data) - // }) - // .then(objects => { - // expect(logHandlerStub.callCount).to.be.equal(50) - // expect(objects.length).to.be.equal(10) - // done() - // }) - // .catch(done) - // }) - - // it('Concurrency update authorization to not pass authtoken', done => { - // api.get('/fail', { headers: { authorization: 'authorization' } }) - // .then((response) => { - // expect(response).to.equal(undefined) - // done() - // }) - // .catch((error) => { - // expect(error.config.headers.authtoken).to.equal(undefined) - // expect(error.config.headers.authorization).to.equal('authorization') - // done() - // }) - // .catch(done) - // }) - - // it('Request to fail with no response', done => { - // reconfigureQueue() - // const mock = new MockAdapter(api) - // mock.onGet('/netError').networkError() - // api.get('/netError') - // .then((response) => { - // expect(response).to.equal(undefined) - // done() - // }) - // .catch((error) => { - // expect(error.esponse).to.equal(undefined) - // done() - // }) - // .catch(done) - // }) + it('Initialize with bad axios instance', done => { + try { + new ConcurrencyQueue({ axios: undefined }) + expect.fail('Undefined axios should fail') + } catch (error) { + expect(error.message).to.be.equal('Axios instance is not present') + done() + } + }) + + it('Initialization with default config test', done => { + const queue = makeConcurrencyQueue() + expect(queue.config.maxRequests).to.be.equal(5) + expect(queue.config.retryLimit).to.be.equal(5) + expect(queue.config.retryDelay).to.be.equal(300) + expect(queue.queue.length).to.be.equal(0) + expect(queue.running.length).to.be.equal(0) + expect(queue.interceptors.request).to.be.equal(0) + expect(queue.interceptors.response).to.be.equal(0) + done() + }) + + it('Initialization with custom config test', done => { + const queue = makeConcurrencyQueue({ maxRequests: 20, retryLimit: 2, retryDelay: 1000 }) + expect(queue.config.maxRequests).to.be.equal(20) + expect(queue.config.retryLimit).to.be.equal(2) + expect(queue.config.retryDelay).to.be.equal(1000) + expect(queue.queue.length).to.be.equal(0) + expect(queue.running.length).to.be.equal(0) + done() + }) + + it('Detach interceptors test', done => { + const queue = makeConcurrencyQueue({ maxRequests: 20 }) + queue.detach() + expect(queue.config.maxRequests).to.be.equal(20) + expect(queue.config.retryLimit).to.be.equal(5) + expect(queue.config.retryDelay).to.be.equal(300) + expect(queue.interceptors.request).to.be.equal(null) + expect(queue.interceptors.response).to.be.equal(null) + done() + }) + + it('Initialization with custom config negative value test', done => { + try { + makeConcurrencyQueue({ maxRequests: -10 }) + expect.fail('Negative concurrency queue should fail') + } catch (error) { + expect(error.message).to.be.equal('Concurrency Manager Error: minimum concurrent requests is 1') + done() + } + }) + + it('Initialization with custom config retry limit negative value test', done => { + try { + makeConcurrencyQueue({ retryLimit: -10 }) + expect.fail('Negative retry limit should fail') + } catch (error) { + expect(error.message).to.be.equal('Retry Policy Error: minimum retry limit is 1') + done() + } + }) + + it('Initialization with custom config retry delay value test', done => { + try { + makeConcurrencyQueue({ retryDelay: 10 }) + expect.fail('Retry delay should be min 300ms') + } catch (error) { + expect(error.message).to.be.equal('Retry Policy Error: minimum retry delay for requests is 300') + done() + } + }) + + it('Concurrency with 100 passing requests Queue tests', done => { + Promise.all(sequence(100).map(() => api.get('/testReq'))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(objects.length).to.be.equal(100) + done() + }) + .catch(done) + }) + + it('Concurrency with 100 failing requests retry on error false tests', done => { + Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(objects.length).to.be.equal(100) + done() + }) + .catch(done) + }) + + it('Concurrency with 10 timeout requests', done => { + const client = Axios.create({ + baseURL: `${host}:${port}` + }) + const concurrency = new ConcurrencyQueue({ axios: client, config: { retryOnError: true, timeout: 250 } }) + client.get('http://localhost:4444/timeout', { + timeout: 250 + }).then(function (res) { + expect(res).to.be.equal(null) + done() + }).catch(function (err) { + concurrency.detach() + expect(err.response.status).to.be.equal(408) + expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') + done() + }).catch(done) + }) + it('Concurrency with 10 timeout requests retry', done => { + retryDelayOptionsStub.returns(5000) + const client = Axios.create({ + baseURL: `${host}:${port}` + }) + const concurrency = new ConcurrencyQueue({ axios: client, config: { retryCondition: (error) => { + if (error.response.status === 408) { + return true + } + return false + }, + logHandler: logHandlerStub, + retryDelayOptions: { + base: retryDelayOptionsStub() + }, + retryLimit: 2, + retryOnError: true, timeout: 250 } }) + client.get('http://localhost:4444/timeout', { + timeout: 250 + }).then(function (res) { + expect(res).to.be.equal(null) + done() + }).catch(function (err) { + concurrency.detach() + expect(err.response.status).to.be.equal(408) + expect(err.response.statusText).to.be.equal('timeout of 250ms exceeded') + done() + }).catch(done) + }) + + it('Concurrency with 100 failing requests retry on error with no retry condition tests', done => { + reconfigureQueue({ retryCondition: (error) => false }) + Promise.all(sequence(100).map(() => wrapPromise(api.get('/fail')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(0) + expect(objects.length).to.be.equal(100) + done() + }) + .catch(done) + }) + + it('Concurrency with 10 failing requests with retry tests', done => { + reconfigureQueue() + Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(50) + expect(objects.length).to.be.equal(10) + done() + }) + .catch(done) + }) + + it('Concurrency with 10 rate limit requests Queue tests', done => { + reconfigureQueue() + Promise.all(sequence(10).map(() => wrapPromise(api.get('/ratelimit')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(50) + expect(objects.length).to.be.equal(10) + done() + }) + .catch(done) + }) + + it('Concurrency with 10 asset upload with rate limit error', done => { + reconfigureQueue() + const fuc = (pathcontent) => { + return () => { + const formData = new FormData() + const uploadStream = createReadStream(path.join(__dirname, '../api/mock/upload.html')) + formData.append('asset[upload]', uploadStream) + return formData + } + } + + Promise.all(sequence(10).map(() => wrapPromise(api.post('/assetUpload', fuc())))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(10) + expect(objects.length).to.be.equal(10) + done() + }) + .catch(done) + }) + + it('Concurrency with 20 request and 1 rate limit request tests', done => { + reconfigureQueue() + Promise.all( + [ + ...wrapPromiseInArray(api.get('/testReq'), 5), + ...wrapPromiseInArray(api.get('/ratelimit'), 1), + ...wrapPromiseInArray(api.get('/testReq'), 15) + ] + ) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(5) + expect(objects.length).to.be.equal(21) + done() + }) + .catch(done) + }) + + it('Concurrency with 20 request and 1 rate limit request tests', done => { + reconfigureQueue({ retryOnError: false }) + Promise.all(sequence(20).map(() => wrapPromise(api.get('/timeout')))) + .then((responses) => { + expect.fail('Should not get response') + }) + .catch(done) + setTimeout(() => { + concurrencyQueue.clear() + expect(concurrencyQueue.queue.length).to.equal(0) + done() + }, 1000) + }) + + it('Concurrency retry on custome backoff test', done => { + reconfigureQueue({ + retryCondition: retryConditionStub, + retryDelayOptions: { + customBackoff: retryDelayOptionsStub + } + }) + + retryConditionStub.returns(true) + retryDelayOptionsStub.onCall(0).returns(200) + retryDelayOptionsStub.onCall(1).returns(300) + retryDelayOptionsStub.onCall(2).returns(-1) + retryDelayOptionsStub.returns(200) + Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(45) + expect(objects.length).to.be.equal(10) + done() + }) + .catch(done) + }) + + it('Concurrency retry delay with base request test', done => { + retryConditionStub.returns(true) + retryDelayOptionsStub.returns(200) + + reconfigureQueue({ + retryCondition: retryConditionStub, + retryDelayOptions: { + base: retryDelayOptionsStub() + } + }) + + Promise.all(sequence(10).map(() => wrapPromise(api.get('/fail')))) + .then((responses) => { + return responses.map(r => r.data) + }) + .then(objects => { + expect(logHandlerStub.callCount).to.be.equal(50) + expect(objects.length).to.be.equal(10) + done() + }) + .catch(done) + }) + + it('Concurrency update authorization to not pass authtoken', done => { + api.get('/fail', { headers: { authorization: 'authorization' } }) + .then((response) => { + expect(response).to.equal(undefined) + done() + }) + .catch((error) => { + expect(error.config.headers.authtoken).to.equal(undefined) + expect(error.config.headers.authorization).to.equal('authorization') + done() + }) + .catch(done) + }) + + it('Request to fail with no response', done => { + reconfigureQueue() + const mock = new MockAdapter(api) + mock.onGet('/netError').networkError() + api.get('/netError') + .then((response) => { + expect(response).to.equal(undefined) + done() + }) + .catch((error) => { + expect(error.esponse).to.equal(undefined) + done() + }) + .catch(done) + }) }) function makeConcurrencyQueue (config) {