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

243 lines
6.8 KiB
JavaScript
Raw Normal View History

2020-10-24 23:57:45 +05:30
import waitForPromises from 'helpers/wait_for_promises';
2023-04-23 21:23:45 +05:30
import {
HTTP_STATUS_INTERNAL_SERVER_ERROR,
HTTP_STATUS_OK,
successCodes,
} from '~/lib/utils/http_status';
2021-03-11 19:13:27 +05:30
import Poll from '~/lib/utils/poll';
2017-08-17 22:00:37 +05:30
describe('Poll', () => {
2020-05-24 23:13:21 +05:30
let callbacks;
let service;
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
}
2020-05-24 23:13:21 +05:30
const mockServiceCall = (response, shouldFail = false) => {
const value = {
...response,
header: response.header || {},
};
if (shouldFail) {
service.fetch.mockRejectedValue(value);
} else {
service.fetch.mockResolvedValue(value);
}
};
const waitForAllCallsToFinish = (waitForCount, successCallback) => {
if (!waitForCount) {
return Promise.resolve().then(successCallback());
}
jest.runOnlyPendingTimers();
return waitForPromises().then(() => waitForAllCallsToFinish(waitForCount - 1, successCallback));
};
beforeEach(() => {
service = {
fetch: jest.fn(),
};
callbacks = {
success: jest.fn(),
error: jest.fn(),
notification: jest.fn(),
};
2017-09-10 17:25:29 +05:30
});
2022-06-21 17:19:12 +05:30
it('calls the success callback when no header for interval is provided', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK });
2017-09-10 17:25:29 +05:30
setup();
2017-08-17 22:00:37 +05:30
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(1, () => {
2017-08-17 22:00:37 +05:30
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
2017-09-10 17:25:29 +05:30
});
2017-08-17 22:00:37 +05:30
});
2022-06-21 17:19:12 +05:30
it('calls the error callback when the http request returns an error', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_INTERNAL_SERVER_ERROR }, true);
2017-09-10 17:25:29 +05:30
setup();
2017-08-17 22:00:37 +05:30
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(1, () => {
2017-08-17 22:00:37 +05:30
expect(callbacks.success).not.toHaveBeenCalled();
expect(callbacks.error).toHaveBeenCalled();
});
});
2022-06-21 17:19:12 +05:30
it('skips the error callback when request is aborted', () => {
2020-05-24 23:13:21 +05:30
mockServiceCall({ status: 0 }, true);
2017-09-10 17:25:29 +05:30
setup();
2017-08-17 22:00:37 +05:30
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(1, () => {
2017-09-10 17:25:29 +05:30
expect(callbacks.success).not.toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
expect(callbacks.notification).toHaveBeenCalled();
});
});
2017-08-17 22:00:37 +05:30
2022-06-21 17:19:12 +05:30
it('should call the success callback when the interval header is -1', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK, headers: { 'poll-interval': -1 } });
2022-06-21 17:19:12 +05:30
return setup().then(() => {
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
describe('for 2xx status code', () => {
2021-03-08 18:12:59 +05:30
successCodes.forEach((httpCode) => {
2022-06-21 17:19:12 +05:30
it(`starts polling when http status is ${httpCode} and interval header is provided`, () => {
2020-05-24 23:13:21 +05:30
mockServiceCall({ 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
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(2, () => {
2018-11-18 11:00:15 +05:30
Polling.stop();
2017-08-17 22:00:37 +05:30
2020-05-24 23:13:21 +05:30
expect(service.fetch.mock.calls).toHaveLength(2);
2018-11-18 11:00:15 +05:30
expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
});
});
2017-08-17 22:00:37 +05:30
});
});
2020-10-24 23:57:45 +05:30
describe('with delayed initial request', () => {
2022-06-21 17:19:12 +05:30
it('delays the first request', async () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK, headers: { 'poll-interval': 1 } });
2020-10-24 23:57:45 +05:30
const Polling = new Poll({
resource: service,
method: 'fetch',
data: { page: 1 },
successCallback: callbacks.success,
errorCallback: callbacks.error,
});
2022-10-11 01:57:18 +05:30
expect(Polling.timeoutID).toBeNull();
2020-10-24 23:57:45 +05:30
Polling.makeDelayedRequest(1);
2022-10-11 01:57:18 +05:30
expect(Polling.timeoutID).not.toBeNull();
2020-10-24 23:57:45 +05:30
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(2, () => {
2020-10-24 23:57:45 +05:30
Polling.stop();
expect(service.fetch.mock.calls).toHaveLength(2);
expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
expect(callbacks.success).toHaveBeenCalled();
expect(callbacks.error).not.toHaveBeenCalled();
});
});
});
2017-08-17 22:00:37 +05:30
describe('stop', () => {
2022-06-21 17:19:12 +05:30
it('stops polling when method is called', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK, 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,
});
2020-05-24 23:13:21 +05:30
jest.spyOn(Polling, 'stop');
2017-08-17 22:00:37 +05:30
Polling.makeRequest();
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(1, () => {
2020-05-24 23:13:21 +05:30
expect(service.fetch.mock.calls).toHaveLength(1);
2017-08-17 22:00:37 +05:30
expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
expect(Polling.stop).toHaveBeenCalled();
});
});
});
2019-07-07 11:18:12 +05:30
describe('enable', () => {
2022-06-21 17:19:12 +05:30
it('should enable polling upon a response', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK });
2019-07-07 11:18:12 +05:30
const Polling = new Poll({
resource: service,
method: 'fetch',
data: { page: 1 },
successCallback: () => {},
});
Polling.enable({
data: { page: 4 },
2023-04-23 21:23:45 +05:30
response: { status: HTTP_STATUS_OK, headers: { 'poll-interval': 1 } },
2019-07-07 11:18:12 +05:30
});
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(1, () => {
2019-07-07 11:18:12 +05:30
Polling.stop();
2020-05-24 23:13:21 +05:30
expect(service.fetch.mock.calls).toHaveLength(1);
2019-07-07 11:18:12 +05:30
expect(service.fetch).toHaveBeenCalledWith({ page: 4 });
expect(Polling.options.data).toEqual({ page: 4 });
});
});
});
2017-08-17 22:00:37 +05:30
describe('restart', () => {
2022-06-21 17:19:12 +05:30
it('should restart polling when its called', () => {
2023-04-23 21:23:45 +05:30
mockServiceCall({ status: HTTP_STATUS_OK, 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();
2020-05-24 23:13:21 +05:30
// Let's pretend that we asynchronously restart this.
// setTimeout is mocked but this will actually get triggered
// in waitForAllCalssToFinish.
2017-08-17 22:00:37 +05:30
setTimeout(() => {
2018-03-17 18:26:18 +05:30
Polling.restart({ data: { page: 4 } });
2020-05-24 23:13:21 +05:30
}, 1);
2017-08-17 22:00:37 +05:30
},
errorCallback: callbacks.error,
});
2020-05-24 23:13:21 +05:30
jest.spyOn(Polling, 'stop');
jest.spyOn(Polling, 'enable');
jest.spyOn(Polling, 'restart');
2017-08-17 22:00:37 +05:30
Polling.makeRequest();
2022-06-21 17:19:12 +05:30
return waitForAllCallsToFinish(2, () => {
2017-08-17 22:00:37 +05:30
Polling.stop();
2020-05-24 23:13:21 +05:30
expect(service.fetch.mock.calls).toHaveLength(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
});
});
});
});