diff options
Diffstat (limited to 'spec/frontend/issuable_show/components')
4 files changed, 144 insertions, 2 deletions
diff --git a/spec/frontend/issuable_show/components/issuable_body_spec.js b/spec/frontend/issuable_show/components/issuable_body_spec.js index bf166bea1e5..6fa298ca3f2 100644 --- a/spec/frontend/issuable_show/components/issuable_body_spec.js +++ b/spec/frontend/issuable_show/components/issuable_body_spec.js @@ -6,11 +6,13 @@ import IssuableBody from '~/issuable_show/components/issuable_body.vue'; import IssuableDescription from '~/issuable_show/components/issuable_description.vue'; import IssuableEditForm from '~/issuable_show/components/issuable_edit_form.vue'; import IssuableTitle from '~/issuable_show/components/issuable_title.vue'; +import TaskList from '~/task_list'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import { mockIssuableShowProps, mockIssuable } from '../mock_data'; jest.mock('~/autosave'); +jest.mock('~/flash'); const issuableBodyProps = { ...mockIssuableShowProps, @@ -80,6 +82,75 @@ describe('IssuableBody', () => { }); }); + describe('watchers', () => { + describe('editFormVisible', () => { + it('calls initTaskList in nextTick', async () => { + jest.spyOn(wrapper.vm, 'initTaskList'); + wrapper.setProps({ + editFormVisible: true, + }); + + await wrapper.vm.$nextTick(); + + wrapper.setProps({ + editFormVisible: false, + }); + + await wrapper.vm.$nextTick(); + + expect(wrapper.vm.initTaskList).toHaveBeenCalled(); + }); + }); + }); + + describe('mounted', () => { + it('initializes TaskList instance when enabledEdit and enableTaskList props are true', () => { + expect(wrapper.vm.taskList instanceof TaskList).toBe(true); + expect(wrapper.vm.taskList).toMatchObject({ + dataType: 'issue', + fieldName: 'description', + lockVersion: issuableBodyProps.taskListLockVersion, + selector: '.js-detail-page-description', + onSuccess: expect.any(Function), + onError: expect.any(Function), + }); + }); + + it('does not initialize TaskList instance when either enabledEdit or enableTaskList prop is false', () => { + const wrapperNoTaskList = createComponent({ + ...issuableBodyProps, + enableTaskList: false, + }); + + expect(wrapperNoTaskList.vm.taskList).not.toBeDefined(); + + wrapperNoTaskList.destroy(); + }); + }); + + describe('methods', () => { + describe('handleTaskListUpdateSuccess', () => { + it('emits `task-list-update-success` event on component', () => { + const updatedIssuable = { + foo: 'bar', + }; + + wrapper.vm.handleTaskListUpdateSuccess(updatedIssuable); + + expect(wrapper.emitted('task-list-update-success')).toBeTruthy(); + expect(wrapper.emitted('task-list-update-success')[0]).toEqual([updatedIssuable]); + }); + }); + + describe('handleTaskListUpdateFailure', () => { + it('emits `task-list-update-failure` event on component', () => { + wrapper.vm.handleTaskListUpdateFailure(); + + expect(wrapper.emitted('task-list-update-failure')).toBeTruthy(); + }); + }); + }); + describe('template', () => { it('renders issuable-title component', () => { const titleEl = wrapper.find(IssuableTitle); diff --git a/spec/frontend/issuable_show/components/issuable_description_spec.js b/spec/frontend/issuable_show/components/issuable_description_spec.js index 29ecce1002d..1058e5decfd 100644 --- a/spec/frontend/issuable_show/components/issuable_description_spec.js +++ b/spec/frontend/issuable_show/components/issuable_description_spec.js @@ -5,9 +5,14 @@ import IssuableDescription from '~/issuable_show/components/issuable_description import { mockIssuable } from '../mock_data'; -const createComponent = (issuable = mockIssuable) => +const createComponent = ({ + issuable = mockIssuable, + enableTaskList = true, + canEdit = true, + taskListUpdatePath = `${mockIssuable.webUrl}.json`, +} = {}) => shallowMount(IssuableDescription, { - propsData: { issuable }, + propsData: { issuable, enableTaskList, canEdit, taskListUpdatePath }, }); describe('IssuableDescription', () => { @@ -38,4 +43,27 @@ describe('IssuableDescription', () => { }); }); }); + + describe('templates', () => { + it('renders container element with class `js-task-list-container` when canEdit and enableTaskList props are true', () => { + expect(wrapper.classes()).toContain('js-task-list-container'); + }); + + it('renders container element without class `js-task-list-container` when canEdit and enableTaskList props are true', () => { + const wrapperNoTaskList = createComponent({ + enableTaskList: false, + }); + + expect(wrapperNoTaskList.classes()).not.toContain('js-task-list-container'); + + wrapperNoTaskList.destroy(); + }); + + it('renders hidden textarea element when issuable.description is present and enableTaskList prop is true', () => { + const textareaEl = wrapper.find('textarea.gl-display-none.js-task-list-field'); + + expect(textareaEl.exists()).toBe(true); + expect(textareaEl.attributes('data-update-url')).toBe(`${mockIssuable.webUrl}.json`); + }); + }); }); diff --git a/spec/frontend/issuable_show/components/issuable_header_spec.js b/spec/frontend/issuable_show/components/issuable_header_spec.js index 2164caa40a8..b85f2dd1999 100644 --- a/spec/frontend/issuable_show/components/issuable_header_spec.js +++ b/spec/frontend/issuable_show/components/issuable_header_spec.js @@ -119,6 +119,27 @@ describe('IssuableHeader', () => { expect(avatarEl.find(GlAvatarLabeled).find(GlIcon).exists()).toBe(false); }); + it('renders tast status text when `taskCompletionStatus` prop is defined', () => { + let taskStatusEl = wrapper.findByTestId('task-status'); + + expect(taskStatusEl.exists()).toBe(true); + expect(taskStatusEl.text()).toContain('0 of 5 tasks completed'); + + const wrapperSingleTask = createComponent({ + ...issuableHeaderProps, + taskCompletionStatus: { + completedCount: 0, + count: 1, + }, + }); + + taskStatusEl = wrapperSingleTask.findByTestId('task-status'); + + expect(taskStatusEl.text()).toContain('0 of 1 task completed'); + + wrapperSingleTask.destroy(); + }); + it('renders sidebar toggle button', () => { const toggleButtonEl = wrapper.findByTestId('sidebar-toggle'); diff --git a/spec/frontend/issuable_show/components/issuable_show_root_spec.js b/spec/frontend/issuable_show/components/issuable_show_root_spec.js index 3e3778492d2..b4c125f4910 100644 --- a/spec/frontend/issuable_show/components/issuable_show_root_spec.js +++ b/spec/frontend/issuable_show/components/issuable_show_root_spec.js @@ -54,6 +54,7 @@ describe('IssuableShowRoot', () => { editFormVisible, descriptionPreviewPath, descriptionHelpPath, + taskCompletionStatus, } = mockIssuableShowProps; const { blocked, confidential, createdAt, author } = mockIssuable; @@ -72,6 +73,7 @@ describe('IssuableShowRoot', () => { confidential, createdAt, author, + taskCompletionStatus, }); expect(issuableHeader.find('.issuable-status-box').text()).toContain('Open'); expect(issuableHeader.find('.detail-page-header-actions button.js-close').exists()).toBe( @@ -111,6 +113,26 @@ describe('IssuableShowRoot', () => { expect(wrapper.emitted('edit-issuable')).toBeTruthy(); }); + it('component emits `task-list-update-success` event bubbled via issuable-body', () => { + const issuableBody = wrapper.find(IssuableBody); + const eventParam = { + foo: 'bar', + }; + + issuableBody.vm.$emit('task-list-update-success', eventParam); + + expect(wrapper.emitted('task-list-update-success')).toBeTruthy(); + expect(wrapper.emitted('task-list-update-success')[0]).toEqual([eventParam]); + }); + + it('component emits `task-list-update-failure` event bubbled via issuable-body', () => { + const issuableBody = wrapper.find(IssuableBody); + + issuableBody.vm.$emit('task-list-update-failure'); + + expect(wrapper.emitted('task-list-update-failure')).toBeTruthy(); + }); + it('component emits `sidebar-toggle` event bubbled via issuable-sidebar', () => { const issuableSidebar = wrapper.find(IssuableSidebar); |