summaryrefslogtreecommitdiff
path: root/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/issuable/related_issues/components/related_issues_root_spec.js')
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_root_spec.js341
1 files changed, 341 insertions, 0 deletions
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
new file mode 100644
index 00000000000..2544d0bd030
--- /dev/null
+++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
@@ -0,0 +1,341 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import waitForPromises from 'helpers/wait_for_promises';
+import {
+ defaultProps,
+ issuable1,
+ issuable2,
+} from 'jest/vue_shared/components/issue/related_issuable_mock_data';
+import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue';
+import relatedIssuesService from '~/related_issues/services/related_issues_service';
+import { linkedIssueTypesMap } from '~/related_issues/constants';
+import axios from '~/lib/utils/axios_utils';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
+
+jest.mock('~/flash');
+
+describe('RelatedIssuesRoot', () => {
+ let wrapper;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet(defaultProps.endpoint).reply(200, []);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ const createComponent = (mountFn = mount) => {
+ wrapper = mountFn(RelatedIssuesRoot, {
+ propsData: defaultProps,
+ });
+
+ // Wait for fetch request `fetchRelatedIssues` to complete before starting to test
+ return waitForPromises();
+ };
+
+ describe('methods', () => {
+ describe('onRelatedIssueRemoveRequest', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(relatedIssuesService.prototype, 'fetchRelatedIssues')
+ .mockReturnValue(Promise.reject());
+
+ return createComponent().then(() => {
+ wrapper.vm.store.setRelatedIssues([issuable1]);
+ });
+ });
+
+ it('remove related issue and succeeds', () => {
+ mock.onDelete(issuable1.referencePath).reply(200, { issues: [] });
+
+ wrapper.vm.onRelatedIssueRemoveRequest(issuable1.id);
+
+ return axios.waitForAll().then(() => {
+ expect(wrapper.vm.state.relatedIssues).toEqual([]);
+ });
+ });
+
+ it('remove related issue, fails, and restores to related issues', () => {
+ mock.onDelete(issuable1.referencePath).reply(422, {});
+
+ wrapper.vm.onRelatedIssueRemoveRequest(issuable1.id);
+
+ return axios.waitForAll().then(() => {
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(1);
+ expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
+ });
+ });
+ });
+
+ describe('onToggleAddRelatedIssuesForm', () => {
+ beforeEach(() => createComponent(shallowMount));
+
+ it('toggle related issues form to visible', () => {
+ wrapper.vm.onToggleAddRelatedIssuesForm();
+
+ expect(wrapper.vm.isFormVisible).toEqual(true);
+ });
+
+ it('show add related issues form to hidden', () => {
+ wrapper.vm.isFormVisible = true;
+
+ wrapper.vm.onToggleAddRelatedIssuesForm();
+
+ expect(wrapper.vm.isFormVisible).toEqual(false);
+ });
+ });
+
+ describe('onPendingIssueRemoveRequest', () => {
+ beforeEach(() =>
+ createComponent().then(() => {
+ wrapper.vm.store.setPendingReferences([issuable1.reference]);
+ }),
+ );
+
+ it('remove pending related issue', () => {
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(1);
+
+ wrapper.vm.onPendingIssueRemoveRequest(0);
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
+ });
+ });
+
+ describe('onPendingFormSubmit', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(relatedIssuesService.prototype, 'fetchRelatedIssues')
+ .mockReturnValue(Promise.reject());
+
+ return createComponent().then(() => {
+ jest.spyOn(wrapper.vm, 'processAllReferences');
+ jest.spyOn(wrapper.vm.service, 'addRelatedIssues');
+ createFlash.mockClear();
+ });
+ });
+
+ it('processes references before submitting', () => {
+ const input = '#123';
+ const linkedIssueType = linkedIssueTypesMap.RELATES_TO;
+ const emitObj = {
+ pendingReferences: input,
+ linkedIssueType,
+ };
+
+ wrapper.vm.onPendingFormSubmit(emitObj);
+
+ expect(wrapper.vm.processAllReferences).toHaveBeenCalledWith(input);
+ expect(wrapper.vm.service.addRelatedIssues).toHaveBeenCalledWith([input], linkedIssueType);
+ });
+
+ it('submit zero pending issue as related issue', () => {
+ wrapper.vm.store.setPendingReferences([]);
+ wrapper.vm.onPendingFormSubmit({});
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(0);
+ });
+ });
+
+ it('submit pending issue as related issue', () => {
+ mock.onPost(defaultProps.endpoint).reply(200, {
+ issuables: [issuable1],
+ result: {
+ message: 'something was successfully related',
+ status: 'success',
+ },
+ });
+
+ wrapper.vm.store.setPendingReferences([issuable1.reference]);
+ wrapper.vm.onPendingFormSubmit({});
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(1);
+ expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
+ });
+ });
+
+ it('submit multiple pending issues as related issues', () => {
+ mock.onPost(defaultProps.endpoint).reply(200, {
+ issuables: [issuable1, issuable2],
+ result: {
+ message: 'something was successfully related',
+ status: 'success',
+ },
+ });
+
+ wrapper.vm.store.setPendingReferences([issuable1.reference, issuable2.reference]);
+ wrapper.vm.onPendingFormSubmit({});
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(2);
+ expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
+ expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id);
+ });
+ });
+
+ it('displays a message from the backend upon error', () => {
+ const input = '#123';
+ const message = 'error';
+
+ mock.onPost(defaultProps.endpoint).reply(409, { message });
+ wrapper.vm.store.setPendingReferences([issuable1.reference, issuable2.reference]);
+
+ expect(createFlash).not.toHaveBeenCalled();
+ wrapper.vm.onPendingFormSubmit(input);
+
+ return waitForPromises().then(() => {
+ expect(createFlash).toHaveBeenCalledWith(message);
+ });
+ });
+ });
+
+ describe('onPendingFormCancel', () => {
+ beforeEach(() =>
+ createComponent().then(() => {
+ wrapper.vm.isFormVisible = true;
+ wrapper.vm.inputValue = 'foo';
+ }),
+ );
+
+ it('when canceling and hiding add issuable form', () => {
+ wrapper.vm.onPendingFormCancel();
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.isFormVisible).toEqual(false);
+ expect(wrapper.vm.inputValue).toEqual('');
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
+ });
+ });
+ });
+
+ describe('fetchRelatedIssues', () => {
+ beforeEach(() => createComponent());
+
+ it('sets isFetching while fetching', () => {
+ wrapper.vm.fetchRelatedIssues();
+
+ expect(wrapper.vm.isFetching).toEqual(true);
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.isFetching).toEqual(false);
+ });
+ });
+
+ it('should fetch related issues', () => {
+ mock.onGet(defaultProps.endpoint).reply(200, [issuable1, issuable2]);
+
+ wrapper.vm.fetchRelatedIssues();
+
+ return waitForPromises().then(() => {
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(2);
+ expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
+ expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id);
+ });
+ });
+ });
+
+ describe('onInput', () => {
+ beforeEach(() => createComponent());
+
+ it('fill in issue number reference and adds to pending related issues', () => {
+ const input = '#123 ';
+ wrapper.vm.onInput({
+ untouchedRawReferences: [input.trim()],
+ touchedReference: input,
+ });
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(1);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('#123');
+ });
+
+ it('fill in with full reference', () => {
+ const input = 'asdf/qwer#444 ';
+ wrapper.vm.onInput({ untouchedRawReferences: [input.trim()], touchedReference: input });
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(1);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('asdf/qwer#444');
+ });
+
+ it('fill in with issue link', () => {
+ const link = 'http://localhost:3000/foo/bar/issues/111';
+ const input = `${link} `;
+ wrapper.vm.onInput({ untouchedRawReferences: [input.trim()], touchedReference: input });
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(1);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual(link);
+ });
+
+ it('fill in with multiple references', () => {
+ const input = 'asdf/qwer#444 #12 ';
+ wrapper.vm.onInput({
+ untouchedRawReferences: input.trim().split(/\s/),
+ touchedReference: 2,
+ });
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(2);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('asdf/qwer#444');
+ expect(wrapper.vm.state.pendingReferences[1]).toEqual('#12');
+ });
+
+ it('fill in with some invalid things', () => {
+ const input = 'something random ';
+ wrapper.vm.onInput({
+ untouchedRawReferences: input.trim().split(/\s/),
+ touchedReference: 2,
+ });
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(2);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('something');
+ expect(wrapper.vm.state.pendingReferences[1]).toEqual('random');
+ });
+ });
+
+ describe('onBlur', () => {
+ beforeEach(() =>
+ createComponent().then(() => {
+ jest.spyOn(wrapper.vm, 'processAllReferences').mockImplementation(() => {});
+ }),
+ );
+
+ it('add any references to pending when blurring', () => {
+ const input = '#123';
+
+ wrapper.vm.onBlur(input);
+
+ expect(wrapper.vm.processAllReferences).toHaveBeenCalledWith(input);
+ });
+ });
+
+ describe('processAllReferences', () => {
+ beforeEach(() => createComponent());
+
+ it('add valid reference to pending', () => {
+ const input = '#123';
+ wrapper.vm.processAllReferences(input);
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(1);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('#123');
+ });
+
+ it('add any valid references to pending', () => {
+ const input = 'asdf #123';
+ wrapper.vm.processAllReferences(input);
+
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(2);
+ expect(wrapper.vm.state.pendingReferences[0]).toEqual('asdf');
+ expect(wrapper.vm.state.pendingReferences[1]).toEqual('#123');
+ });
+ });
+ });
+});