From 04c1474375d5d0c9ad387c23a453951b83d94425 Mon Sep 17 00:00:00 2001 From: Christie Baker Date: Wed, 11 Apr 2018 11:02:07 -0500 Subject: [PATCH] feat(api-core): refactor polling for extending MS --- packages/api-core/src/api.js | 64 ++++++++++++++----------- packages/api-core/src/ms.js | 25 +++++----- packages/api-core/src/options.js | 4 ++ packages/api-core/src/tests/api.test.js | 18 ++++--- 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/packages/api-core/src/api.js b/packages/api-core/src/api.js index e44c33b71..e3a67f692 100644 --- a/packages/api-core/src/api.js +++ b/packages/api-core/src/api.js @@ -118,41 +118,54 @@ export default class AvApi { getLocation(response) { let location = false; - const toPoll = - response.config.polling && - response.status === 202 && - response.config.attempt < response.config.pollingIntervals.length; - - if (toPoll) { - if (response.config.getHeader) { - location = response.config.getHeader(response, 'Location'); - } else { - location = response.headers.Location; - } + if (response.config.getHeader) { + location = response.config.getHeader(response, 'Location'); + } else { + location = response.headers.Location; } + return location; } + // condition for calls that should continue polling + shouldPoll(response) { + return ( + response.config.polling && + response.status === 202 && + response.config.attempt < response.config.pollingIntervals.length + ); + } + // handle response with possible polling onResponse(response, afterResponse) { - const location = this.getLocation(response); - - if (location) { + if (this.shouldPoll(response)) { const newConfig = this.config(response.config); - newConfig.method = 'GET'; - newConfig.url = location; - newConfig.cache = false; - return new this.Promise(resolve => { - setTimeout( - resolve, - newConfig.pollingIntervals[newConfig.attempt] || 1000 - ); - }).then(() => this.request(newConfig, afterResponse)); + const pollingUrl = this.getLocation(response); + + if (pollingUrl) { + newConfig.method = this.defaultConfig.pollingMethod; + newConfig.url = pollingUrl; + newConfig.cache = false; + return new this.Promise(resolve => { + setTimeout( + resolve, + newConfig.pollingIntervals[newConfig.attempt] || 1000 + ); + }).then(() => this.request(newConfig, afterResponse)); + } } return afterResponse ? afterResponse(response) : response; } + getError(error) { + let response; + if (error.response) { + response = { error }; + } + return response; + } + // make request to http request(config, afterResponse) { if (config.polling) { @@ -163,10 +176,7 @@ export default class AvApi { return this.http(config) .then(response => this.onResponse(response, afterResponse)) .catch(error => { - let response; - if (error.response) { - response = { error }; - } + const response = this.getError(error); return afterResponse ? afterResponse(response) : response; }); } diff --git a/packages/api-core/src/ms.js b/packages/api-core/src/ms.js index 1922289aa..7a7cf9b49 100644 --- a/packages/api-core/src/ms.js +++ b/packages/api-core/src/ms.js @@ -12,6 +12,7 @@ export default class AvMicroservice extends AvApi { this.defaultConfig = this.merge({}, API_OPTIONS.MS, config); } + // override aries 1 url concatentation getUrl(config) { const { path, name, id } = this.config(config); let parts = [path, name]; @@ -24,17 +25,17 @@ export default class AvMicroservice extends AvApi { .replace(/\/$/, ''); } - // make request to http - request(config, afterResponse) { - return this.http(config) - .then(response => this.onResponse(response, afterResponse)) - .catch(error => { - let response; - if (error) { - response = error; - response.error = true; - } - return afterResponse ? afterResponse(response) : response; - }); + getError(error) { + let response; + if (error) { + response = error; + response.error = true; + } + return response; + } + + // polling location is the same url + getLocation(response) { + return this.getUrl(response.config); } } diff --git a/packages/api-core/src/options.js b/packages/api-core/src/options.js index f11bf387c..cae74e50d 100644 --- a/packages/api-core/src/options.js +++ b/packages/api-core/src/options.js @@ -22,6 +22,8 @@ const API_OPTIONS = { pollingIntervals: [1e3, 2e3, 5e3, 1e4], // in ms + pollingMethod: 'GET', + // default headers headers: { // Turn off content encoding for angular apis @@ -53,6 +55,8 @@ const API_OPTIONS = { pollingIntervals: [1e3, 2e3, 5e3, 1e4], // in ms + pollingMethod: 'POST', + // default headers headers: { // Turn off content encoding for angular apis diff --git a/packages/api-core/src/tests/api.test.js b/packages/api-core/src/tests/api.test.js index cce20c6b3..6526b238a 100644 --- a/packages/api-core/src/tests/api.test.js +++ b/packages/api-core/src/tests/api.test.js @@ -440,7 +440,7 @@ describe('AvApi', () => { polling: false, }, }; - expect(api.getLocation(testResponse)).toBeFalsy(); + expect(api.shouldPoll(testResponse)).toBeFalsy(); }); test('should return false when status is not 202', () => { @@ -450,7 +450,7 @@ describe('AvApi', () => { }, status: 200, }; - expect(api.getLocation(testResponse)).toBeFalsy(); + expect(api.shouldPoll(testResponse)).toBeFalsy(); }); test('should return false when attempt is larger than polling intervals', () => { @@ -462,7 +462,7 @@ describe('AvApi', () => { }, status: 202, }; - expect(api.getLocation(testResponse)).toBeFalsy(); + expect(api.shouldPoll(testResponse)).toBeFalsy(); }); test('should call config.getHeader() when polling is available', () => { @@ -523,6 +523,7 @@ describe('AvApi', () => { merge: mockMerge, config: {}, }); + api.shouldPoll = jest.fn(); api.getLocation = jest.fn(() => testLocation); api.request = jest.fn(); api.config = jest.fn(() => testNewConfig); @@ -554,20 +555,25 @@ describe('AvApi', () => { }); test('should request when polling', () => { - const mockAfterResponse = 'after'; + api.shouldPoll = jest.fn(() => true); + api.getLocation = jest.fn(() => testLocation); + + const mockAfterResponse = { testKey: 'after' }; + const afterResponse = jest.fn(() => mockAfterResponse); + const mockConfig = { testVal: 'test', }; const output = api - .onResponse({ config: mockConfig }, mockAfterResponse) + .onResponse({ config: mockConfig }, afterResponse) .then(() => { expect(api.config).toHaveBeenCalledWith(mockConfig); expect(setTimeout).toHaveBeenCalledTimes(1); expect(setTimeout.mock.calls[0][1]).toBe(testInterval); expect(api.request).toHaveBeenCalledWith( expectedNewConfig, - mockAfterResponse + afterResponse ); return true; });