Commit c0dca9d2 authored by Phil Hughes's avatar Phil Hughes

Merge branch '344247-replace-setimmediate-in-tests-1' into 'master'

Remove setImmediate usage in specs

See merge request gitlab-org/gitlab!80367
parents a91a7f94 95f5d578
import { getByRole } from '@testing-library/dom';
import Vue, { nextTick } from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { OPEN_REVERT_MODAL, OPEN_CHERRY_PICK_MODAL } from '~/projects/commit/constants';
import modalEventHub from '~/projects/commit/event_hub';
import mergedComponent from '~/vue_merge_request_widget/components/states/mr_widget_merged.vue';
......@@ -127,7 +128,7 @@ describe('MRWidgetMerged', () => {
describe('methods', () => {
describe('removeSourceBranch', () => {
it('should set flag and call service then request main component to update the widget', (done) => {
it('should set flag and call service then request main component to update the widget', async () => {
jest.spyOn(vm.service, 'removeSourceBranch').mockReturnValue(
new Promise((resolve) => {
resolve({
......@@ -139,14 +140,14 @@ describe('MRWidgetMerged', () => {
);
vm.removeSourceBranch();
setImmediate(() => {
await waitForPromises();
const args = eventHub.$emit.mock.calls[0];
expect(vm.isMakingRequest).toEqual(true);
expect(args[0]).toEqual('MRWidgetUpdateRequested');
expect(args[1]).not.toThrow();
done();
});
});
});
});
......
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { GlSprintf } from '@gitlab/ui';
import waitForPromises from 'helpers/wait_for_promises';
import simplePoll from '~/lib/utils/simple_poll';
import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
......@@ -261,29 +262,27 @@ describe('ReadyToMerge', () => {
describe('methods', () => {
describe('handleMergeButtonClick', () => {
const returnPromise = (status) =>
new Promise((resolve) => {
resolve({
const response = (status) => ({
data: {
status,
},
});
});
it('should handle merge when pipeline succeeds', (done) => {
it('should handle merge when pipeline succeeds', async () => {
createComponent();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
jest
.spyOn(wrapper.vm.service, 'merge')
.mockReturnValue(returnPromise('merge_when_pipeline_succeeds'));
.mockResolvedValue(response('merge_when_pipeline_succeeds'));
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ removeSourceBranch: false });
wrapper.vm.handleMergeButtonClick(true);
setImmediate(() => {
await waitForPromises();
expect(wrapper.vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
expect(eventHub.$emit).toHaveBeenCalledWith('StateMachineValueChanged', {
......@@ -300,18 +299,17 @@ describe('ReadyToMerge', () => {
auto_merge_strategy: 'merge_when_pipeline_succeeds',
}),
);
done();
});
});
it('should handle merge failed', (done) => {
it('should handle merge failed', async () => {
createComponent();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'merge').mockReturnValue(returnPromise('failed'));
jest.spyOn(wrapper.vm.service, 'merge').mockResolvedValue(response('failed'));
wrapper.vm.handleMergeButtonClick(false, true);
setImmediate(() => {
await waitForPromises();
expect(wrapper.vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
......@@ -319,15 +317,13 @@ describe('ReadyToMerge', () => {
expect(params.should_remove_source_branch).toBeTruthy();
expect(params.auto_merge_strategy).toBeUndefined();
done();
});
});
it('should handle merge action accepted case', (done) => {
it('should handle merge action accepted case', async () => {
createComponent();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'merge').mockReturnValue(returnPromise('success'));
jest.spyOn(wrapper.vm.service, 'merge').mockResolvedValue(response('success'));
jest.spyOn(wrapper.vm.mr, 'transitionStateMachine');
wrapper.vm.handleMergeButtonClick();
......@@ -335,7 +331,8 @@ describe('ReadyToMerge', () => {
transition: 'start-merge',
});
setImmediate(() => {
await waitForPromises();
expect(wrapper.vm.isMakingRequest).toBeTruthy();
expect(wrapper.vm.mr.transitionStateMachine).toHaveBeenCalledWith({
transition: 'start-merge',
......@@ -345,8 +342,6 @@ describe('ReadyToMerge', () => {
expect(params.should_remove_source_branch).toBeTruthy();
expect(params.auto_merge_strategy).toBeUndefined();
done();
});
});
});
......@@ -364,20 +359,17 @@ describe('ReadyToMerge', () => {
});
describe('handleRemoveBranchPolling', () => {
const returnPromise = (state) =>
new Promise((resolve) => {
resolve({
const response = (state) => ({
data: {
source_branch_exists: state,
},
});
});
it('should call start and stop polling when MR merged', (done) => {
it('should call start and stop polling when MR merged', async () => {
createComponent();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'poll').mockReturnValue(returnPromise(false));
jest.spyOn(wrapper.vm.service, 'poll').mockResolvedValue(response(false));
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
......@@ -390,7 +382,9 @@ describe('ReadyToMerge', () => {
spc = true;
},
);
setImmediate(() => {
await waitForPromises();
expect(wrapper.vm.service.poll).toHaveBeenCalled();
const args = eventHub.$emit.mock.calls[0];
......@@ -403,15 +397,12 @@ describe('ReadyToMerge', () => {
expect(cpc).toBeFalsy();
expect(spc).toBeTruthy();
done();
});
});
it('should continue polling until MR is merged', (done) => {
it('should continue polling until MR is merged', async () => {
createComponent();
jest.spyOn(wrapper.vm.service, 'poll').mockReturnValue(returnPromise(true));
jest.spyOn(wrapper.vm.service, 'poll').mockResolvedValue(response(true));
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
......@@ -424,12 +415,11 @@ describe('ReadyToMerge', () => {
spc = true;
},
);
setImmediate(() => {
await waitForPromises();
expect(cpc).toBeTruthy();
expect(spc).toBeFalsy();
done();
});
});
});
});
......
import Vue, { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import WorkInProgress from '~/vue_merge_request_widget/components/states/work_in_progress.vue';
import toast from '~/vue_shared/plugins/global_toast';
import eventHub from '~/vue_merge_request_widget/event_hub';
......@@ -47,7 +48,7 @@ describe('Wip', () => {
};
describe('handleRemoveDraft', () => {
it('should make a request to service and handle response', (done) => {
it('should make a request to service and handle response', async () => {
const vm = createComponent();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
......@@ -60,12 +61,12 @@ describe('Wip', () => {
);
vm.handleRemoveDraft();
setImmediate(() => {
await waitForPromises();
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
expect(toast).toHaveBeenCalledWith('Marked as ready. Merging is now allowed.');
done();
});
});
});
});
......@@ -91,13 +92,12 @@ describe('Wip', () => {
);
});
it('should not show removeWIP button is user cannot update MR', (done) => {
it('should not show removeWIP button is user cannot update MR', async () => {
vm.mr.removeWIPPath = '';
nextTick(() => {
await nextTick();
expect(el.querySelector('.js-remove-draft')).toEqual(null);
done();
});
});
});
});
......@@ -176,17 +176,18 @@ describe('AlertManagementStatus', () => {
jest.spyOn(Tracking, 'event');
});
it('should not track alert status updates when the tracking options do not exist', () => {
it('should not track alert status updates when the tracking options do not exist', async () => {
mountComponent({});
Tracking.event.mockClear();
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
findFirstStatusOption().vm.$emit('click');
setImmediate(() => {
await nextTick();
expect(Tracking.event).not.toHaveBeenCalled();
});
});
it('should track alert status updates when the tracking options exist', () => {
it('should track alert status updates when the tracking options exist', async () => {
const trackAlertStatusUpdateOptions = {
category: 'Alert Management',
action: 'update_alert_status',
......@@ -196,11 +197,12 @@ describe('AlertManagementStatus', () => {
Tracking.event.mockClear();
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
findFirstStatusOption().vm.$emit('click');
await nextTick();
const status = findFirstStatusOption().text();
setImmediate(() => {
const { category, action, label } = trackAlertStatusUpdateOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action, { label, property: status });
});
});
});
});
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import { GREEN_BOX_IMAGE_URL, RED_BOX_IMAGE_URL } from 'spec/test_constants';
......@@ -26,14 +26,15 @@ describe('DiffViewer', () => {
vm.$destroy();
});
it('renders image diff', (done) => {
it('renders image diff', async () => {
window.gon = {
relative_url_root: '',
};
createComponent({ ...requiredProps, projectPath: '' });
setImmediate(() => {
await nextTick();
expect(vm.$el.querySelector('.deleted img').getAttribute('src')).toBe(
`//-/raw/DEF/${RED_BOX_IMAGE_URL}`,
);
......@@ -41,12 +42,9 @@ describe('DiffViewer', () => {
expect(vm.$el.querySelector('.added img').getAttribute('src')).toBe(
`//-/raw/ABC/${GREEN_BOX_IMAGE_URL}`,
);
done();
});
});
it('renders fallback download diff display', (done) => {
it('renders fallback download diff display', async () => {
createComponent({
...requiredProps,
diffViewerMode: 'added',
......@@ -54,10 +52,9 @@ describe('DiffViewer', () => {
oldPath: 'testold.abc',
});
setImmediate(() => {
expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain(
'testold.abc',
);
await nextTick();
expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain('testold.abc');
expect(vm.$el.querySelector('.deleted .btn.btn-default').textContent.trim()).toContain(
'Download',
......@@ -67,9 +64,6 @@ describe('DiffViewer', () => {
expect(vm.$el.querySelector('.added .btn.btn-default').textContent.trim()).toContain(
'Download',
);
done();
});
});
describe('renamed file', () => {
......
......@@ -75,33 +75,29 @@ describe('ImageDiffViewer', () => {
expect(metaInfoElements[1]).toHaveText('1.00 KiB');
});
it('renders image diff for new', (done) => {
it('renders image diff for new', async () => {
createComponent({ ...allProps, diffMode: 'new', oldPath: '' });
setImmediate(() => {
await nextTick();
const metaInfoElement = vm.$el.querySelector('.image-info');
expect(vm.$el.querySelector('.added img').getAttribute('src')).toBe(GREEN_BOX_IMAGE_URL);
expect(metaInfoElement).toHaveText('1.00 KiB');
done();
});
});
it('renders image diff for deleted', (done) => {
it('renders image diff for deleted', async () => {
createComponent({ ...allProps, diffMode: 'deleted', newPath: '' });
setImmediate(() => {
await nextTick();
const metaInfoElement = vm.$el.querySelector('.image-info');
expect(vm.$el.querySelector('.deleted img').getAttribute('src')).toBe(RED_BOX_IMAGE_URL);
expect(metaInfoElement).toHaveText('2.00 KiB');
done();
});
});
it('renders image diff for renamed', (done) => {
it('renders image diff for renamed', async () => {
vm = new Vue({
components: {
imageDiffViewer,
......@@ -127,25 +123,21 @@ describe('ImageDiffViewer', () => {
`),
}).$mount();
setImmediate(() => {
await nextTick();
const metaInfoElement = vm.$el.querySelector('.image-info');
expect(vm.$el.querySelector('img').getAttribute('src')).toBe(GREEN_BOX_IMAGE_URL);
expect(vm.$el.querySelector('.overlay')).not.toBe(null);
expect(metaInfoElement).toHaveText('2.00 KiB');
done();
});
});
describe('swipeMode', () => {
beforeEach((done) => {
beforeEach(() => {
createComponent({ ...requiredProps });
setImmediate(() => {
done();
});
return nextTick();
});
it('switches to Swipe Mode', async () => {
......@@ -157,12 +149,10 @@ describe('ImageDiffViewer', () => {
});
describe('onionSkin', () => {
beforeEach((done) => {
beforeEach(() => {
createComponent({ ...requiredProps });
setImmediate(() => {
done();
});
return nextTick();
});
it('switches to Onion Skin Mode', async () => {
......
import Mousetrap from 'mousetrap';
import Vue, { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import { file } from 'jest/ide/helpers';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
import FindFileComponent from '~/vue_shared/components/file_finder/index.vue';
......@@ -31,7 +30,7 @@ describe('File finder item spec', () => {
});
describe('with entries', () => {
beforeEach((done) => {
beforeEach(() => {
createComponent({
files: [
{
......@@ -48,7 +47,7 @@ describe('File finder item spec', () => {
],
});
setImmediate(done);
return nextTick();
});
it('renders list of blobs', () => {
......@@ -57,68 +56,48 @@ describe('File finder item spec', () => {
expect(vm.$el.textContent).not.toContain('folder');
});
it('filters entries', (done) => {
it('filters entries', async () => {
vm.searchText = 'index';
setImmediate(() => {
await nextTick();
expect(vm.$el.textContent).toContain('index.js');
expect(vm.$el.textContent).not.toContain('component.js');
done();
});
});
it('shows clear button when searchText is not empty', (done) => {
it('shows clear button when searchText is not empty', async () => {
vm.searchText = 'index';
setImmediate(() => {
await nextTick();
expect(vm.$el.querySelector('.dropdown-input').classList).toContain('has-value');
expect(vm.$el.querySelector('.dropdown-input-search').classList).toContain('hidden');
done();
});
});
it('clear button resets searchText', (done) => {
it('clear button resets searchText', async () => {
vm.searchText = 'index';
waitForPromises()
.then(() => {
vm.clearSearchInput();
})
.then(waitForPromises)
.then(() => {
expect(vm.searchText).toBe('');
})
.then(done)
.catch(done.fail);
});
it('clear button focuses search input', (done) => {
it('clear button focuses search input', async () => {
jest.spyOn(vm.$refs.searchInput, 'focus').mockImplementation(() => {});
vm.searchText = 'index';
waitForPromises()
.then(() => {
vm.clearSearchInput();
})
.then(waitForPromises)
.then(() => {
await nextTick();
expect(vm.$refs.searchInput.focus).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
describe('listShowCount', () => {
it('returns 1 when no filtered entries exist', (done) => {
it('returns 1 when no filtered entries exist', () => {
vm.searchText = 'testing 123';
setImmediate(() => {
expect(vm.listShowCount).toBe(1);
done();
});
});
it('returns entries length when not filtered', () => {
......@@ -131,26 +110,18 @@ describe('File finder item spec', () => {
expect(vm.listHeight).toBe(55);
});
it('returns 33 when entries dont exist', (done) => {
it('returns 33 when entries dont exist', () => {
vm.searchText = 'testing 123';
setImmediate(() => {
expect(vm.listHeight).toBe(33);
done();
});
});
});
describe('filteredBlobsLength', () => {
it('returns length of filtered blobs', (done) => {
it('returns length of filtered blobs', () => {
vm.searchText = 'index';
setImmediate(() => {
expect(vm.filteredBlobsLength).toBe(1);
done();
});
});
});
......@@ -158,7 +129,7 @@ describe('File finder item spec', () => {
it('renders less DOM nodes if not visible by utilizing v-if', async () => {
vm.visible = false;
await waitForPromises();
await nextTick();
expect(vm.$el).toBeInstanceOf(Comment);
});
......@@ -166,33 +137,24 @@ describe('File finder item spec', () => {
describe('watches', () => {
describe('searchText', () => {
it('resets focusedIndex when updated', (done) => {
it('resets focusedIndex when updated', async () => {
vm.focusedIndex = 1;
vm.searchText = 'test';
setImmediate(() => {
expect(vm.focusedIndex).toBe(0);
await nextTick();
done();
});
expect(vm.focusedIndex).toBe(0);
});
});
describe('visible', () => {
it('resets searchText when changed to false', (done) => {
it('resets searchText when changed to false', async () => {
vm.searchText = 'test';
vm.visible = true;
waitForPromises()
.then(() => {
vm.visible = false;
})
.then(waitForPromises)
.then(() => {
await nextTick();
expect(vm.searchText).toBe('');
})
.then(done)
.catch(done.fail);
});
});
});
......@@ -216,7 +178,7 @@ describe('File finder item spec', () => {
});
describe('onKeyup', () => {
it('opens file on enter key', (done) => {
it('opens file on enter key', async () => {
const event = new CustomEvent('keyup');
event.keyCode = ENTER_KEY_CODE;
......@@ -224,14 +186,12 @@ describe('File finder item spec', () => {
vm.$refs.searchInput.dispatchEvent(event);
setImmediate(() => {
expect(vm.openFile).toHaveBeenCalledWith(vm.files[0]);
await nextTick();
done();
});
expect(vm.openFile).toHaveBeenCalledWith(vm.files[0]);
});
it('closes file finder on esc key', (done) => {
it('closes file finder on esc key', async () => {
const event = new CustomEvent('keyup');
event.keyCode = ESC_KEY_CODE;
......@@ -239,11 +199,9 @@ describe('File finder item spec', () => {
vm.$refs.searchInput.dispatchEvent(event);
setImmediate(() => {
expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
await nextTick();
done();
});
expect(vm.$emit).toHaveBeenCalledWith('toggle', false);
});
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment