Commit 7d58f0e0 authored by Kushal Pandya's avatar Kushal Pandya

LabelsSelect Base Component

parent 8c9094cb
<script>
import LabelsSelect from '~/labels_select';
import LoadingIcon from '../../loading_icon.vue';
import DropdownTitle from './dropdown_title.vue';
import DropdownValue from './dropdown_value.vue';
import DropdownValueCollapsed from './dropdown_value_collapsed.vue';
import DropdownButton from './dropdown_button.vue';
import DropdownHiddenInput from './dropdown_hidden_input.vue';
import DropdownHeader from './dropdown_header.vue';
import DropdownSearchInput from './dropdown_search_input.vue';
import DropdownFooter from './dropdown_footer.vue';
import DropdownCreateLabel from './dropdown_create_label.vue';
export default {
components: {
LoadingIcon,
DropdownTitle,
DropdownValue,
DropdownValueCollapsed,
DropdownButton,
DropdownHiddenInput,
DropdownHeader,
DropdownSearchInput,
DropdownFooter,
DropdownCreateLabel,
},
props: {
showCreate: {
type: Boolean,
required: false,
default: false,
},
abilityName: {
type: String,
required: true,
},
context: {
type: Object,
required: true,
},
namespace: {
type: String,
required: false,
default: '',
},
updatePath: {
type: String,
required: false,
default: '',
},
labelsPath: {
type: String,
required: true,
},
labelsWebUrl: {
type: String,
required: false,
default: '',
},
labelFilterBasePath: {
type: String,
required: false,
default: '',
},
canEdit: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
hiddenInputName() {
return this.showCreate ? `${this.abilityName}[label_names][]` : 'label_id[]';
},
},
mounted() {
this.labelsDropdown = new LabelsSelect(this.$refs.dropdownButton, {
handleClick: this.handleClick,
});
},
methods: {
handleClick(label) {
this.$emit('onLabelClick', label);
},
},
};
</script>
<template>
<div class="block labels">
<dropdown-value-collapsed
v-if="showCreate"
:labels="context.labels"
/>
<dropdown-title
:can-edit="canEdit"
/>
<dropdown-value
:labels="context.labels"
:label-filter-base-path="labelFilterBasePath"
>
<slot></slot>
</dropdown-value>
<div
v-if="canEdit"
class="selectbox"
style="display: none;"
>
<dropdown-hidden-input
v-for="label in context.labels"
:key="label.id"
:name="hiddenInputName"
:label="label"
/>
<div class="dropdown">
<dropdown-button
:ability-name="abilityName"
:field-name="hiddenInputName"
:update-path="updatePath"
:labels-path="labelsPath"
:namespace="namespace"
:labels="context.labels"
:show-extra-options="!showCreate"
/>
<div
class="dropdown-menu dropdown-select dropdown-menu-paging
dropdown-menu-labels dropdown-menu-selectable"
>
<div class="dropdown-page-one">
<dropdown-header v-if="showCreate" />
<dropdown-search-input/>
<div class="dropdown-content"></div>
<div class="dropdown-loading">
<loading-icon />
</div>
<dropdown-footer
v-if="showCreate"
:labels-web-url="labelsWebUrl"
/>
</div>
<dropdown-create-label
v-if="showCreate"
/>
</div>
</div>
</div>
</div>
</template>
import Vue from 'vue';
import LabelsSelect from '~/labels_select';
import baseComponent from '~/vue_shared/components/sidebar/labels_select/base.vue';
import { mockConfig, mockLabels } from './mock_data';
import mountComponent from '../../../../helpers/vue_mount_component_helper';
const createComponent = (config = mockConfig) => {
const Component = Vue.extend(baseComponent);
return mountComponent(Component, config);
};
describe('BaseComponent', () => {
let vm;
beforeEach(() => {
vm = createComponent();
});
afterEach(() => {
vm.$destroy();
});
describe('computed', () => {
describe('hiddenInputName', () => {
it('returns correct string when showCreate prop is `true`', () => {
expect(vm.hiddenInputName).toBe('issue[label_names][]');
});
it('returns correct string when showCreate prop is `false`', () => {
const mockConfigNonEditable = Object.assign({}, mockConfig, { showCreate: false });
const vmNonEditable = createComponent(mockConfigNonEditable);
expect(vmNonEditable.hiddenInputName).toBe('label_id[]');
vmNonEditable.$destroy();
});
});
});
describe('methods', () => {
describe('handleClick', () => {
it('emits onLabelClick event with label and list of labels as params', () => {
spyOn(vm, '$emit');
vm.handleClick(mockLabels[0]);
expect(vm.$emit).toHaveBeenCalledWith('onLabelClick', mockLabels[0]);
});
});
});
describe('mounted', () => {
it('creates LabelsSelect object and assigns it to `labelsDropdon` as prop', () => {
expect(vm.labelsDropdown instanceof LabelsSelect).toBe(true);
});
});
describe('template', () => {
it('renders component container element with classes `block labels`', () => {
expect(vm.$el.classList.contains('block')).toBe(true);
expect(vm.$el.classList.contains('labels')).toBe(true);
});
it('renders `.selectbox` element', () => {
expect(vm.$el.querySelector('.selectbox')).not.toBeNull();
expect(vm.$el.querySelector('.selectbox').getAttribute('style')).toBe('display: none;');
});
it('renders `.dropdown` element', () => {
expect(vm.$el.querySelector('.dropdown')).not.toBeNull();
});
it('renders `.dropdown-menu` element', () => {
const dropdownMenuEl = vm.$el.querySelector('.dropdown-menu');
expect(dropdownMenuEl).not.toBeNull();
expect(dropdownMenuEl.querySelector('.dropdown-page-one')).not.toBeNull();
expect(dropdownMenuEl.querySelector('.dropdown-content')).not.toBeNull();
expect(dropdownMenuEl.querySelector('.dropdown-loading')).not.toBeNull();
});
});
});
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