mirror of https://github.com/rancher/dashboard.git
fix labeledselect getOptionLabel to use reduce prop when labels change (#8176)
* fix labeledselect getOptionLabel to use reduce prop when labels change * Add unit tests --------- Co-authored-by: cnotv <giuseppe.leo@suse.com>
This commit is contained in:
parent
5f91d46762
commit
21167e1dc9
|
|
@ -5,6 +5,7 @@ import { get } from '@shell/utils/object';
|
|||
import { LabeledTooltip } from '@components/LabeledTooltip';
|
||||
import VueSelectOverrides from '@shell/mixins/vue-select-overrides';
|
||||
import { onClickOption, calculatePosition } from '@shell/utils/select';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
export default {
|
||||
name: 'LabeledSelect',
|
||||
|
|
@ -152,10 +153,13 @@ export default {
|
|||
const isOutdated = !this.options.find(opt => option[this.optionLabel] === opt[this.optionLabel]);
|
||||
|
||||
if (isOutdated && this.options) {
|
||||
const newOption = this.options.find(opt => option[this.optionKey] === opt[this.optionKey]);
|
||||
const label = get(newOption, this.optionLabel);
|
||||
const newOption = this.options.find(opt => isEqual(this.reduce(option), this.reduce(opt)));
|
||||
|
||||
return this.localizedLabel ? this.$store.getters['i18n/t'](label) || label : label;
|
||||
if (newOption) {
|
||||
const label = get(newOption, this.optionLabel);
|
||||
|
||||
return this.localizedLabel ? this.$store.getters['i18n/t'](label) || label : label;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.$attrs['get-option-label']) {
|
||||
|
|
|
|||
|
|
@ -2,42 +2,137 @@ import { mount } from '@vue/test-utils';
|
|||
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
||||
|
||||
describe('component: LabeledSelect', () => {
|
||||
it('should automatically pick option for given value', () => {
|
||||
const label = 'Foo';
|
||||
const value = 'foo';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [
|
||||
{ label, value },
|
||||
],
|
||||
}
|
||||
describe('should display correct label', () => {
|
||||
it('given an existing value and option', () => {
|
||||
const label = 'Foo';
|
||||
const value = 'foo';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [
|
||||
{ label, value },
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(label);
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(label);
|
||||
});
|
||||
it('using value as label if no options', () => {
|
||||
const value = 'foo';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [],
|
||||
}
|
||||
});
|
||||
|
||||
it('should update the displayed label if options are changed', async() => {
|
||||
const newLabel = 'Baz';
|
||||
const oldLabel = 'Foo';
|
||||
const value = 'foo';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [
|
||||
{ label: oldLabel, value },
|
||||
],
|
||||
}
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(value);
|
||||
});
|
||||
|
||||
await wrapper.setProps({
|
||||
options: [
|
||||
{ label: newLabel, value },
|
||||
]
|
||||
it('using custom key as label for option object', () => {
|
||||
const value = 'foo';
|
||||
const label = 'Foo';
|
||||
const customLabelKey = 'bananas';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
optionLabel: customLabelKey,
|
||||
options: [{
|
||||
[customLabelKey]: label,
|
||||
value
|
||||
}],
|
||||
}
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(label);
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(newLabel);
|
||||
it('translating localized cases', () => {
|
||||
const value = 'foo';
|
||||
const translation = 'bananas';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
localizedLabel: true,
|
||||
value,
|
||||
options: [{ label: 'whatever', value }],
|
||||
},
|
||||
mocks: { $store: { getters: { 'i18n/t': () => translation } } }
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(translation);
|
||||
});
|
||||
|
||||
describe('updating the value on options change', () => {
|
||||
it('using new label', async() => {
|
||||
const value = 'foo';
|
||||
const oldLabel = 'Foo';
|
||||
const newLabel = 'Baz';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [
|
||||
{ label: oldLabel, value },
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
await wrapper.setProps({
|
||||
options: [
|
||||
{ label: newLabel, value },
|
||||
]
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(newLabel);
|
||||
});
|
||||
|
||||
it('using values only and no labels', async() => {
|
||||
const value = 'foo';
|
||||
const newValue = 'bananas';
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
options: [value],
|
||||
}
|
||||
});
|
||||
|
||||
await wrapper.setProps({ options: [newValue] });
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(value);
|
||||
});
|
||||
|
||||
it('using translated value', async() => {
|
||||
const value = 'foo';
|
||||
const oldLabel = 'Foo';
|
||||
const newLabel = 'Baz';
|
||||
const translation = 'bananas';
|
||||
const i18nMap: Record<string, string> = { [newLabel]: translation };
|
||||
const wrapper = mount(LabeledSelect, {
|
||||
propsData: {
|
||||
value,
|
||||
localizedLabel: true,
|
||||
options: [
|
||||
{ label: oldLabel, value },
|
||||
],
|
||||
},
|
||||
mocks: { $store: { getters: { 'i18n/t': (text: string) => i18nMap[text] } } }
|
||||
});
|
||||
|
||||
await wrapper.setProps({
|
||||
options: [
|
||||
{ label: newLabel, value },
|
||||
]
|
||||
});
|
||||
|
||||
// Component is from a library and class is not going to be changed
|
||||
expect(wrapper.find('.vs__selected').text()).toBe(translation);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue