Skip to content

Commit

Permalink
feat(api-core): refactor polling for extending MS
Browse files Browse the repository at this point in the history
  • Loading branch information
Christie Baker authored and Christie Baker committed Apr 11, 2018
1 parent b5d81e2 commit 04c1474
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 45 deletions.
64 changes: 37 additions & 27 deletions packages/api-core/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
});
}
Expand Down
25 changes: 13 additions & 12 deletions packages/api-core/src/ms.js
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);
}
}
4 changes: 4 additions & 0 deletions packages/api-core/src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 12 additions & 6 deletions packages/api-core/src/tests/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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', () => {
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
});
Expand Down

0 comments on commit 04c1474

Please sign in to comment.