Commit 1ed0e173 authored by Mark Florian's avatar Mark Florian

Merge branch 'fix-null-value-dropdown-multiple' into 'master'

Do not add initial empty value in create cluster dropdown

See merge request gitlab-org/gitlab!26927
parents fcf55205 ae83e133
<script> <script>
import { isNil } from 'lodash';
import $ from 'jquery'; import $ from 'jquery';
import { GlIcon } from '@gitlab/ui'; import { GlIcon } from '@gitlab/ui';
import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue'; import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue';
import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
const toArray = value => [].concat(value); const toArray = value => (isNil(value) ? [] : [].concat(value));
const itemsProp = (items, prop) => items.map(item => item[prop]); const itemsProp = (items, prop) => items.map(item => item[prop]);
const defaultSearchFn = (searchQuery, labelProp) => item => const defaultSearchFn = (searchQuery, labelProp) => item =>
item[labelProp].toLowerCase().indexOf(searchQuery) > -1; item[labelProp].toLowerCase().indexOf(searchQuery) > -1;
......
...@@ -7,22 +7,22 @@ import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue ...@@ -7,22 +7,22 @@ import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue
import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue'; import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue';
describe('ClusterFormDropdown', () => { describe('ClusterFormDropdown', () => {
let vm; let wrapper;
const firstItem = { name: 'item 1', value: 1 }; const firstItem = { name: 'item 1', value: 1 };
const secondItem = { name: 'item 2', value: 2 }; const secondItem = { name: 'item 2', value: 2 };
const items = [firstItem, secondItem, { name: 'item 3', value: 3 }]; const items = [firstItem, secondItem, { name: 'item 3', value: 3 }];
beforeEach(() => { beforeEach(() => {
vm = shallowMount(ClusterFormDropdown); wrapper = shallowMount(ClusterFormDropdown);
}); });
afterEach(() => vm.destroy()); afterEach(() => wrapper.destroy());
describe('when initial value is provided', () => { describe('when initial value is provided', () => {
it('sets selectedItem to initial value', () => { it('sets selectedItem to initial value', () => {
vm.setProps({ items, value: secondItem.value }); wrapper.setProps({ items, value: secondItem.value });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('toggleText')).toEqual(secondItem.name); expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(secondItem.name);
}); });
}); });
}); });
...@@ -31,28 +31,29 @@ describe('ClusterFormDropdown', () => { ...@@ -31,28 +31,29 @@ describe('ClusterFormDropdown', () => {
it('displays placeholder text', () => { it('displays placeholder text', () => {
const placeholder = 'placeholder'; const placeholder = 'placeholder';
vm.setProps({ placeholder }); wrapper.setProps({ placeholder });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('toggleText')).toEqual(placeholder); expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(placeholder);
}); });
}); });
}); });
describe('when an item is selected', () => { describe('when an item is selected', () => {
beforeEach(() => { beforeEach(() => {
vm.setProps({ items }); wrapper.setProps({ items });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
vm.findAll('.js-dropdown-item') wrapper
.findAll('.js-dropdown-item')
.at(1) .at(1)
.trigger('click'); .trigger('click');
return vm.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
}); });
it('emits input event with selected item', () => { it('emits input event with selected item', () => {
expect(vm.emitted('input')[0]).toEqual([secondItem.value]); expect(wrapper.emitted('input')[0]).toEqual([secondItem.value]);
}); });
}); });
...@@ -60,37 +61,54 @@ describe('ClusterFormDropdown', () => { ...@@ -60,37 +61,54 @@ describe('ClusterFormDropdown', () => {
const value = [1]; const value = [1];
beforeEach(() => { beforeEach(() => {
vm.setProps({ items, multiple: true, value }); wrapper.setProps({ items, multiple: true, value });
return vm.vm return wrapper.vm
.$nextTick() .$nextTick()
.then(() => { .then(() => {
vm.findAll('.js-dropdown-item') wrapper
.findAll('.js-dropdown-item')
.at(0) .at(0)
.trigger('click'); .trigger('click');
return vm.vm.$nextTick(); return wrapper.vm.$nextTick();
}) })
.then(() => { .then(() => {
vm.findAll('.js-dropdown-item') wrapper
.findAll('.js-dropdown-item')
.at(1) .at(1)
.trigger('click'); .trigger('click');
return vm.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
}); });
it('emits input event with an array of selected items', () => { it('emits input event with an array of selected items', () => {
expect(vm.emitted('input')[1]).toEqual([[firstItem.value, secondItem.value]]); expect(wrapper.emitted('input')[1]).toEqual([[firstItem.value, secondItem.value]]);
}); });
}); });
describe('when multiple items can be selected', () => { describe('when multiple items can be selected', () => {
beforeEach(() => { beforeEach(() => {
vm.setProps({ items, multiple: true, value: firstItem.value }); wrapper.setProps({ items, multiple: true, value: firstItem.value });
return vm.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
it('displays a checked GlIcon next to the item', () => { it('displays a checked GlIcon next to the item', () => {
expect(vm.find(GlIcon).is('.invisible')).toBe(false); expect(wrapper.find(GlIcon).is('.invisible')).toBe(false);
expect(vm.find(GlIcon).props('name')).toBe('mobile-issue-close'); expect(wrapper.find(GlIcon).props('name')).toBe('mobile-issue-close');
});
});
describe('when multiple values can be selected and initial value is null', () => {
it('emits input event with an array of a single selected item', () => {
wrapper.setProps({ items, multiple: true, value: null });
return wrapper.vm.$nextTick().then(() => {
wrapper
.findAll('.js-dropdown-item')
.at(0)
.trigger('click');
expect(wrapper.emitted('input')[0]).toEqual([[firstItem.value]]);
});
}); });
}); });
...@@ -101,20 +119,20 @@ describe('ClusterFormDropdown', () => { ...@@ -101,20 +119,20 @@ describe('ClusterFormDropdown', () => {
const currentValue = 1; const currentValue = 1;
const customLabelItems = [{ [labelProperty]: label, value: currentValue }]; const customLabelItems = [{ [labelProperty]: label, value: currentValue }];
vm.setProps({ labelProperty, items: customLabelItems, value: currentValue }); wrapper.setProps({ labelProperty, items: customLabelItems, value: currentValue });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('toggleText')).toEqual(label); expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(label);
}); });
}); });
}); });
describe('when loading', () => { describe('when loading', () => {
it('dropdown button isLoading', () => { it('dropdown button isLoading', () => {
vm.setProps({ loading: true }); wrapper.setProps({ loading: true });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('isLoading')).toBe(true); expect(wrapper.find(DropdownButton).props('isLoading')).toBe(true);
}); });
}); });
}); });
...@@ -123,20 +141,20 @@ describe('ClusterFormDropdown', () => { ...@@ -123,20 +141,20 @@ describe('ClusterFormDropdown', () => {
it('uses loading text as toggle button text', () => { it('uses loading text as toggle button text', () => {
const loadingText = 'loading text'; const loadingText = 'loading text';
vm.setProps({ loading: true, loadingText }); wrapper.setProps({ loading: true, loadingText });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('toggleText')).toEqual(loadingText); expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(loadingText);
}); });
}); });
}); });
describe('when disabled', () => { describe('when disabled', () => {
it('dropdown button isDisabled', () => { it('dropdown button isDisabled', () => {
vm.setProps({ disabled: true }); wrapper.setProps({ disabled: true });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('isDisabled')).toBe(true); expect(wrapper.find(DropdownButton).props('isDisabled')).toBe(true);
}); });
}); });
}); });
...@@ -145,20 +163,20 @@ describe('ClusterFormDropdown', () => { ...@@ -145,20 +163,20 @@ describe('ClusterFormDropdown', () => {
it('uses disabled text as toggle button text', () => { it('uses disabled text as toggle button text', () => {
const disabledText = 'disabled text'; const disabledText = 'disabled text';
vm.setProps({ disabled: true, disabledText }); wrapper.setProps({ disabled: true, disabledText });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).props('toggleText')).toBe(disabledText); expect(wrapper.find(DropdownButton).props('toggleText')).toBe(disabledText);
}); });
}); });
}); });
describe('when has errors', () => { describe('when has errors', () => {
it('sets border-danger class selector to dropdown toggle', () => { it('sets border-danger class selector to dropdown toggle', () => {
vm.setProps({ hasErrors: true }); wrapper.setProps({ hasErrors: true });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownButton).classes('border-danger')).toBe(true); expect(wrapper.find(DropdownButton).classes('border-danger')).toBe(true);
}); });
}); });
}); });
...@@ -167,10 +185,10 @@ describe('ClusterFormDropdown', () => { ...@@ -167,10 +185,10 @@ describe('ClusterFormDropdown', () => {
it('displays error message', () => { it('displays error message', () => {
const errorMessage = 'error message'; const errorMessage = 'error message';
vm.setProps({ hasErrors: true, errorMessage }); wrapper.setProps({ hasErrors: true, errorMessage });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find('.js-eks-dropdown-error-message').text()).toEqual(errorMessage); expect(wrapper.find('.js-eks-dropdown-error-message').text()).toEqual(errorMessage);
}); });
}); });
}); });
...@@ -179,10 +197,10 @@ describe('ClusterFormDropdown', () => { ...@@ -179,10 +197,10 @@ describe('ClusterFormDropdown', () => {
it('displays empty text', () => { it('displays empty text', () => {
const emptyText = 'error message'; const emptyText = 'error message';
vm.setProps({ items: [], emptyText }); wrapper.setProps({ items: [], emptyText });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find('.js-empty-text').text()).toEqual(emptyText); expect(wrapper.find('.js-empty-text').text()).toEqual(emptyText);
}); });
}); });
}); });
...@@ -190,34 +208,36 @@ describe('ClusterFormDropdown', () => { ...@@ -190,34 +208,36 @@ describe('ClusterFormDropdown', () => {
it('displays search field placeholder', () => { it('displays search field placeholder', () => {
const searchFieldPlaceholder = 'Placeholder'; const searchFieldPlaceholder = 'Placeholder';
vm.setProps({ searchFieldPlaceholder }); wrapper.setProps({ searchFieldPlaceholder });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.find(DropdownSearchInput).props('placeholderText')).toEqual(searchFieldPlaceholder); expect(wrapper.find(DropdownSearchInput).props('placeholderText')).toEqual(
searchFieldPlaceholder,
);
}); });
}); });
it('it filters results by search query', () => { it('it filters results by search query', () => {
const searchQuery = secondItem.name; const searchQuery = secondItem.name;
vm.setProps({ items }); wrapper.setProps({ items });
vm.setData({ searchQuery }); wrapper.setData({ searchQuery });
return vm.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(vm.findAll('.js-dropdown-item').length).toEqual(1); expect(wrapper.findAll('.js-dropdown-item').length).toEqual(1);
expect(vm.find('.js-dropdown-item').text()).toEqual(secondItem.name); expect(wrapper.find('.js-dropdown-item').text()).toEqual(secondItem.name);
}); });
}); });
it('focuses dropdown search input when dropdown is displayed', () => { it('focuses dropdown search input when dropdown is displayed', () => {
const dropdownEl = vm.find('.dropdown').element; const dropdownEl = wrapper.find('.dropdown').element;
expect(vm.find(DropdownSearchInput).props('focused')).toBe(false); expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(false);
$(dropdownEl).trigger('shown.bs.dropdown'); $(dropdownEl).trigger('shown.bs.dropdown');
return vm.vm.$nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(vm.find(DropdownSearchInput).props('focused')).toBe(true); expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(true);
}); });
}); });
}); });
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