summaryrefslogtreecommitdiff
path: root/spec/frontend/issuable
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/issuable')
-rw-r--r--spec/frontend/issuable/helpers.js18
-rw-r--r--spec/frontend/issuable/issuable_form_spec.js72
-rw-r--r--spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js15
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_block_spec.js6
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_root_spec.js17
5 files changed, 98 insertions, 30 deletions
diff --git a/spec/frontend/issuable/helpers.js b/spec/frontend/issuable/helpers.js
new file mode 100644
index 00000000000..632d69c2c88
--- /dev/null
+++ b/spec/frontend/issuable/helpers.js
@@ -0,0 +1,18 @@
+export function getSaveableFormChildren(form, exclude = ['input.js-toggle-draft']) {
+ const children = Array.from(form.children);
+ const saveable = children.filter((e) => {
+ const isFiltered = exclude.reduce(
+ ({ isFiltered: filtered, element }, selector) => {
+ return {
+ isFiltered: filtered || element.matches(selector),
+ element,
+ };
+ },
+ { isFiltered: false, element: e },
+ );
+
+ return !isFiltered.isFiltered;
+ });
+
+ return saveable;
+}
diff --git a/spec/frontend/issuable/issuable_form_spec.js b/spec/frontend/issuable/issuable_form_spec.js
index 28ec0e22d8b..3e778e50fb8 100644
--- a/spec/frontend/issuable/issuable_form_spec.js
+++ b/spec/frontend/issuable/issuable_form_spec.js
@@ -4,6 +4,8 @@ import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import IssuableForm from '~/issuable/issuable_form';
import setWindowLocation from 'helpers/set_window_location_helper';
+import { getSaveableFormChildren } from './helpers';
+
jest.mock('~/autosave');
const createIssuable = (form) => {
@@ -18,6 +20,7 @@ describe('IssuableForm', () => {
setHTMLFixture(`
<form>
<input name="[title]" />
+ <input type="checkbox" class="js-toggle-draft" />
<textarea name="[description]"></textarea>
</form>
`);
@@ -99,10 +102,11 @@ describe('IssuableForm', () => {
])('creates $id autosave when $id input exist', ({ id, input, selector }) => {
$form.append(input);
const $input = $form.find(selector);
- const totalAutosaveFormFields = $form.children().length;
createIssuable($form);
- expect(Autosave).toHaveBeenCalledTimes(totalAutosaveFormFields);
+ const children = getSaveableFormChildren($form[0]);
+
+ expect(Autosave).toHaveBeenCalledTimes(children.length);
expect(Autosave).toHaveBeenLastCalledWith(
$input.get(0),
['/', '', id],
@@ -153,12 +157,17 @@ describe('IssuableForm', () => {
});
});
- describe('wip', () => {
+ describe('draft', () => {
+ let titleField;
+ let toggleDraft;
+
beforeEach(() => {
instance = createIssuable($form);
+ titleField = document.querySelector('input[name="[title]"]');
+ toggleDraft = document.querySelector('input.js-toggle-draft');
});
- describe('removeWip', () => {
+ describe('removeDraft', () => {
it.each`
prefix
${'draFT: '}
@@ -169,25 +178,25 @@ describe('IssuableForm', () => {
${' (DrafT)'}
${'draft: [draft] (draft)'}
`('removes "$prefix" from the beginning of the title', ({ prefix }) => {
- instance.titleField.val(`${prefix}The Issuable's Title Value`);
+ titleField.value = `${prefix}The Issuable's Title Value`;
- instance.removeWip();
+ instance.removeDraft();
- expect(instance.titleField.val()).toBe("The Issuable's Title Value");
+ expect(titleField.value).toBe("The Issuable's Title Value");
});
});
- describe('addWip', () => {
+ describe('addDraft', () => {
it("properly adds the work in progress prefix to the Issuable's title", () => {
- instance.titleField.val("The Issuable's Title Value");
+ titleField.value = "The Issuable's Title Value";
- instance.addWip();
+ instance.addDraft();
- expect(instance.titleField.val()).toBe("Draft: The Issuable's Title Value");
+ expect(titleField.value).toBe("Draft: The Issuable's Title Value");
});
});
- describe('workInProgress', () => {
+ describe('isMarkedDraft', () => {
it.each`
title | expected
${'draFT: something is happening'} | ${true}
@@ -195,10 +204,45 @@ describe('IssuableForm', () => {
${'something is happening to drafts'} | ${false}
${'something is happening'} | ${false}
`('returns $expected with "$title"', ({ title, expected }) => {
- instance.titleField.val(title);
+ titleField.value = title;
- expect(instance.workInProgress()).toBe(expected);
+ expect(instance.isMarkedDraft()).toBe(expected);
});
});
+
+ describe('readDraftStatus', () => {
+ it.each`
+ title | checked
+ ${'Draft: my title'} | ${true}
+ ${'my title'} | ${false}
+ `(
+ 'sets the draft checkbox checked status to $checked when the title is $title',
+ ({ title, checked }) => {
+ titleField.value = title;
+
+ instance.readDraftStatus();
+
+ expect(toggleDraft.checked).toBe(checked);
+ },
+ );
+ });
+
+ describe('writeDraftStatus', () => {
+ it.each`
+ checked | title
+ ${true} | ${'Draft: my title'}
+ ${false} | ${'my title'}
+ `(
+ 'updates the title to $title when the draft checkbox checked status is $checked',
+ ({ checked, title }) => {
+ titleField.value = 'my title';
+ toggleDraft.checked = checked;
+
+ instance.writeDraftStatus();
+
+ expect(titleField.value).toBe(title);
+ },
+ );
+ });
});
});
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
index 16d4459f597..72fcab63ba7 100644
--- a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
+++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
@@ -1,9 +1,10 @@
import { GlFormGroup } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { TYPE_EPIC, TYPE_ISSUE } from '~/issues/constants';
import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
import IssueToken from '~/related_issues/components/issue_token.vue';
-import { issuableTypesMap, linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants';
+import { linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants';
const issuable1 = {
id: 200,
@@ -125,7 +126,7 @@ describe('AddIssuableForm', () => {
wrapper = mount(AddIssuableForm, {
propsData: {
inputValue: '',
- issuableType: issuableTypesMap.ISSUE,
+ issuableType: TYPE_ISSUE,
pathIdSeparator,
pendingReferences: [],
},
@@ -142,7 +143,7 @@ describe('AddIssuableForm', () => {
wrapper = shallowMount(AddIssuableForm, {
propsData: {
inputValue: '',
- issuableType: issuableTypesMap.EPIC,
+ issuableType: TYPE_EPIC,
pathIdSeparator,
pendingReferences: [],
},
@@ -156,9 +157,9 @@ describe('AddIssuableForm', () => {
describe('categorized issuables', () => {
it.each`
- issuableType | pathIdSeparator | contextHeader | contextFooter
- ${issuableTypesMap.ISSUE} | ${PathIdSeparator.Issue} | ${'The current issue'} | ${'the following issues'}
- ${issuableTypesMap.EPIC} | ${PathIdSeparator.Epic} | ${'The current epic'} | ${'the following epics'}
+ issuableType | pathIdSeparator | contextHeader | contextFooter
+ ${TYPE_ISSUE} | ${PathIdSeparator.Issue} | ${'The current issue'} | ${'the following issues'}
+ ${TYPE_EPIC} | ${PathIdSeparator.Epic} | ${'The current epic'} | ${'the following epics'}
`(
'show header text as "$contextHeader" and footer text as "$contextFooter" issuableType is set to $issuableType',
({ issuableType, contextHeader, contextFooter }) => {
@@ -184,7 +185,7 @@ describe('AddIssuableForm', () => {
propsData: {
inputValue: '',
showCategorizedIssues: true,
- issuableType: issuableTypesMap.ISSUE,
+ issuableType: TYPE_ISSUE,
pathIdSeparator,
pendingReferences: [],
},
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
index 996b2406240..ff8d5073005 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
@@ -6,10 +6,10 @@ import {
issuable2,
issuable3,
} from 'jest/issuable/components/related_issuable_mock_data';
+import { TYPE_ISSUE } from '~/issues/constants';
import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue';
import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
import {
- issuableTypesMap,
linkedIssueTypesMap,
linkedIssueTypesTextMap,
PathIdSeparator,
@@ -34,7 +34,7 @@ describe('RelatedIssuesBlock', () => {
wrapper = mountExtended(RelatedIssuesBlock, {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
- issuableType: issuableTypesMap.ISSUE,
+ issuableType: TYPE_ISSUE,
},
});
});
@@ -237,7 +237,7 @@ describe('RelatedIssuesBlock', () => {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
relatedIssues: [issuable1, issuable2, issuable3],
- issuableType: issuableTypesMap.ISSUE,
+ issuableType: TYPE_ISSUE,
},
});
});
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
index bedf8bcaf34..96c0b87e2cb 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
@@ -9,6 +9,11 @@ import {
} from 'jest/issuable/components/related_issuable_mock_data';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
+import {
+ HTTP_STATUS_CONFLICT,
+ HTTP_STATUS_OK,
+ HTTP_STATUS_UNPROCESSABLE_ENTITY,
+} from '~/lib/utils/http_status';
import { linkedIssueTypesMap } from '~/related_issues/constants';
import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue';
import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue';
@@ -24,7 +29,7 @@ describe('RelatedIssuesRoot', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
- mock.onGet(defaultProps.endpoint).reply(200, []);
+ mock.onGet(defaultProps.endpoint).reply(HTTP_STATUS_OK, []);
});
afterEach(() => {
@@ -59,7 +64,7 @@ describe('RelatedIssuesRoot', () => {
});
it('removes related issue on API success', async () => {
- mock.onDelete(issuable1.referencePath).reply(200, { issues: [] });
+ mock.onDelete(issuable1.referencePath).reply(HTTP_STATUS_OK, { issues: [] });
findRelatedIssuesBlock().vm.$emit('relatedIssueRemoveRequest', issuable1.id);
await axios.waitForAll();
@@ -68,7 +73,7 @@ describe('RelatedIssuesRoot', () => {
});
it('does not remove related issue on API error', async () => {
- mock.onDelete(issuable1.referencePath).reply(422, {});
+ mock.onDelete(issuable1.referencePath).reply(HTTP_STATUS_UNPROCESSABLE_ENTITY, {});
findRelatedIssuesBlock().vm.$emit('relatedIssueRemoveRequest', issuable1.id);
await axios.waitForAll();
@@ -163,7 +168,7 @@ describe('RelatedIssuesRoot', () => {
});
it('submits pending issue as related issue', async () => {
- mock.onPost(defaultProps.endpoint).reply(200, {
+ mock.onPost(defaultProps.endpoint).reply(HTTP_STATUS_OK, {
issuables: [issuable1],
result: {
message: 'something was successfully related',
@@ -182,7 +187,7 @@ describe('RelatedIssuesRoot', () => {
});
it('submits multiple pending issues as related issues', async () => {
- mock.onPost(defaultProps.endpoint).reply(200, {
+ mock.onPost(defaultProps.endpoint).reply(HTTP_STATUS_OK, {
issuables: [issuable1, issuable2],
result: {
message: 'something was successfully related',
@@ -204,7 +209,7 @@ describe('RelatedIssuesRoot', () => {
it('passes an error message from the backend upon error', async () => {
const input = '#123';
const message = 'error';
- mock.onPost(defaultProps.endpoint).reply(409, { message });
+ mock.onPost(defaultProps.endpoint).reply(HTTP_STATUS_CONFLICT, { message });
wrapper.vm.store.setPendingReferences([issuable1.reference, issuable2.reference]);
expect(findRelatedIssuesBlock().props('hasError')).toBe(false);