summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js')
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js129
1 files changed, 120 insertions, 9 deletions
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
index 05508d14209..73dbecadd89 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, mount } from '@vue/test-utils';
import {
GlFilteredSearch,
GlButtonGroup,
@@ -16,13 +16,16 @@ import RecentSearchesService from '~/filtered_search/services/recent_searches_se
import { mockAvailableTokens, mockSortOptions, mockHistoryItems } from './mock_data';
const createComponent = ({
+ shallow = true,
namespace = 'gitlab-org/gitlab-test',
recentSearchesStorageKey = 'requirements',
tokens = mockAvailableTokens,
- sortOptions = mockSortOptions,
+ sortOptions,
searchInputPlaceholder = 'Filter requirements',
-} = {}) =>
- shallowMount(FilteredSearchBarRoot, {
+} = {}) => {
+ const mountMethod = shallow ? shallowMount : mount;
+
+ return mountMethod(FilteredSearchBarRoot, {
propsData: {
namespace,
recentSearchesStorageKey,
@@ -31,12 +34,13 @@ const createComponent = ({
searchInputPlaceholder,
},
});
+};
describe('FilteredSearchBarRoot', () => {
let wrapper;
beforeEach(() => {
- wrapper = createComponent();
+ wrapper = createComponent({ sortOptions: mockSortOptions });
});
afterEach(() => {
@@ -44,23 +48,38 @@ describe('FilteredSearchBarRoot', () => {
});
describe('data', () => {
- it('initializes `filterValue`, `selectedSortOption` and `selectedSortDirection` data props', () => {
+ it('initializes `filterValue`, `selectedSortOption` and `selectedSortDirection` data props and displays the sort dropdown', () => {
expect(wrapper.vm.filterValue).toEqual([]);
expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[0].sortDirection.descending);
expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending);
+ expect(wrapper.contains(GlButtonGroup)).toBe(true);
+ expect(wrapper.contains(GlButton)).toBe(true);
+ expect(wrapper.contains(GlDropdown)).toBe(true);
+ expect(wrapper.contains(GlDropdownItem)).toBe(true);
+ });
+
+ it('does not initialize `selectedSortOption` and `selectedSortDirection` when `sortOptions` is not applied and hides the sort dropdown', () => {
+ const wrapperNoSort = createComponent();
+
+ expect(wrapperNoSort.vm.filterValue).toEqual([]);
+ expect(wrapperNoSort.vm.selectedSortOption).toBe(undefined);
+ expect(wrapperNoSort.contains(GlButtonGroup)).toBe(false);
+ expect(wrapperNoSort.contains(GlButton)).toBe(false);
+ expect(wrapperNoSort.contains(GlDropdown)).toBe(false);
+ expect(wrapperNoSort.contains(GlDropdownItem)).toBe(false);
});
});
describe('computed', () => {
describe('tokenSymbols', () => {
it('returns a map containing type and symbols from `tokens` prop', () => {
- expect(wrapper.vm.tokenSymbols).toEqual({ author_username: '@' });
+ expect(wrapper.vm.tokenSymbols).toEqual({ author_username: '@', label_name: '~' });
});
});
describe('tokenTitles', () => {
it('returns a map containing type and title from `tokens` prop', () => {
- expect(wrapper.vm.tokenTitles).toEqual({ author_username: 'Author' });
+ expect(wrapper.vm.tokenTitles).toEqual({ author_username: 'Author', label_name: 'Label' });
});
});
@@ -99,6 +118,29 @@ describe('FilteredSearchBarRoot', () => {
expect(wrapper.vm.sortDirectionTooltip).toBe('Sort direction: Descending');
});
});
+
+ describe('filteredRecentSearches', () => {
+ it('returns array of recent searches filtering out any string type (unsupported) items', async () => {
+ wrapper.setData({
+ recentSearches: [{ foo: 'bar' }, 'foo'],
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.filteredRecentSearches).toHaveLength(1);
+ expect(wrapper.vm.filteredRecentSearches[0]).toEqual({ foo: 'bar' });
+ });
+
+ it('returns undefined when recentSearchesStorageKey prop is not set on component', async () => {
+ wrapper.setProps({
+ recentSearchesStorageKey: '',
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.filteredRecentSearches).not.toBeDefined();
+ });
+ });
});
describe('watchers', () => {
@@ -139,6 +181,46 @@ describe('FilteredSearchBarRoot', () => {
});
});
+ describe('removeQuotesEnclosure', () => {
+ const mockFilters = [
+ {
+ type: 'author_username',
+ value: {
+ data: 'root',
+ operator: '=',
+ },
+ },
+ {
+ type: 'label_name',
+ value: {
+ data: '"Documentation Update"',
+ operator: '=',
+ },
+ },
+ 'foo',
+ ];
+
+ it('returns filter array with unescaped strings for values which have spaces', () => {
+ expect(wrapper.vm.removeQuotesEnclosure(mockFilters)).toEqual([
+ {
+ type: 'author_username',
+ value: {
+ data: 'root',
+ operator: '=',
+ },
+ },
+ {
+ type: 'label_name',
+ value: {
+ data: 'Documentation Update',
+ operator: '=',
+ },
+ },
+ 'foo',
+ ]);
+ });
+ });
+
describe('handleSortOptionClick', () => {
it('emits component event `onSort` with selected sort by value', () => {
wrapper.vm.handleSortOptionClick(mockSortOptions[1]);
@@ -172,9 +254,12 @@ describe('FilteredSearchBarRoot', () => {
describe('handleHistoryItemSelected', () => {
it('emits `onFilter` event with provided filters param', () => {
+ jest.spyOn(wrapper.vm, 'removeQuotesEnclosure');
+
wrapper.vm.handleHistoryItemSelected(mockHistoryItems[0]);
expect(wrapper.emitted('onFilter')[0]).toEqual([mockHistoryItems[0]]);
+ expect(wrapper.vm.removeQuotesEnclosure).toHaveBeenCalledWith(mockHistoryItems[0]);
});
});
@@ -233,10 +318,21 @@ describe('FilteredSearchBarRoot', () => {
});
});
+ it('calls `blurSearchInput` method to remove focus from filter input field', () => {
+ jest.spyOn(wrapper.vm, 'blurSearchInput');
+
+ wrapper.find(GlFilteredSearch).vm.$emit('submit', mockFilters);
+
+ expect(wrapper.vm.blurSearchInput).toHaveBeenCalled();
+ });
+
it('emits component event `onFilter` with provided filters param', () => {
+ jest.spyOn(wrapper.vm, 'removeQuotesEnclosure');
+
wrapper.vm.handleFilterSubmit(mockFilters);
expect(wrapper.emitted('onFilter')[0]).toEqual([mockFilters]);
+ expect(wrapper.vm.removeQuotesEnclosure).toHaveBeenCalledWith(mockFilters);
});
});
});
@@ -260,13 +356,28 @@ describe('FilteredSearchBarRoot', () => {
expect(glFilteredSearchEl.props('historyItems')).toEqual(mockHistoryItems);
});
+ it('renders search history items dropdown with formatting done using token symbols', async () => {
+ const wrapperFullMount = createComponent({ sortOptions: mockSortOptions, shallow: false });
+ wrapperFullMount.vm.recentSearchesStore.addRecentSearch(mockHistoryItems[0]);
+
+ await wrapperFullMount.vm.$nextTick();
+
+ const searchHistoryItemsEl = wrapperFullMount.findAll(
+ '.gl-search-box-by-click-menu .gl-search-box-by-click-history-item',
+ );
+
+ expect(searchHistoryItemsEl.at(0).text()).toBe('Author := @tobyLabel := ~Bug"duo"');
+
+ wrapperFullMount.destroy();
+ });
+
it('renders sort dropdown component', () => {
expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
expect(wrapper.find(GlDropdown).exists()).toBe(true);
expect(wrapper.find(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
});
- it('renders dropdown items', () => {
+ it('renders sort dropdown items', () => {
const dropdownItemsEl = wrapper.findAll(GlDropdownItem);
expect(dropdownItemsEl).toHaveLength(mockSortOptions.length);