2020-03-04 15:08:09 +00:00
|
|
|
import Vuex from 'vuex';
|
|
|
|
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
|
|
|
|
2020-05-05 12:09:31 +00:00
|
|
|
import { GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui';
|
2020-03-04 15:08:09 +00:00
|
|
|
import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue';
|
|
|
|
|
|
|
|
import labelSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store';
|
|
|
|
|
|
|
|
import { mockConfig, mockSuggestedColors } from './mock_data';
|
|
|
|
|
|
|
|
const localVue = createLocalVue();
|
|
|
|
localVue.use(Vuex);
|
|
|
|
|
|
|
|
const createComponent = (initialState = mockConfig) => {
|
|
|
|
const store = new Vuex.Store(labelSelectModule());
|
|
|
|
|
|
|
|
store.dispatch('setInitialState', initialState);
|
|
|
|
|
|
|
|
return shallowMount(DropdownContentsCreateView, {
|
|
|
|
localVue,
|
|
|
|
store,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('DropdownContentsCreateView', () => {
|
|
|
|
let wrapper;
|
|
|
|
const colors = Object.keys(mockSuggestedColors).map(color => ({
|
|
|
|
[color]: mockSuggestedColors[color],
|
|
|
|
}));
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
gon.suggested_label_colors = mockSuggestedColors;
|
|
|
|
wrapper = createComponent();
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('computed', () => {
|
|
|
|
describe('disableCreate', () => {
|
|
|
|
it('returns `true` when label title and color is not defined', () => {
|
|
|
|
expect(wrapper.vm.disableCreate).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns `true` when `labelCreateInProgress` is true', () => {
|
|
|
|
wrapper.setData({
|
|
|
|
labelTitle: 'Foo',
|
|
|
|
selectedColor: '#ff0000',
|
|
|
|
});
|
|
|
|
wrapper.vm.$store.dispatch('requestCreateLabel');
|
|
|
|
|
|
|
|
return wrapper.vm.$nextTick(() => {
|
|
|
|
expect(wrapper.vm.disableCreate).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns `false` when label title and color is defined and create request is not already in progress', () => {
|
|
|
|
wrapper.setData({
|
|
|
|
labelTitle: 'Foo',
|
|
|
|
selectedColor: '#ff0000',
|
|
|
|
});
|
|
|
|
|
|
|
|
return wrapper.vm.$nextTick(() => {
|
|
|
|
expect(wrapper.vm.disableCreate).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('suggestedColors', () => {
|
|
|
|
it('returns array of color objects containing color code and name', () => {
|
|
|
|
colors.forEach((color, index) => {
|
|
|
|
expect(wrapper.vm.suggestedColors[index]).toEqual(expect.objectContaining(color));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('methods', () => {
|
|
|
|
describe('getColorCode', () => {
|
|
|
|
it('returns color code from color object', () => {
|
|
|
|
expect(wrapper.vm.getColorCode(colors[0])).toBe(Object.keys(colors[0]).pop());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('getColorName', () => {
|
|
|
|
it('returns color name from color object', () => {
|
|
|
|
expect(wrapper.vm.getColorName(colors[0])).toBe(Object.values(colors[0]).pop());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('handleColorClick', () => {
|
|
|
|
it('sets provided `color` param to `selectedColor` prop', () => {
|
|
|
|
wrapper.vm.handleColorClick(colors[0]);
|
|
|
|
|
|
|
|
expect(wrapper.vm.selectedColor).toBe(Object.keys(colors[0]).pop());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('handleCreateClick', () => {
|
|
|
|
it('calls action `createLabel` with object containing `labelTitle` & `selectedColor`', () => {
|
|
|
|
jest.spyOn(wrapper.vm, 'createLabel').mockImplementation();
|
|
|
|
wrapper.setData({
|
|
|
|
labelTitle: 'Foo',
|
|
|
|
selectedColor: '#ff0000',
|
|
|
|
});
|
|
|
|
|
|
|
|
wrapper.vm.handleCreateClick();
|
|
|
|
|
|
|
|
return wrapper.vm.$nextTick(() => {
|
|
|
|
expect(wrapper.vm.createLabel).toHaveBeenCalledWith(
|
|
|
|
expect.objectContaining({
|
|
|
|
title: 'Foo',
|
|
|
|
color: '#ff0000',
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('template', () => {
|
|
|
|
it('renders component container element with class "labels-select-contents-create"', () => {
|
|
|
|
expect(wrapper.attributes('class')).toContain('labels-select-contents-create');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders dropdown back button element', () => {
|
|
|
|
const backBtnEl = wrapper
|
|
|
|
.find('.dropdown-title')
|
2020-05-05 12:09:31 +00:00
|
|
|
.findAll(GlButton)
|
2020-03-04 15:08:09 +00:00
|
|
|
.at(0);
|
|
|
|
|
|
|
|
expect(backBtnEl.exists()).toBe(true);
|
|
|
|
expect(backBtnEl.attributes('aria-label')).toBe('Go back');
|
2020-05-05 12:09:31 +00:00
|
|
|
expect(backBtnEl.props('icon')).toBe('arrow-left');
|
2020-03-04 15:08:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('renders dropdown title element', () => {
|
|
|
|
const headerEl = wrapper.find('.dropdown-title > span');
|
|
|
|
|
|
|
|
expect(headerEl.exists()).toBe(true);
|
|
|
|
expect(headerEl.text()).toBe('Create label');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders dropdown close button element', () => {
|
|
|
|
const closeBtnEl = wrapper
|
|
|
|
.find('.dropdown-title')
|
2020-05-05 12:09:31 +00:00
|
|
|
.findAll(GlButton)
|
2020-03-04 15:08:09 +00:00
|
|
|
.at(1);
|
|
|
|
|
|
|
|
expect(closeBtnEl.exists()).toBe(true);
|
|
|
|
expect(closeBtnEl.attributes('aria-label')).toBe('Close');
|
2020-05-05 12:09:31 +00:00
|
|
|
expect(closeBtnEl.props('icon')).toBe('close');
|
2020-03-04 15:08:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('renders label title input element', () => {
|
|
|
|
const titleInputEl = wrapper.find('.dropdown-input').find(GlFormInput);
|
|
|
|
|
|
|
|
expect(titleInputEl.exists()).toBe(true);
|
|
|
|
expect(titleInputEl.attributes('placeholder')).toBe('Name new label');
|
|
|
|
expect(titleInputEl.attributes('autofocus')).toBe('true');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders color block element for all suggested colors', () => {
|
|
|
|
const colorBlocksEl = wrapper.find('.dropdown-content').findAll(GlLink);
|
|
|
|
|
|
|
|
colorBlocksEl.wrappers.forEach((colorBlock, index) => {
|
|
|
|
expect(colorBlock.attributes('style')).toContain('background-color');
|
|
|
|
expect(colorBlock.attributes('title')).toBe(Object.values(colors[index]).pop());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders color input element', () => {
|
|
|
|
wrapper.setData({
|
|
|
|
selectedColor: '#ff0000',
|
|
|
|
});
|
|
|
|
|
|
|
|
return wrapper.vm.$nextTick(() => {
|
|
|
|
const colorPreviewEl = wrapper.find(
|
|
|
|
'.color-input-container > .dropdown-label-color-preview',
|
|
|
|
);
|
|
|
|
const colorInputEl = wrapper.find('.color-input-container').find(GlFormInput);
|
|
|
|
|
|
|
|
expect(colorPreviewEl.exists()).toBe(true);
|
|
|
|
expect(colorPreviewEl.attributes('style')).toContain('background-color');
|
|
|
|
expect(colorInputEl.exists()).toBe(true);
|
|
|
|
expect(colorInputEl.attributes('placeholder')).toBe('Use custom color #FF0000');
|
|
|
|
expect(colorInputEl.attributes('value')).toBe('#ff0000');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders create button element', () => {
|
|
|
|
const createBtnEl = wrapper
|
|
|
|
.find('.dropdown-actions')
|
2020-05-05 12:09:31 +00:00
|
|
|
.findAll(GlButton)
|
2020-03-04 15:08:09 +00:00
|
|
|
.at(0);
|
|
|
|
|
|
|
|
expect(createBtnEl.exists()).toBe(true);
|
|
|
|
expect(createBtnEl.text()).toContain('Create');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows gl-loading-icon within create button element when `labelCreateInProgress` is `true`', () => {
|
|
|
|
wrapper.vm.$store.dispatch('requestCreateLabel');
|
|
|
|
|
|
|
|
return wrapper.vm.$nextTick(() => {
|
|
|
|
const loadingIconEl = wrapper.find('.dropdown-actions').find(GlLoadingIcon);
|
|
|
|
|
|
|
|
expect(loadingIconEl.exists()).toBe(true);
|
|
|
|
expect(loadingIconEl.isVisible()).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders cancel button element', () => {
|
|
|
|
const cancelBtnEl = wrapper
|
|
|
|
.find('.dropdown-actions')
|
2020-05-05 12:09:31 +00:00
|
|
|
.findAll(GlButton)
|
2020-03-04 15:08:09 +00:00
|
|
|
.at(1);
|
|
|
|
|
|
|
|
expect(cancelBtnEl.exists()).toBe(true);
|
|
|
|
expect(cancelBtnEl.text()).toContain('Cancel');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|