debian-mirror-gitlab/spec/javascripts/lib/utils/poll_spec.js

223 lines
6.1 KiB
JavaScript
Raw Normal View History

2018-12-05 23:21:45 +05:30
/* eslint-disable jasmine/no-unsafe-spy */
2017-08-17 22:00:37 +05:30
import Poll from '~/lib/utils/poll';
2018-11-18 11:00:15 +05:30
import { successCodes } from '~/lib/utils/http_status';
2017-08-17 22:00:37 +05:30
const waitForAllCallsToFinish = (service, waitForCount, successCallback) => {
const timer = () => {
setTimeout(() => {
if (service.fetch.calls.count() === waitForCount) {
successCallback();
} else {
timer();
}
2017-09-10 17:25:29 +05:30
}, 0);
2017-08-17 22:00:37 +05:30
};
timer();
};
2017-09-10 17:25:29 +05:30
function mockServiceCall(service, response, shouldFail = false) {
const action = shouldFail ? Promise.reject : Promise.resolve;
const responseObject = response;
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
if (!responseObject.headers) responseObject.headers = {};
service.fetch.and.callFake(action.bind(Promise, responseObject));
2017-08-17 22:00:37 +05:30
}
describe('Poll', () => {
2017-09-10 17:25:29 +05:30
const service = jasmine.createSpyObj('service', ['fetch']);
const callbacks = jasmine.createSpyObj('callbacks', ['success', 'error', 'notification']);
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
function setup() {
return new Poll({
2017-08-17 22:00:37 +05:30
resource: service,
method: 'fetch',
successCallback: callbacks.success,
errorCallback: callbacks.error,
2017-09-10 17:25:29 +05:30
notificationCallback: callbacks.notification,
2017-08-17 22:00:37 +05:30
}).makeRequest();
2017-09-10 17:25:29 +05:30
}
afterEach(() => {
callbacks.success.calls.reset();
callbacks.error.calls.reset();
callbacks.notification.calls.reset();
service.fetch.calls.reset();
});
2018-12-13 13:39:08 +05:30
it('calls the success callback when no header for interval is provided', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 200 });
setup();
2017-08-17 22:00:37 +05:30
waitForAllCallsToFinish(service, 1, () => {
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
done();
2017-09-10 17:25:29 +05:30
});
2017-08-17 22:00:37 +05:30
});
2018-12-13 13:39:08 +05:30
it('calls the error callback when the http request returns an error', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 500 }, true);
setup();
2017-08-17 22:00:37 +05:30
waitForAllCallsToFinish(service, 1, () => {
expect(callbacks.success).not.toHaveBeenCalled();
expect(callbacks.error).toHaveBeenCalled();
done();
});
});
2018-12-13 13:39:08 +05:30
it('skips the error callback when request is aborted', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 0 }, true);
setup();
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
waitForAllCallsToFinish(service, 1, () => {
expect(callbacks.success).not.toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
expect(callbacks.notification).toHaveBeenCalled();
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
done();
});
});
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
it('should call the success callback when the interval header is -1', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 200, headers: { 'poll-interval': -1 } });
2018-12-13 13:39:08 +05:30
setup()
.then(() => {
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
2017-08-17 22:00:37 +05:30
2018-12-13 13:39:08 +05:30
done();
})
.catch(done.fail);
2017-08-17 22:00:37 +05:30
});
2018-11-18 11:00:15 +05:30
describe('for 2xx status code', () => {
successCodes.forEach(httpCode => {
2018-12-13 13:39:08 +05:30
it(`starts polling when http status is ${httpCode} and interval header is provided`, done => {
2018-11-18 11:00:15 +05:30
mockServiceCall(service, { status: httpCode, headers: { 'poll-interval': 1 } });
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
const Polling = new Poll({
resource: service,
method: 'fetch',
data: { page: 1 },
successCallback: callbacks.success,
errorCallback: callbacks.error,
});
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
Polling.makeRequest();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
waitForAllCallsToFinish(service, 2, () => {
Polling.stop();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
expect(service.fetch.calls.count()).toEqual(2);
expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
2017-08-17 22:00:37 +05:30
2018-11-18 11:00:15 +05:30
done();
});
});
2017-08-17 22:00:37 +05:30
});
});
describe('stop', () => {
2018-12-13 13:39:08 +05:30
it('stops polling when method is called', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
2017-08-17 22:00:37 +05:30
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();
});
});
});
2019-07-07 11:18:12 +05:30
describe('enable', () => {
it('should enable polling upon a response', done => {
jasmine.clock().install();
const Polling = new Poll({
resource: service,
method: 'fetch',
data: { page: 1 },
successCallback: () => {},
});
Polling.enable({
data: { page: 4 },
response: { status: 200, headers: { 'poll-interval': 1 } },
});
jasmine.clock().tick(1);
jasmine.clock().uninstall();
waitForAllCallsToFinish(service, 1, () => {
Polling.stop();
expect(service.fetch.calls.count()).toEqual(1);
expect(service.fetch).toHaveBeenCalledWith({ page: 4 });
expect(Polling.options.data).toEqual({ page: 4 });
done();
});
});
});
2017-08-17 22:00:37 +05:30
describe('restart', () => {
2018-12-13 13:39:08 +05:30
it('should restart polling when its called', done => {
2017-09-10 17:25:29 +05:30
mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
2017-08-17 22:00:37 +05:30
const Polling = new Poll({
resource: service,
method: 'fetch',
data: { page: 1 },
successCallback: () => {
Polling.stop();
setTimeout(() => {
2018-03-17 18:26:18 +05:30
Polling.restart({ data: { page: 4 } });
2017-08-17 22:00:37 +05:30
}, 0);
},
errorCallback: callbacks.error,
});
spyOn(Polling, 'stop').and.callThrough();
2019-07-07 11:18:12 +05:30
spyOn(Polling, 'enable').and.callThrough();
2017-08-17 22:00:37 +05:30
spyOn(Polling, 'restart').and.callThrough();
Polling.makeRequest();
waitForAllCallsToFinish(service, 2, () => {
Polling.stop();
expect(service.fetch.calls.count()).toEqual(2);
2018-03-17 18:26:18 +05:30
expect(service.fetch).toHaveBeenCalledWith({ page: 4 });
2017-08-17 22:00:37 +05:30
expect(Polling.stop).toHaveBeenCalled();
2019-07-07 11:18:12 +05:30
expect(Polling.enable).toHaveBeenCalled();
2017-08-17 22:00:37 +05:30
expect(Polling.restart).toHaveBeenCalled();
2018-03-17 18:26:18 +05:30
expect(Polling.options.data).toEqual({ page: 4 });
2017-08-17 22:00:37 +05:30
done();
});
});
});
});