diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2017-03-28 17:08:15 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2017-03-28 17:08:15 +0000 |
commit | 15ca592ffbf5d36d9736dc2f42f3c2f85bf2f457 (patch) | |
tree | 59ae21d47479d6074fa329f8616e04491cc09b09 | |
parent | 387f2c43d31fe940da3b953c6e2b55b2e830d9f2 (diff) | |
parent | 81ed06cb33b7d54285285a2ce77bac7080ff7bd8 (diff) | |
download | gitlab-ce-15ca592ffbf5d36d9736dc2f42f3c2f85bf2f457.tar.gz |
Merge branch '5983-poll-changes' into 'master'
Adds restart method and auxiliar callback to polling class
See merge request !10223
-rw-r--r-- | app/assets/javascripts/lib/utils/poll.js | 55 | ||||
-rw-r--r-- | spec/javascripts/lib/utils/poll_spec.js | 40 |
2 files changed, 81 insertions, 14 deletions
diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js index c30a1fcb5da..5c22aea51cd 100644 --- a/app/assets/javascripts/lib/utils/poll.js +++ b/app/assets/javascripts/lib/utils/poll.js @@ -5,23 +5,37 @@ import httpStatusCodes from './http_status'; * Service for vue resouce and method need to be provided as props * * @example - * new poll({ + * new Poll({ * resource: resource, * method: 'name', - * data: {page: 1, scope: 'all'}, + * data: {page: 1, scope: 'all'}, // optional * successCallback: () => {}, * errorCallback: () => {}, + * notificationCallback: () => {}, // optional * }).makeRequest(); * - * this.service = new BoardsService(endpoint); - * new poll({ - * resource: this.service, - * method: 'get', - * data: {page: 1, scope: 'all'}, - * successCallback: () => {}, - * errorCallback: () => {}, - * }).makeRequest(); + * Usage in pipelines table with visibility lib: * + * const poll = new Poll({ + * resource: this.service, + * method: 'getPipelines', + * data: { page: pageNumber, scope }, + * successCallback: this.successCallback, + * errorCallback: this.errorCallback, + * notificationCallback: this.updateLoading, + * }); + * + * if (!Visibility.hidden()) { + * poll.makeRequest(); + * } + * + * Visibility.change(() => { + * if (!Visibility.hidden()) { + * poll.restart(); + * } else { + * poll.stop(); + * } +* }); * * 1. Checks for response and headers before start polling * 2. Interval is provided by `Poll-Interval` header. @@ -34,6 +48,8 @@ export default class Poll { constructor(options = {}) { this.options = options; this.options.data = options.data || {}; + this.options.notificationCallback = options.notificationCallback || + function notificationCallback() {}; this.intervalHeader = 'POLL-INTERVAL'; this.timeoutID = null; @@ -42,7 +58,7 @@ export default class Poll { checkConditions(response) { const headers = gl.utils.normalizeHeaders(response.headers); - const pollInterval = headers[this.intervalHeader]; + const pollInterval = parseInt(headers[this.intervalHeader], 10); if (pollInterval > 0 && response.status === httpStatusCodes.OK && this.canPoll) { this.timeoutID = setTimeout(() => { @@ -54,11 +70,14 @@ export default class Poll { } makeRequest() { - const { resource, method, data, errorCallback } = this.options; + const { resource, method, data, errorCallback, notificationCallback } = this.options; + + // It's called everytime a new request is made. Useful to update the status. + notificationCallback(true); return resource[method](data) - .then(response => this.checkConditions(response)) - .catch(error => errorCallback(error)); + .then(response => this.checkConditions(response)) + .catch(error => errorCallback(error)); } /** @@ -70,4 +89,12 @@ export default class Poll { this.canPoll = false; clearTimeout(this.timeoutID); } + + /** + * Restarts polling after it has been stoped + */ + restart() { + this.canPoll = true; + this.makeRequest(); + } } diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js index c794a632417..e3429c2a1cb 100644 --- a/spec/javascripts/lib/utils/poll_spec.js +++ b/spec/javascripts/lib/utils/poll_spec.js @@ -160,4 +160,44 @@ describe('Poll', () => { Vue.http.interceptors = _.without(Vue.http.interceptors, pollInterceptor); }); }); + + describe('restart', () => { + it('should restart polling when its called', (done) => { + const pollInterceptor = (request, next) => { + next(request.respondWith(JSON.stringify([]), { status: 200, headers: { 'poll-interval': 2 } })); + }; + + Vue.http.interceptors.push(pollInterceptor); + + const service = new ServiceMock('endpoint'); + + spyOn(service, 'fetch').and.callThrough(); + + const Polling = new Poll({ + resource: service, + method: 'fetch', + data: { page: 1 }, + successCallback: () => { + Polling.stop(); + setTimeout(() => { + Polling.restart(); + }, 0); + }, + errorCallback: callbacks.error, + }); + + spyOn(Polling, 'stop').and.callThrough(); + + Polling.makeRequest(); + + setTimeout(() => { + expect(service.fetch.calls.count()).toEqual(2); + expect(service.fetch).toHaveBeenCalledWith({ page: 1 }); + expect(Polling.stop).toHaveBeenCalled(); + done(); + }, 10); + + Vue.http.interceptors = _.without(Vue.http.interceptors, pollInterceptor); + }); + }); }); |