Commit 8188d09f authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'ps-fix-search-term-case-sensitivity-namespace-select' into 'master'

Fix search term case sensitivity for transfer namespace

See merge request gitlab-org/gitlab!79595
parents 36d22a85 d8256211
......@@ -43,9 +43,6 @@ export default {
};
},
computed: {
selectedNamespaceId() {
return this.selectedId;
},
disableSubmitButton() {
return this.isPaidGroup || !this.selectedId;
},
......
......@@ -4,6 +4,10 @@ import { parseBoolean } from '~/lib/utils/common_utils';
import TransferGroupForm, { i18n } from './components/transfer_group_form.vue';
const prepareGroups = (rawGroups) => {
if (!rawGroups) {
return { group: [] };
}
const group = JSON.parse(rawGroups).map(({ id, text: humanName }) => ({
id,
humanName,
......@@ -22,7 +26,7 @@ export default () => {
targetFormId = null,
buttonText: confirmButtonText = '',
groupName = '',
parentGroups = [],
parentGroups,
isPaidGroup,
} = el.dataset;
......
......@@ -16,8 +16,13 @@ export const i18n = {
USERS: __('Users'),
};
const filterByName = (data, searchTerm = '') =>
data.filter((d) => d.humanName.toLowerCase().includes(searchTerm));
const filterByName = (data, searchTerm = '') => {
if (!searchTerm) {
return data;
}
return data.filter((d) => d.humanName.toLowerCase().includes(searchTerm.toLowerCase()));
};
export default {
name: 'NamespaceSelect',
......@@ -85,7 +90,15 @@ export default {
},
filteredEmptyNamespaceTitle() {
const { includeEmptyNamespace, emptyNamespaceTitle, searchTerm } = this;
return includeEmptyNamespace && emptyNamespaceTitle.toLowerCase().includes(searchTerm);
if (!includeEmptyNamespace) {
return '';
}
if (!searchTerm) {
return emptyNamespaceTitle;
}
return emptyNamespaceTitle.toLowerCase().includes(searchTerm.toLowerCase());
},
},
methods: {
......
import { nextTick } from 'vue';
import { GlDropdown, GlDropdownItem, GlDropdownSectionHeader } from '@gitlab/ui';
import { GlDropdown, GlDropdownItem, GlDropdownSectionHeader, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NamespaceSelect, {
i18n,
......@@ -7,6 +7,10 @@ import NamespaceSelect, {
} from '~/vue_shared/components/namespace_select/namespace_select.vue';
import { user, group, namespaces } from './mock_data';
const FLAT_NAMESPACES = [...group, ...user];
const EMPTY_NAMESPACE_TITLE = 'Empty namespace TEST';
const EMPTY_NAMESPACE_ITEM = { id: EMPTY_NAMESPACE_ID, humanName: EMPTY_NAMESPACE_TITLE };
describe('Namespace Select', () => {
let wrapper;
......@@ -16,67 +20,97 @@ describe('Namespace Select', () => {
data: namespaces,
...props,
},
stubs: {
// We have to "full" mount GlDropdown so that slot children will render
GlDropdown,
},
});
const wrappersText = (arr) => arr.wrappers.map((w) => w.text());
const flatNamespaces = () => [...group, ...user];
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownAttributes = (attr) => findDropdown().attributes(attr);
const selectedDropdownItemText = () => findDropdownAttributes('text');
const findDropdownText = () => findDropdown().props('text');
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findDropdownItemsTexts = () => findDropdownItems().wrappers.map((x) => x.text());
const findSectionHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
beforeEach(() => {
wrapper = createComponent();
});
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const search = (term) => findSearchBox().vm.$emit('input', term);
afterEach(() => {
wrapper.destroy();
});
it('renders the dropdown', () => {
expect(findDropdown().exists()).toBe(true);
});
describe('default', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('can override the default text', () => {
const textOverride = 'Select an option';
wrapper = createComponent({ defaultText: textOverride });
expect(selectedDropdownItemText()).toBe(textOverride);
});
it('renders the dropdown', () => {
expect(findDropdown().exists()).toBe(true);
});
it('renders each dropdown item', () => {
const items = findDropdownItems().wrappers;
expect(items).toHaveLength(flatNamespaces().length);
});
it('renders each dropdown item', () => {
expect(findDropdownItemsTexts()).toEqual(FLAT_NAMESPACES.map((x) => x.humanName));
});
it('renders the human name for each item', () => {
const dropdownItems = wrappersText(findDropdownItems());
const flatNames = flatNamespaces().map(({ humanName }) => humanName);
expect(dropdownItems).toEqual(flatNames);
});
it('renders default dropdown text', () => {
expect(findDropdownText()).toBe(i18n.DEFAULT_TEXT);
});
it('sets the initial dropdown text', () => {
expect(selectedDropdownItemText()).toBe(i18n.DEFAULT_TEXT);
it('splits group and user namespaces', () => {
const headers = findSectionHeaders();
expect(wrappersText(headers)).toEqual([i18n.GROUPS, i18n.USERS]);
});
it('does not render wrapper as full width', () => {
expect(findDropdown().attributes('block')).toBeUndefined();
});
});
it('splits group and user namespaces', () => {
const headers = findSectionHeaders();
expect(headers).toHaveLength(2);
expect(wrappersText(headers)).toEqual([i18n.GROUPS, i18n.USERS]);
it('with defaultText, it overrides dropdown text', () => {
const textOverride = 'Select an option';
wrapper = createComponent({ defaultText: textOverride });
expect(findDropdownText()).toBe(textOverride);
});
it('can hide the group / user headers', () => {
it('with includeHeaders=false, hides group/user headers', () => {
wrapper = createComponent({ includeHeaders: false });
expect(findSectionHeaders()).toHaveLength(0);
});
it('sets the dropdown to full width', () => {
expect(findDropdownAttributes('block')).toBeUndefined();
it('with fullWidth=true, sets the dropdown to full width', () => {
wrapper = createComponent({ fullWidth: true });
expect(findDropdownAttributes('block')).not.toBeUndefined();
expect(findDropdownAttributes('block')).toBe('true');
expect(findDropdown().attributes('block')).toBe('true');
});
describe('with search', () => {
it.each`
term | includeEmptyNamespace | expectedItems
${''} | ${false} | ${[...namespaces.group, ...namespaces.user]}
${'sub'} | ${false} | ${[namespaces.group[1]]}
${'User'} | ${false} | ${[...namespaces.user]}
${'User'} | ${true} | ${[...namespaces.user]}
${'namespace'} | ${true} | ${[EMPTY_NAMESPACE_ITEM, ...namespaces.user]}
`(
'with term=$term and includeEmptyNamespace=$includeEmptyNamespace, should show $expectedItems.length',
async ({ term, includeEmptyNamespace, expectedItems }) => {
wrapper = createComponent({
includeEmptyNamespace,
emptyNamespaceTitle: EMPTY_NAMESPACE_TITLE,
});
search(term);
await nextTick();
const expected = expectedItems.map((x) => x.humanName);
expect(findDropdownItemsTexts()).toEqual(expected);
},
);
});
describe('with a selected namespace', () => {
......@@ -84,11 +118,13 @@ describe('Namespace Select', () => {
const selectedItem = group[selectedGroupIndex];
beforeEach(() => {
wrapper = createComponent();
findDropdownItems().at(selectedGroupIndex).vm.$emit('click');
});
it('sets the dropdown text', () => {
expect(selectedDropdownItemText()).toBe(selectedItem.humanName);
expect(findDropdownText()).toBe(selectedItem.humanName);
});
it('emits the `select` event when a namespace is selected', () => {
......@@ -98,27 +134,35 @@ describe('Namespace Select', () => {
});
describe('with an empty namespace option', () => {
const emptyNamespaceTitle = 'No namespace selected';
beforeEach(async () => {
beforeEach(() => {
wrapper = createComponent({
includeEmptyNamespace: true,
emptyNamespaceTitle,
emptyNamespaceTitle: EMPTY_NAMESPACE_TITLE,
});
await nextTick();
});
it('includes the empty namespace', () => {
const first = findDropdownItems().at(0);
expect(first.text()).toBe(emptyNamespaceTitle);
expect(first.text()).toBe(EMPTY_NAMESPACE_TITLE);
});
it('emits the `select` event when a namespace is selected', () => {
findDropdownItems().at(0).vm.$emit('click');
expect(wrapper.emitted('select')).toEqual([
[{ id: EMPTY_NAMESPACE_ID, humanName: emptyNamespaceTitle }],
]);
expect(wrapper.emitted('select')).toEqual([[EMPTY_NAMESPACE_ITEM]]);
});
it.each`
desc | term | shouldShow
${'should hide empty option'} | ${'group'} | ${false}
${'should show empty option'} | ${'Empty'} | ${true}
`('when search for $term, $desc', async ({ term, shouldShow }) => {
search(term);
await nextTick();
expect(findDropdownItemsTexts().includes(EMPTY_NAMESPACE_TITLE)).toBe(shouldShow);
});
});
});
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