/spec/javascripts/lib/utils/poll_spec.js
JavaScript | 190 lines | 151 code | 38 blank | 1 comment | 4 complexity | fa1475ba9b257e8bb50d7f38e8049237 MD5 | raw file
- /* eslint-disable jasmine/no-unsafe-spy */
- import Poll from '~/lib/utils/poll';
- import { successCodes } from '~/lib/utils/http_status';
- const waitForAllCallsToFinish = (service, waitForCount, successCallback) => {
- const timer = () => {
- setTimeout(() => {
- if (service.fetch.calls.count() === waitForCount) {
- successCallback();
- } else {
- timer();
- }
- }, 0);
- };
- timer();
- };
- function mockServiceCall(service, response, shouldFail = false) {
- const action = shouldFail ? Promise.reject : Promise.resolve;
- const responseObject = response;
- if (!responseObject.headers) responseObject.headers = {};
- service.fetch.and.callFake(action.bind(Promise, responseObject));
- }
- describe('Poll', () => {
- const service = jasmine.createSpyObj('service', ['fetch']);
- const callbacks = jasmine.createSpyObj('callbacks', ['success', 'error', 'notification']);
- function setup() {
- return new Poll({
- resource: service,
- method: 'fetch',
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- notificationCallback: callbacks.notification,
- }).makeRequest();
- }
- afterEach(() => {
- callbacks.success.calls.reset();
- callbacks.error.calls.reset();
- callbacks.notification.calls.reset();
- service.fetch.calls.reset();
- });
- it('calls the success callback when no header for interval is provided', done => {
- mockServiceCall(service, { status: 200 });
- setup();
- waitForAllCallsToFinish(service, 1, () => {
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
- done();
- });
- });
- it('calls the error callback when the http request returns an error', done => {
- mockServiceCall(service, { status: 500 }, true);
- setup();
- waitForAllCallsToFinish(service, 1, () => {
- expect(callbacks.success).not.toHaveBeenCalled();
- expect(callbacks.error).toHaveBeenCalled();
- done();
- });
- });
- it('skips the error callback when request is aborted', done => {
- mockServiceCall(service, { status: 0 }, true);
- setup();
- waitForAllCallsToFinish(service, 1, () => {
- expect(callbacks.success).not.toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
- expect(callbacks.notification).toHaveBeenCalled();
- done();
- });
- });
- it('should call the success callback when the interval header is -1', done => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': -1 } });
- setup()
- .then(() => {
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
- describe('for 2xx status code', () => {
- successCodes.forEach(httpCode => {
- it(`starts polling when http status is ${httpCode} and interval header is provided`, done => {
- mockServiceCall(service, { status: httpCode, headers: { 'poll-interval': 1 } });
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: callbacks.success,
- errorCallback: callbacks.error,
- });
- Polling.makeRequest();
- waitForAllCallsToFinish(service, 2, () => {
- Polling.stop();
- expect(service.fetch.calls.count()).toEqual(2);
- expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
- done();
- });
- });
- });
- });
- describe('stop', () => {
- it('stops polling when method is called', done => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: () => {
- Polling.stop();
- },
- errorCallback: callbacks.error,
- });
- spyOn(Polling, 'stop').and.callThrough();
- Polling.makeRequest();
- waitForAllCallsToFinish(service, 1, () => {
- expect(service.fetch.calls.count()).toEqual(1);
- expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
- expect(Polling.stop).toHaveBeenCalled();
- done();
- });
- });
- });
- describe('restart', () => {
- it('should restart polling when its called', done => {
- mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
- const Polling = new Poll({
- resource: service,
- method: 'fetch',
- data: { page: 1 },
- successCallback: () => {
- Polling.stop();
- setTimeout(() => {
- Polling.restart({ data: { page: 4 } });
- }, 0);
- },
- errorCallback: callbacks.error,
- });
- spyOn(Polling, 'stop').and.callThrough();
- spyOn(Polling, 'restart').and.callThrough();
- Polling.makeRequest();
- waitForAllCallsToFinish(service, 2, () => {
- Polling.stop();
- expect(service.fetch.calls.count()).toEqual(2);
- expect(service.fetch).toHaveBeenCalledWith({ page: 4 });
- expect(Polling.stop).toHaveBeenCalled();
- expect(Polling.restart).toHaveBeenCalled();
- expect(Polling.options.data).toEqual({ page: 4 });
- done();
- });
- });
- });
- });