Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js')
-rw-r--r--spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js289
1 files changed, 289 insertions, 0 deletions
diff --git a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
new file mode 100644
index 00000000000..bfbe4ec8e70
--- /dev/null
+++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
@@ -0,0 +1,289 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import { issuableTypesMap, linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants';
+import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
+
+const issuable1 = {
+ id: 200,
+ reference: 'foo/bar#123',
+ displayReference: '#123',
+ title: 'some title',
+ path: '/foo/bar/issues/123',
+ state: 'opened',
+};
+
+const issuable2 = {
+ id: 201,
+ reference: 'foo/bar#124',
+ displayReference: '#124',
+ title: 'some other thing',
+ path: '/foo/bar/issues/124',
+ state: 'opened',
+};
+
+const pathIdSeparator = PathIdSeparator.Issue;
+
+const findFormInput = wrapper => wrapper.find('.js-add-issuable-form-input').element;
+
+const findRadioInput = (inputs, value) => inputs.filter(input => input.element.value === value)[0];
+
+const findRadioInputs = wrapper => wrapper.findAll('[name="linked-issue-type-radio"]');
+
+const constructWrapper = props => {
+ return shallowMount(AddIssuableForm, {
+ propsData: {
+ inputValue: '',
+ pendingReferences: [],
+ pathIdSeparator,
+ ...props,
+ },
+ });
+};
+
+describe('AddIssuableForm', () => {
+ let wrapper;
+
+ afterEach(() => {
+ // Jest doesn't blur an item even if it is destroyed,
+ // so blur the input manually after each test
+ const input = findFormInput(wrapper);
+ if (input) input.blur();
+
+ wrapper.destroy();
+ });
+
+ describe('with data', () => {
+ describe('without references', () => {
+ describe('without any input text', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(AddIssuableForm, {
+ propsData: {
+ inputValue: '',
+ pendingReferences: [],
+ pathIdSeparator,
+ },
+ });
+ });
+
+ it('should have disabled submit button', () => {
+ expect(wrapper.vm.$refs.addButton.disabled).toBe(true);
+ expect(wrapper.vm.$refs.loadingIcon).toBeUndefined();
+ });
+ });
+
+ describe('with input text', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(AddIssuableForm, {
+ propsData: {
+ inputValue: 'foo',
+ pendingReferences: [],
+ pathIdSeparator,
+ },
+ });
+ });
+
+ it('should not have disabled submit button', () => {
+ expect(wrapper.vm.$refs.addButton.disabled).toBe(false);
+ });
+ });
+ });
+
+ describe('with references', () => {
+ const inputValue = 'foo #123';
+
+ beforeEach(() => {
+ wrapper = mount(AddIssuableForm, {
+ propsData: {
+ inputValue,
+ pendingReferences: [issuable1.reference, issuable2.reference],
+ pathIdSeparator,
+ },
+ });
+ });
+
+ it('should put input value in place', () => {
+ expect(findFormInput(wrapper).value).toEqual(inputValue);
+ });
+
+ it('should render pending issuables items', () => {
+ expect(wrapper.findAll('.js-add-issuable-form-token-list-item').length).toEqual(2);
+ });
+
+ it('should not have disabled submit button', () => {
+ expect(wrapper.vm.$refs.addButton.disabled).toBe(false);
+ });
+ });
+
+ describe('when issuable type is "issue"', () => {
+ beforeEach(() => {
+ wrapper = mount(AddIssuableForm, {
+ propsData: {
+ inputValue: '',
+ issuableType: issuableTypesMap.ISSUE,
+ pathIdSeparator,
+ pendingReferences: [],
+ },
+ });
+ });
+
+ it('does not show radio inputs', () => {
+ expect(findRadioInputs(wrapper).length).toBe(0);
+ });
+ });
+
+ describe('when issuable type is "epic"', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(AddIssuableForm, {
+ propsData: {
+ inputValue: '',
+ issuableType: issuableTypesMap.EPIC,
+ pathIdSeparator,
+ pendingReferences: [],
+ },
+ });
+ });
+
+ it('does not show radio inputs', () => {
+ expect(findRadioInputs(wrapper).length).toBe(0);
+ });
+ });
+
+ describe('when it is a Linked Issues form', () => {
+ beforeEach(() => {
+ wrapper = mount(AddIssuableForm, {
+ propsData: {
+ inputValue: '',
+ showCategorizedIssues: true,
+ issuableType: issuableTypesMap.ISSUE,
+ pathIdSeparator,
+ pendingReferences: [],
+ },
+ });
+ });
+
+ it('shows radio inputs to allow categorisation of blocking issues', () => {
+ expect(findRadioInputs(wrapper).length).toBeGreaterThan(0);
+ });
+
+ describe('form radio buttons', () => {
+ let radioInputs;
+
+ beforeEach(() => {
+ radioInputs = findRadioInputs(wrapper);
+ });
+
+ it('shows "relates to" option', () => {
+ expect(findRadioInput(radioInputs, linkedIssueTypesMap.RELATES_TO)).not.toBeNull();
+ });
+
+ it('shows "blocks" option', () => {
+ expect(findRadioInput(radioInputs, linkedIssueTypesMap.BLOCKS)).not.toBeNull();
+ });
+
+ it('shows "is blocked by" option', () => {
+ expect(findRadioInput(radioInputs, linkedIssueTypesMap.IS_BLOCKED_BY)).not.toBeNull();
+ });
+
+ it('shows 3 options in total', () => {
+ expect(radioInputs.length).toBe(3);
+ });
+ });
+
+ describe('when the form is submitted', () => {
+ it('emits an event with a "relates_to" link type when the "relates to" radio input selected', done => {
+ jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
+
+ wrapper.vm.linkedIssueType = linkedIssueTypesMap.RELATES_TO;
+ wrapper.vm.onFormSubmit();
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.RELATES_TO,
+ });
+ done();
+ });
+ });
+
+ it('emits an event with a "blocks" link type when the "blocks" radio input selected', done => {
+ jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
+
+ wrapper.vm.linkedIssueType = linkedIssueTypesMap.BLOCKS;
+ wrapper.vm.onFormSubmit();
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.BLOCKS,
+ });
+ done();
+ });
+ });
+
+ it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', done => {
+ jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
+
+ wrapper.vm.linkedIssueType = linkedIssueTypesMap.IS_BLOCKED_BY;
+ wrapper.vm.onFormSubmit();
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY,
+ });
+ done();
+ });
+ });
+
+ it('shows error message when error is present', done => {
+ const itemAddFailureMessage = 'Something went wrong while submitting.';
+ wrapper.setProps({
+ hasError: true,
+ itemAddFailureMessage,
+ });
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.gl-field-error').exists()).toBe(true);
+ expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage);
+ done();
+ });
+ });
+ });
+ });
+ });
+
+ describe('computed', () => {
+ describe('transformedAutocompleteSources', () => {
+ const autoCompleteSources = {
+ issues: 'http://localhost/autocomplete/issues',
+ epics: 'http://localhost/autocomplete/epics',
+ };
+
+ it('returns autocomplete object', () => {
+ wrapper = constructWrapper({
+ autoCompleteSources,
+ });
+
+ expect(wrapper.vm.transformedAutocompleteSources).toBe(autoCompleteSources);
+
+ wrapper = constructWrapper({
+ autoCompleteSources,
+ confidential: false,
+ });
+
+ expect(wrapper.vm.transformedAutocompleteSources).toBe(autoCompleteSources);
+ });
+
+ it('returns autocomplete sources with query `confidential_only`, when it is confidential', () => {
+ wrapper = constructWrapper({
+ autoCompleteSources,
+ confidential: true,
+ });
+
+ const actualSources = wrapper.vm.transformedAutocompleteSources;
+
+ expect(actualSources.epics).toContain('?confidential_only=true');
+ expect(actualSources.issues).toContain('?confidential_only=true');
+ });
+ });
+ });
+});