Commit 92b40a04 authored by Miguel Rincon's avatar Miguel Rincon

Merge branch 'justin_ho-remove-legacy-mount-component-helper-in-sidebar' into 'master'

Replace `mountComponent` helper in `vue_shared/components/sidebar` specs

See merge request gitlab-org/gitlab!73459
parents 245b3021 ad8017de
......@@ -40,7 +40,7 @@ export default {
</script>
<template>
<div v-gl-tooltip.left.viewport :class="containerClass" :title="tooltipText" @click="click">
<div v-gl-tooltip.left.viewport="tooltipText" :class="containerClass" @click="click">
<gl-icon v-if="showIcon" name="calendar" />
<slot>
<span> {{ text }} </span>
......
......@@ -43,12 +43,7 @@ export default {
</script>
<template>
<div
v-gl-tooltip.left.viewport
:title="labelsList"
class="sidebar-collapsed-icon"
@click="handleClick"
>
<div v-gl-tooltip.left.viewport="labelsList" class="sidebar-collapsed-icon" @click="handleClick">
<gl-icon name="labels" />
<span>{{ labels.length }}</span>
</div>
......
import Vue from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import collapsedCalendarIcon from '~/vue_shared/components/sidebar/collapsed_calendar_icon.vue';
import { shallowMount } from '@vue/test-utils';
import { GlIcon } from '@gitlab/ui';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
describe('collapsedCalendarIcon', () => {
let vm;
beforeEach(() => {
const CollapsedCalendarIcon = Vue.extend(collapsedCalendarIcon);
vm = mountComponent(CollapsedCalendarIcon, {
import CollapsedCalendarIcon from '~/vue_shared/components/sidebar/collapsed_calendar_icon.vue';
describe('CollapsedCalendarIcon', () => {
let wrapper;
const defaultProps = {
containerClass: 'test-class',
text: 'text',
tooltipText: 'tooltip text',
showIcon: false,
};
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(CollapsedCalendarIcon, {
propsData: { ...defaultProps, ...props },
directives: {
GlTooltip: createMockDirective(),
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
const findGlIcon = () => wrapper.findComponent(GlIcon);
const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip');
it('adds class to container', () => {
expect(wrapper.classes()).toContain(defaultProps.containerClass);
});
it('does not render calendar icon when showIcon is false', () => {
expect(findGlIcon().exists()).toBe(false);
});
it('renders calendar icon when showIcon is true', () => {
createComponent({
props: { showIcon: true },
});
it('should add class to container', () => {
expect(vm.$el.classList.contains('test-class')).toEqual(true);
expect(findGlIcon().exists()).toBe(true);
});
it('should hide calendar icon if showIcon', () => {
expect(vm.$el.querySelector('[data-testid="calendar-icon"]')).toBeNull();
it('renders text', () => {
expect(wrapper.text()).toBe(defaultProps.text);
});
it('should render text', () => {
expect(vm.$el.querySelector('span').innerText.trim()).toEqual('text');
it('renders tooltipText as tooltip', () => {
expect(getTooltip().value).toBe(defaultProps.tooltipText);
});
it('should emit click event when container is clicked', () => {
const click = jest.fn();
vm.$on('click', click);
it('emits click event when container is clicked', async () => {
wrapper.trigger('click');
vm.$el.click();
await wrapper.vm.$nextTick();
expect(click).toHaveBeenCalled();
expect(wrapper.emitted('click')[0]).toBeDefined();
});
});
import Vue from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import collapsedGroupedDatePicker from '~/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue';
import { shallowMount } from '@vue/test-utils';
describe('collapsedGroupedDatePicker', () => {
let vm;
beforeEach(() => {
const CollapsedGroupedDatePicker = Vue.extend(collapsedGroupedDatePicker);
vm = mountComponent(CollapsedGroupedDatePicker, {
import CollapsedGroupedDatePicker from '~/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue';
import CollapsedCalendarIcon from '~/vue_shared/components/sidebar/collapsed_calendar_icon.vue';
describe('CollapsedGroupedDatePicker', () => {
let wrapper;
const defaultProps = {
showToggleSidebar: true,
};
const minDate = new Date('07/17/2016');
const maxDate = new Date('07/17/2017');
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(CollapsedGroupedDatePicker, {
propsData: { ...defaultProps, ...props },
});
});
};
describe('toggleCollapse events', () => {
beforeEach((done) => {
jest.spyOn(vm, 'toggleSidebar').mockImplementation(() => {});
vm.minDate = new Date('07/17/2016');
Vue.nextTick(done);
afterEach(() => {
wrapper.destroy();
});
const findCollapsedCalendarIcon = () => wrapper.findComponent(CollapsedCalendarIcon);
const findAllCollapsedCalendarIcons = () => wrapper.findAllComponents(CollapsedCalendarIcon);
describe('toggleCollapse events', () => {
it('should emit when collapsed-calendar-icon is clicked', () => {
vm.$el.querySelector('.sidebar-collapsed-icon').click();
createComponent();
findCollapsedCalendarIcon().trigger('click');
expect(vm.toggleSidebar).toHaveBeenCalled();
expect(wrapper.emitted('toggleCollapse')[0]).toBeDefined();
});
});
describe('minDate and maxDate', () => {
beforeEach((done) => {
vm.minDate = new Date('07/17/2016');
vm.maxDate = new Date('07/17/2017');
Vue.nextTick(done);
it('should render both collapsed-calendar-icon', () => {
createComponent({
props: {
minDate,
maxDate,
},
});
it('should render both collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
const icons = findAllCollapsedCalendarIcons();
expect(icons.length).toEqual(2);
expect(icons[0].innerText.trim()).toEqual('Jul 17 2016');
expect(icons[1].innerText.trim()).toEqual('Jul 17 2017');
expect(icons.length).toBe(2);
expect(icons.at(0).text()).toBe('Jul 17 2016');
expect(icons.at(1).text()).toBe('Jul 17 2017');
});
});
describe('minDate', () => {
beforeEach((done) => {
vm.minDate = new Date('07/17/2016');
Vue.nextTick(done);
it('should render minDate in collapsed-calendar-icon', () => {
createComponent({
props: {
minDate,
},
});
it('should render minDate in collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
const icons = findAllCollapsedCalendarIcons();
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('From Jul 17 2016');
expect(icons.length).toBe(1);
expect(icons.at(0).text()).toBe('From Jul 17 2016');
});
});
describe('maxDate', () => {
beforeEach((done) => {
vm.maxDate = new Date('07/17/2017');
Vue.nextTick(done);
});
it('should render maxDate in collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
createComponent({
props: {
maxDate,
},
});
const icons = findAllCollapsedCalendarIcons();
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('Until Jul 17 2017');
expect(icons.length).toBe(1);
expect(icons.at(0).text()).toBe('Until Jul 17 2017');
});
});
describe('no dates', () => {
beforeEach(() => {
createComponent();
});
it('should render None', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
const icons = findAllCollapsedCalendarIcons();
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('None');
expect(icons.length).toBe(1);
expect(icons.at(0).text()).toBe('None');
});
it('should have tooltip as `Start and due date`', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
const icons = findAllCollapsedCalendarIcons();
expect(icons[0].title).toBe('Start and due date');
expect(icons.at(0).props('tooltipText')).toBe('Start and due date');
});
});
});
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import DatePicker from '~/vue_shared/components/pikaday.vue';
import SidebarDatePicker from '~/vue_shared/components/sidebar/date_picker.vue';
......@@ -5,14 +6,8 @@ import SidebarDatePicker from '~/vue_shared/components/sidebar/date_picker.vue';
describe('SidebarDatePicker', () => {
let wrapper;
const mountComponent = (propsData = {}, data = {}) => {
if (wrapper) {
throw new Error('tried to call mountComponent without d');
}
const createComponent = (propsData = {}, data = {}) => {
wrapper = mount(SidebarDatePicker, {
stubs: {
DatePicker: true,
},
propsData,
data: () => data,
});
......@@ -20,87 +15,93 @@ describe('SidebarDatePicker', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findDatePicker = () => wrapper.findComponent(DatePicker);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findEditButton = () => wrapper.find('.title .btn-blank');
const findRemoveButton = () => wrapper.find('.value-content .btn-blank');
const findSidebarToggle = () => wrapper.find('.title .gutter-toggle');
const findValueContent = () => wrapper.find('.value-content');
it('should emit toggleCollapse when collapsed toggle sidebar is clicked', () => {
mountComponent();
createComponent();
wrapper.find('.issuable-sidebar-header .gutter-toggle').element.click();
wrapper.find('.issuable-sidebar-header .gutter-toggle').trigger('click');
expect(wrapper.emitted('toggleCollapse')).toEqual([[]]);
});
it('should render collapsed-calendar-icon', () => {
mountComponent();
createComponent();
expect(wrapper.find('.sidebar-collapsed-icon').element).toBeDefined();
expect(wrapper.find('.sidebar-collapsed-icon').exists()).toBe(true);
});
it('should render value when not editing', () => {
mountComponent();
createComponent();
expect(wrapper.find('.value-content').element).toBeDefined();
expect(findValueContent().exists()).toBe(true);
});
it('should render None if there is no selectedDate', () => {
mountComponent();
createComponent();
expect(wrapper.find('.value-content span').text().trim()).toEqual('None');
expect(findValueContent().text()).toBe('None');
});
it('should render date-picker when editing', () => {
mountComponent({}, { editing: true });
createComponent({}, { editing: true });
expect(wrapper.find(DatePicker).element).toBeDefined();
expect(findDatePicker().exists()).toBe(true);
});
it('should render label', () => {
const label = 'label';
mountComponent({ label });
expect(wrapper.find('.title').text().trim()).toEqual(label);
createComponent({ label });
expect(wrapper.find('.title').text()).toBe(label);
});
it('should render loading-icon when isLoading', () => {
mountComponent({ isLoading: true });
expect(wrapper.find('.gl-spinner').element).toBeDefined();
createComponent({ isLoading: true });
expect(findLoadingIcon().exists()).toBe(true);
});
describe('editable', () => {
beforeEach(() => {
mountComponent({ editable: true });
createComponent({ editable: true });
});
it('should render edit button', () => {
expect(wrapper.find('.title .btn-blank').text().trim()).toEqual('Edit');
expect(findEditButton().text()).toBe('Edit');
});
it('should enable editing when edit button is clicked', async () => {
wrapper.find('.title .btn-blank').element.click();
findEditButton().trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.vm.editing).toEqual(true);
expect(wrapper.vm.editing).toBe(true);
});
});
it('should render date if selectedDate', () => {
mountComponent({ selectedDate: new Date('07/07/2017') });
createComponent({ selectedDate: new Date('07/07/2017') });
expect(wrapper.find('.value-content strong').text().trim()).toEqual('Jul 7, 2017');
expect(wrapper.find('.value-content strong').text()).toBe('Jul 7, 2017');
});
describe('selectedDate and editable', () => {
beforeEach(() => {
mountComponent({ selectedDate: new Date('07/07/2017'), editable: true });
createComponent({ selectedDate: new Date('07/07/2017'), editable: true });
});
it('should render remove button if selectedDate and editable', () => {
expect(wrapper.find('.value-content .btn-blank').text().trim()).toEqual('remove');
expect(findRemoveButton().text()).toBe('remove');
});
it('should emit saveDate with null when remove button is clicked', () => {
wrapper.find('.value-content .btn-blank').element.click();
findRemoveButton().trigger('click');
expect(wrapper.emitted('saveDate')).toEqual([[null]]);
});
......@@ -108,15 +109,15 @@ describe('SidebarDatePicker', () => {
describe('showToggleSidebar', () => {
beforeEach(() => {
mountComponent({ showToggleSidebar: true });
createComponent({ showToggleSidebar: true });
});
it('should render toggle-sidebar when showToggleSidebar', () => {
expect(wrapper.find('.title .gutter-toggle').element).toBeDefined();
expect(findSidebarToggle().exists()).toBe(true);
});
it('should emit toggleCollapse when toggle sidebar is clicked', () => {
wrapper.find('.title .gutter-toggle').element.click();
findSidebarToggle().trigger('click');
expect(wrapper.emitted('toggleCollapse')).toEqual([[]]);
});
......
import Vue from 'vue';
import { shallowMount } from '@vue/test-utils';
import { GlIcon } from '@gitlab/ui';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import DropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import dropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue';
import { mockCollapsedLabels as mockLabels, mockRegularLabel } from './mock_data';
import { mockCollapsedLabels as mockLabels } from './mock_data';
describe('DropdownValueCollapsedComponent', () => {
let wrapper;
const createComponent = (labels = mockLabels) => {
const Component = Vue.extend(dropdownValueCollapsedComponent);
const defaultProps = {
labels: [],
};
return mountComponent(Component, {
labels,
});
};
const mockManyLabels = [...mockLabels, ...mockLabels, ...mockLabels];
describe('DropdownValueCollapsedComponent', () => {
let vm;
beforeEach(() => {
vm = createComponent();
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(DropdownValueCollapsedComponent, {
propsData: { ...defaultProps, ...props },
directives: {
GlTooltip: createMockDirective(),
},
});
};
afterEach(() => {
vm.$destroy();
wrapper.destroy();
});
describe('computed', () => {
describe('labelsList', () => {
it('returns default text when `labels` prop is empty array', () => {
const vmEmptyLabels = createComponent([]);
const findGlIcon = () => wrapper.findComponent(GlIcon);
const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip');
expect(vmEmptyLabels.labelsList).toBe('Labels');
vmEmptyLabels.$destroy();
});
it('returns labels names separated by coma when `labels` prop has more than one item', () => {
const labels = mockLabels.concat(mockLabels);
const vmMoreLabels = createComponent(labels);
const expectedText = labels.map((label) => label.title).join(', ');
describe('template', () => {
it('renders tags icon element', () => {
createComponent();
expect(vmMoreLabels.labelsList).toBe(expectedText);
vmMoreLabels.$destroy();
expect(findGlIcon().exists()).toBe(true);
});
it('returns labels names separated by coma with remaining labels count and `and more` phrase when `labels` prop has more than five items', () => {
const mockMoreLabels = Object.assign([], mockLabels);
for (let i = 0; i < 6; i += 1) {
mockMoreLabels.unshift(mockLabels[0]);
}
it('emits onValueClick event on click', async () => {
createComponent();
const vmMoreLabels = createComponent(mockMoreLabels);
wrapper.trigger('click');
const expectedText = `${mockMoreLabels
.slice(0, 5)
.map((label) => label.title)
.join(', ')}, and ${mockMoreLabels.length - 5} more`;
await wrapper.vm.$nextTick();
expect(vmMoreLabels.labelsList).toBe(expectedText);
vmMoreLabels.$destroy();
expect(wrapper.emitted('onValueClick')[0]).toBeDefined();
});
it('returns first label name when `labels` prop has only one item present', () => {
const text = mockLabels.map((label) => label.title).join(', ');
expect(vm.labelsList).toBe(text);
});
});
});
describe('methods', () => {
describe('handleClick', () => {
it('emits onValueClick event on component', () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.handleClick();
expect(vm.$emit).toHaveBeenCalledWith('onValueClick');
});
describe.each`
scenario | labels | expectedResult | expectedText
${'`labels` is empty'} | ${[]} | ${'default text'} | ${'Labels'}
${'`labels` has 1 item'} | ${[mockRegularLabel]} | ${'label name'} | ${'Foo Label'}
${'`labels` has 2 items'} | ${mockLabels} | ${'comma separated label names'} | ${'Foo Label, Foo::Bar'}
${'`labels` has more than 5 items'} | ${mockManyLabels} | ${'comma separated label names with "and more" phrase'} | ${'Foo Label, Foo::Bar, Foo Label, Foo::Bar, Foo Label, and 1 more'}
`('when $scenario', ({ labels, expectedResult, expectedText }) => {
beforeEach(() => {
createComponent({
props: {
labels,
},
});
});
describe('template', () => {
it('renders component container element with tooltip`', () => {
expect(vm.$el.title).toBe(vm.labelsList);
it('renders labels count', () => {
expect(wrapper.text()).toBe(`${labels.length}`);
});
it('renders tags icon element', () => {
expect(vm.$el.querySelector('[data-testid="labels-icon"]')).not.toBeNull();
it(`renders "${expectedResult}" as tooltip`, () => {
expect(getTooltip().value).toBe(expectedText);
});
it('renders labels count', () => {
expect(vm.$el.querySelector('span').innerText.trim()).toBe(`${vm.labels.length}`);
});
});
});
import Vue from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import toggleSidebar from '~/vue_shared/components/sidebar/toggle_sidebar.vue';
describe('toggleSidebar', () => {
let vm;
beforeEach(() => {
const ToggleSidebar = Vue.extend(toggleSidebar);
vm = mountComponent(ToggleSidebar, {
import { GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import ToggleSidebar from '~/vue_shared/components/sidebar/toggle_sidebar.vue';
describe('ToggleSidebar', () => {
let wrapper;
const defaultProps = {
collapsed: true,
};
const createComponent = ({ mountFn = shallowMount, props = {} } = {}) => {
wrapper = mountFn(ToggleSidebar, {
propsData: { ...defaultProps, ...props },
});
};
afterEach(() => {
wrapper.destroy();
});
const findGlButton = () => wrapper.findComponent(GlButton);
it('should render the "chevron-double-lg-left" icon when collapsed', () => {
expect(vm.$el.querySelector('[data-testid="chevron-double-lg-left-icon"]')).not.toBeNull();
createComponent();
expect(findGlButton().props('icon')).toBe('chevron-double-lg-left');
});
it('should render the "chevron-double-lg-right" icon when expanded', async () => {
vm.collapsed = false;
await Vue.nextTick();
expect(vm.$el.querySelector('[data-testid="chevron-double-lg-right-icon"]')).not.toBeNull();
createComponent({ props: { collapsed: false } });
expect(findGlButton().props('icon')).toBe('chevron-double-lg-right');
});
it('should emit toggle event when button clicked', () => {
const toggle = jest.fn();
vm.$on('toggle', toggle);
vm.$el.click();
it('should emit toggle event when button clicked', async () => {
createComponent({ mountFn: mount });
findGlButton().trigger('click');
await wrapper.vm.$nextTick();
expect(toggle).toHaveBeenCalled();
expect(wrapper.emitted('toggle')[0]).toBeDefined();
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment