From 45482d5a2704da7fabe4ccf07f85d9be6e0a791a Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 27 Sep 2019 12:06:07 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../confidential_issue_sidebar_spec.js.snap | 229 +++++++++++++++++++++ .../sidebar/__snapshots__/todo_spec.js.snap | 37 ++++ .../sidebar/confidential_issue_sidebar_spec.js | 110 +++++----- spec/frontend/sidebar/todo_spec.js | 88 ++++++++ spec/javascripts/sidebar/todo_spec.js | 171 --------------- 5 files changed, 413 insertions(+), 222 deletions(-) create mode 100644 spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap create mode 100644 spec/frontend/sidebar/__snapshots__/todo_spec.js.snap create mode 100644 spec/frontend/sidebar/todo_spec.js delete mode 100644 spec/javascripts/sidebar/todo_spec.js (limited to 'spec') diff --git a/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap b/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap new file mode 100644 index 00000000000..32d67120183 --- /dev/null +++ b/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap @@ -0,0 +1,229 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Confidential Issue Sidebar Block renders for isConfidential = false and isEditable = false 1`] = ` +
+ + +
+ + Confidentiality + + +
+ + +
+`; + +exports[`Confidential Issue Sidebar Block renders for isConfidential = false and isEditable = true 1`] = ` +
+ + +
+ + Confidentiality + + + + Edit + + +
+ + +
+`; + +exports[`Confidential Issue Sidebar Block renders for isConfidential = true and isEditable = false 1`] = ` +
+ + +
+ + Confidentiality + + +
+ + +
+`; + +exports[`Confidential Issue Sidebar Block renders for isConfidential = true and isEditable = true 1`] = ` +
+ + +
+ + Confidentiality + + + + Edit + + +
+ + +
+`; diff --git a/spec/frontend/sidebar/__snapshots__/todo_spec.js.snap b/spec/frontend/sidebar/__snapshots__/todo_spec.js.snap new file mode 100644 index 00000000000..e680c917611 --- /dev/null +++ b/spec/frontend/sidebar/__snapshots__/todo_spec.js.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SidebarTodo template renders component container element with proper data attributes 1`] = ` + +`; diff --git a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js index 549010075db..0fd50c0e989 100644 --- a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js +++ b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js @@ -1,77 +1,85 @@ -import Vue from 'vue'; -import confidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue'; +import { shallowMount } from '@vue/test-utils'; +import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue'; import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; +import EditForm from '~/sidebar/components/confidential/edit_form.vue'; describe('Confidential Issue Sidebar Block', () => { - let vm1; - let vm2; + let wrapper; - beforeEach(() => { - const Component = Vue.extend(confidentialIssueSidebar); + const createComponent = propsData => { const service = { update: () => Promise.resolve(true), }; - vm1 = new Component({ + wrapper = shallowMount(ConfidentialIssueSidebar, { propsData: { - isConfidential: true, - isEditable: true, service, + ...propsData, }, - }).$mount(); - - vm2 = new Component({ - propsData: { - isConfidential: false, - isEditable: false, - service, - }, - }).$mount(); - }); - - it('shows if confidential and/or editable', () => { - expect(vm1.$el.innerHTML.includes('Edit')).toBe(true); - - expect(vm1.$el.innerHTML.includes('This issue is confidential')).toBe(true); - - expect(vm2.$el.innerHTML.includes('Not confidential')).toBe(true); + sync: false, + }); + }; + + it.each` + isConfidential | isEditable + ${false} | ${false} + ${false} | ${true} + ${true} | ${false} + ${true} | ${true} + `( + 'renders for isConfidential = $isConfidential and isEditable = $isEditable', + ({ isConfidential, isEditable }) => { + createComponent({ + isConfidential, + isEditable, + }); + + expect(wrapper.element).toMatchSnapshot(); + }, + ); + + afterEach(() => { + wrapper.destroy(); }); - it('displays the edit form when editable', () => { - expect(vm1.edit).toBe(false); + describe('if editable', () => { + beforeEach(() => { + createComponent({ + isConfidential: true, + isEditable: true, + }); + }); - vm1.$el.querySelector('.confidential-edit').click(); + it('displays the edit form when editable', () => { + wrapper.setData({ edit: false }); - expect(vm1.edit).toBe(true); + wrapper.find({ ref: 'editLink' }).trigger('click'); - return Vue.nextTick().then(() => { - expect(vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.')).toBe( - true, - ); + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.find(EditForm).exists()).toBe(true); + }); }); - }); - - it('displays the edit form when opened from collapsed state', () => { - expect(vm1.edit).toBe(false); - vm1.$el.querySelector('.sidebar-collapsed-icon').click(); + it('displays the edit form when opened from collapsed state', () => { + wrapper.setData({ edit: false }); - expect(vm1.edit).toBe(true); + wrapper.find({ ref: 'collapseIcon' }).trigger('click'); - return Vue.nextTick().then(() => { - expect(vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.')).toBe( - true, - ); + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.find(EditForm).exists()).toBe(true); + }); }); - }); - it('tracks the event when "Edit" is clicked', () => { - const spy = mockTracking('_category_', vm1.$el, jest.spyOn); - triggerEvent('.confidential-edit'); + it('tracks the event when "Edit" is clicked', () => { + const spy = mockTracking('_category_', wrapper.element, jest.spyOn); + + const editLink = wrapper.find({ ref: 'editLink' }); + triggerEvent(editLink.element); - expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', { - label: 'right_sidebar', - property: 'confidentiality', + expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', { + label: 'right_sidebar', + property: 'confidentiality', + }); }); }); }); diff --git a/spec/frontend/sidebar/todo_spec.js b/spec/frontend/sidebar/todo_spec.js new file mode 100644 index 00000000000..b6cf799126b --- /dev/null +++ b/spec/frontend/sidebar/todo_spec.js @@ -0,0 +1,88 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLoadingIcon } from '@gitlab/ui'; + +import SidebarTodos from '~/sidebar/components/todo_toggle/todo.vue'; +import Icon from '~/vue_shared/components/icon.vue'; + +const defaultProps = { + issuableId: 1, + issuableType: 'epic', +}; + +describe('SidebarTodo', () => { + let wrapper; + + const createComponent = (props = {}) => { + wrapper = shallowMount(SidebarTodos, { + sync: false, + propsData: { + ...defaultProps, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + it.each` + state | classes + ${false} | ${['btn', 'btn-default', 'btn-todo', 'issuable-header-btn', 'float-right']} + ${true} | ${['btn-blank', 'btn-todo', 'sidebar-collapsed-icon', 'dont-change-state']} + `('returns todo button classes for when `collapsed` prop is `$state`', ({ state, classes }) => { + createComponent({ collapsed: state }); + expect(wrapper.find('button').classes()).toStrictEqual(classes); + }); + + it.each` + isTodo | iconClass | label | icon + ${false} | ${''} | ${'Add a To Do'} | ${'todo-add'} + ${true} | ${'todo-undone'} | ${'Mark as done'} | ${'todo-done'} + `( + 'renders proper button when `isTodo` prop is `$isTodo`', + ({ isTodo, iconClass, label, icon }) => { + createComponent({ isTodo }); + + expect(wrapper.find(Icon).props('cssClasses')).toStrictEqual(iconClass); + expect(wrapper.find(Icon).props('name')).toStrictEqual(icon); + expect(wrapper.find('button').text()).toBe(label); + }, + ); + + describe('template', () => { + it('emits `toggleTodo` event when clicked on button', () => { + createComponent(); + wrapper.find('button').trigger('click'); + + expect(wrapper.emitted().toggleTodo).toBeTruthy(); + }); + + it('renders component container element with proper data attributes', () => { + createComponent({ + issuableId: 1, + issuableType: 'epic', + }); + + expect(wrapper.element).toMatchSnapshot(); + }); + + it('renders button label element when `collapsed` prop is `false`', () => { + createComponent({ collapsed: false }); + + expect(wrapper.find('span.issuable-todo-inner').text()).toBe('Mark as done'); + }); + + it('renders button icon when `collapsed` prop is `true`', () => { + createComponent({ collapsed: true }); + + expect(wrapper.find(Icon).props('name')).toBe('todo-done'); + }); + + it('renders loading icon when `isActionActive` prop is true', () => { + createComponent({ isActionActive: true }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + }); +}); diff --git a/spec/javascripts/sidebar/todo_spec.js b/spec/javascripts/sidebar/todo_spec.js deleted file mode 100644 index e7abd19c865..00000000000 --- a/spec/javascripts/sidebar/todo_spec.js +++ /dev/null @@ -1,171 +0,0 @@ -import Vue from 'vue'; - -import SidebarTodos from '~/sidebar/components/todo_toggle/todo.vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; - -const createComponent = ({ - issuableId = 1, - issuableType = 'epic', - isTodo, - isActionActive, - collapsed, -}) => { - const Component = Vue.extend(SidebarTodos); - - return mountComponent(Component, { - issuableId, - issuableType, - isTodo, - isActionActive, - collapsed, - }); -}; - -describe('SidebarTodo', () => { - let vm; - - beforeEach(() => { - vm = createComponent({}); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('computed', () => { - describe('buttonClasses', () => { - it('returns todo button classes for when `collapsed` prop is `false`', () => { - expect(vm.buttonClasses).toBe('btn btn-default btn-todo issuable-header-btn float-right'); - }); - - it('returns todo button classes for when `collapsed` prop is `true`', done => { - vm.collapsed = true; - Vue.nextTick() - .then(() => { - expect(vm.buttonClasses).toBe( - 'btn-blank btn-todo sidebar-collapsed-icon dont-change-state', - ); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('buttonLabel', () => { - it('returns todo button text for marking todo as done when `isTodo` prop is `true`', () => { - expect(vm.buttonLabel).toBe('Mark as done'); - }); - - it('returns todo button text for add todo when `isTodo` prop is `false`', done => { - vm.isTodo = false; - Vue.nextTick() - .then(() => { - expect(vm.buttonLabel).toBe('Add a To Do'); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('collapsedButtonIconClasses', () => { - it('returns collapsed button icon class when `isTodo` prop is `true`', () => { - expect(vm.collapsedButtonIconClasses).toBe('todo-undone'); - }); - - it('returns empty string when `isTodo` prop is `false`', done => { - vm.isTodo = false; - Vue.nextTick() - .then(() => { - expect(vm.collapsedButtonIconClasses).toBe(''); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('collapsedButtonIcon', () => { - it('returns button icon name when `isTodo` prop is `true`', () => { - expect(vm.collapsedButtonIcon).toBe('todo-done'); - }); - - it('returns button icon name when `isTodo` prop is `false`', done => { - vm.isTodo = false; - Vue.nextTick() - .then(() => { - expect(vm.collapsedButtonIcon).toBe('todo-add'); - }) - .then(done) - .catch(done.fail); - }); - }); - }); - - describe('methods', () => { - describe('handleButtonClick', () => { - it('emits `toggleTodo` event on component', () => { - spyOn(vm, '$emit'); - vm.handleButtonClick(); - - expect(vm.$emit).toHaveBeenCalledWith('toggleTodo'); - }); - }); - }); - - describe('template', () => { - it('renders component container element', () => { - const dataAttributes = { - issuableId: '1', - issuableType: 'epic', - originalTitle: '', - placement: 'left', - container: 'body', - boundary: 'viewport', - }; - - expect(vm.$el.nodeName).toBe('BUTTON'); - - const elDataAttrs = vm.$el.dataset; - Object.keys(elDataAttrs).forEach(attr => { - expect(elDataAttrs[attr]).toBe(dataAttributes[attr]); - }); - }); - - it('check button label computed property', () => { - expect(vm.buttonLabel).toEqual('Mark as done'); - }); - - it('renders button label element when `collapsed` prop is `false`', () => { - const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner'); - - expect(buttonLabelEl).not.toBeNull(); - expect(buttonLabelEl.innerText.trim()).toBe('Mark as done'); - }); - - it('renders button icon when `collapsed` prop is `true`', done => { - vm.collapsed = true; - Vue.nextTick() - .then(() => { - const buttonIconEl = vm.$el.querySelector('svg'); - - expect(buttonIconEl).not.toBeNull(); - expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain( - 'todo-done', - ); - }) - .then(done) - .catch(done.fail); - }); - - it('renders loading icon when `isActionActive` prop is true', done => { - vm.isActionActive = true; - Vue.nextTick() - .then(() => { - const loadingEl = vm.$el.querySelector('span.loading-container'); - - expect(loadingEl).not.toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - }); -}); -- cgit v1.2.3