summaryrefslogtreecommitdiff
path: root/spec/frontend/issues/show/components/description_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/issues/show/components/description_spec.js')
-rw-r--r--spec/frontend/issues/show/components/description_spec.js170
1 files changed, 102 insertions, 68 deletions
diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js
index 08f8996de6f..0b3daadae1d 100644
--- a/spec/frontend/issues/show/components/description_spec.js
+++ b/spec/frontend/issues/show/components/description_spec.js
@@ -1,26 +1,35 @@
import $ from 'jquery';
import { nextTick } from 'vue';
import '~/behaviors/markdown/render_gfm';
-import { GlPopover, GlModal } from '@gitlab/ui';
+import { GlTooltip, GlModal } from '@gitlab/ui';
+import setWindowLocation from 'helpers/set_window_location_helper';
import { stubComponent } from 'helpers/stub_component';
import { TEST_HOST } from 'helpers/test_constants';
import { mockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import createFlash from '~/flash';
import Description from '~/issues/show/components/description.vue';
+import { updateHistory } from '~/lib/utils/url_utility';
import TaskList from '~/task_list';
import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import {
descriptionProps as initialProps,
descriptionHtmlWithCheckboxes,
+ descriptionHtmlWithTask,
} from '../mock_data/mock_data';
jest.mock('~/flash');
+jest.mock('~/lib/utils/url_utility', () => ({
+ ...jest.requireActual('~/lib/utils/url_utility'),
+ updateHistory: jest.fn(),
+}));
jest.mock('~/task_list');
const showModal = jest.fn();
const hideModal = jest.fn();
+const $toast = {
+ show: jest.fn(),
+};
describe('Description component', () => {
let wrapper;
@@ -28,10 +37,9 @@ describe('Description component', () => {
const findGfmContent = () => wrapper.find('[data-testid="gfm-content"]');
const findTextarea = () => wrapper.find('[data-testid="textarea"]');
const findTaskActionButtons = () => wrapper.findAll('.js-add-task');
- const findConvertToTaskButton = () => wrapper.find('[data-testid="convert-to-task"]');
- const findTaskSvg = () => wrapper.find('[data-testid="issue-open-m-icon"]');
+ const findConvertToTaskButton = () => wrapper.find('.js-add-task');
- const findPopovers = () => wrapper.findAllComponents(GlPopover);
+ const findTooltips = () => wrapper.findAllComponents(GlTooltip);
const findModal = () => wrapper.findComponent(GlModal);
const findCreateWorkItem = () => wrapper.findComponent(CreateWorkItem);
const findWorkItemDetailModal = () => wrapper.findComponent(WorkItemDetailModal);
@@ -39,10 +47,14 @@ describe('Description component', () => {
function createComponent({ props = {}, provide = {} } = {}) {
wrapper = shallowMountExtended(Description, {
propsData: {
+ issueId: 1,
...initialProps,
...props,
},
provide,
+ mocks: {
+ $toast,
+ },
stubs: {
GlModal: stubComponent(GlModal, {
methods: {
@@ -50,12 +62,13 @@ describe('Description component', () => {
hide: hideModal,
},
}),
- GlPopover,
},
});
}
beforeEach(() => {
+ setWindowLocation(TEST_HOST);
+
if (!document.querySelector('.issuable-meta')) {
const metaData = document.createElement('div');
metaData.classList.add('issuable-meta');
@@ -253,9 +266,9 @@ describe('Description component', () => {
expect(findTaskActionButtons()).toHaveLength(3);
});
- it('renders a list of popovers corresponding to checkboxes in description HTML', () => {
- expect(findPopovers()).toHaveLength(3);
- expect(findPopovers().at(0).props('target')).toBe(
+ it('renders a list of tooltips corresponding to checkboxes in description HTML', () => {
+ expect(findTooltips()).toHaveLength(3);
+ expect(findTooltips().at(0).props('target')).toBe(
findTaskActionButtons().at(0).attributes('id'),
);
});
@@ -264,92 +277,113 @@ describe('Description component', () => {
expect(findModal().props('visible')).toBe(false);
});
- it('opens a modal when a button on popover is clicked and displays correct title', async () => {
- findConvertToTaskButton().vm.$emit('click');
- expect(showModal).toHaveBeenCalled();
- await nextTick();
+ it('opens a modal when a button is clicked and displays correct title', async () => {
+ await findConvertToTaskButton().trigger('click');
expect(findCreateWorkItem().props('initialTitle').trim()).toBe('todo 1');
});
- it('closes the modal on `closeCreateTaskModal` event', () => {
- findConvertToTaskButton().vm.$emit('click');
+ it('closes the modal on `closeCreateTaskModal` event', async () => {
+ await findConvertToTaskButton().trigger('click');
findCreateWorkItem().vm.$emit('closeModal');
expect(hideModal).toHaveBeenCalled();
});
- it('updates description HTML on `onCreate` event', async () => {
- const newTitle = 'New title';
- findConvertToTaskButton().vm.$emit('click');
- findCreateWorkItem().vm.$emit('onCreate', { title: newTitle });
+ it('emits `updateDescription` on `onCreate` event', () => {
+ const newDescription = `<p>New description</p>`;
+ findCreateWorkItem().vm.$emit('onCreate', newDescription);
expect(hideModal).toHaveBeenCalled();
- await nextTick();
+ expect(wrapper.emitted('updateDescription')).toEqual([[newDescription]]);
+ });
+
+ it('shows toast after delete success', async () => {
+ findWorkItemDetailModal().vm.$emit('workItemDeleted');
- expect(findTaskSvg().exists()).toBe(true);
- expect(wrapper.text()).toContain(newTitle);
+ expect($toast.show).toHaveBeenCalledWith('Work item deleted');
});
});
describe('work items detail', () => {
- const id = '1';
- const title = 'my first task';
- const type = 'task';
+ const findTaskLink = () => wrapper.find('a.gfm-issue');
- const createThenClickOnTask = () => {
- findConvertToTaskButton().vm.$emit('click');
- findCreateWorkItem().vm.$emit('onCreate', { id, title, type });
- return wrapper.findByRole('button', { name: title }).trigger('click');
- };
-
- beforeEach(() => {
- createComponent({
- props: {
- descriptionHtml: descriptionHtmlWithCheckboxes,
- },
- provide: {
- glFeatures: { workItems: true },
- },
+ describe('when opening and closing', () => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ descriptionHtml: descriptionHtmlWithTask,
+ },
+ provide: {
+ glFeatures: { workItems: true },
+ },
+ });
+ return nextTick();
});
- return nextTick();
- });
- it('opens when task button is clicked', async () => {
- expect(findWorkItemDetailModal().props('visible')).toBe(false);
+ it('opens when task button is clicked', async () => {
+ expect(findWorkItemDetailModal().props('visible')).toBe(false);
- await createThenClickOnTask();
+ await findTaskLink().trigger('click');
- expect(findWorkItemDetailModal().props('visible')).toBe(true);
- });
+ expect(findWorkItemDetailModal().props('visible')).toBe(true);
+ expect(updateHistory).toHaveBeenCalledWith({
+ url: `${TEST_HOST}/?work_item_id=2`,
+ replace: true,
+ });
+ });
- it('closes from an open state', async () => {
- await createThenClickOnTask();
+ it('closes from an open state', async () => {
+ await findTaskLink().trigger('click');
- expect(findWorkItemDetailModal().props('visible')).toBe(true);
+ expect(findWorkItemDetailModal().props('visible')).toBe(true);
- findWorkItemDetailModal().vm.$emit('close');
- await nextTick();
+ findWorkItemDetailModal().vm.$emit('close');
+ await nextTick();
- expect(findWorkItemDetailModal().props('visible')).toBe(false);
- });
+ expect(findWorkItemDetailModal().props('visible')).toBe(false);
+ expect(updateHistory).toHaveBeenLastCalledWith({
+ url: `${TEST_HOST}/`,
+ replace: true,
+ });
+ });
- it('shows error on error', async () => {
- const message = 'I am error';
+ it('tracks when opened', async () => {
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
- await createThenClickOnTask();
- findWorkItemDetailModal().vm.$emit('error', message);
+ await findTaskLink().trigger('click');
- expect(createFlash).toHaveBeenCalledWith({ message });
+ expect(trackingSpy).toHaveBeenCalledWith(
+ 'workItems:show',
+ 'viewed_work_item_from_modal',
+ {
+ category: 'workItems:show',
+ label: 'work_item_view',
+ property: 'type_task',
+ },
+ );
+ });
});
- it('tracks when opened', async () => {
- const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
-
- await createThenClickOnTask();
-
- expect(trackingSpy).toHaveBeenCalledWith('workItems:show', 'viewed_work_item_from_modal', {
- category: 'workItems:show',
- label: 'work_item_view',
- property: 'type_task',
- });
+ describe('when url query `work_item_id` exists', () => {
+ it.each`
+ behavior | workItemId | visible
+ ${'opens'} | ${'123'} | ${true}
+ ${'does not open'} | ${'123e'} | ${false}
+ ${'does not open'} | ${'12e3'} | ${false}
+ ${'does not open'} | ${'1e23'} | ${false}
+ ${'does not open'} | ${'x'} | ${false}
+ ${'does not open'} | ${'undefined'} | ${false}
+ `(
+ '$behavior when url contains `work_item_id=$workItemId`',
+ async ({ workItemId, visible }) => {
+ setWindowLocation(`?work_item_id=${workItemId}`);
+
+ createComponent({
+ props: { descriptionHtml: descriptionHtmlWithTask },
+ provide: { glFeatures: { workItems: true } },
+ });
+
+ expect(findWorkItemDetailModal().props('visible')).toBe(visible);
+ },
+ );
});
});
});