Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-09 21:08:16 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-09 21:08:16 +0300
commit4da595a071829d1046f921e402f3978eeca15d93 (patch)
treef792687f66b20dacfd5f48cae4ba42961bddddd7 /spec/frontend/vue_shared/components/filtered_search_bar
parentc87924a358cab4283e48f7c3ffd27b07320b9f62 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/vue_shared/components/filtered_search_bar')
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js180
1 files changed, 176 insertions, 4 deletions
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
index dd9bf2ff598..9684d483c0d 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
@@ -1,12 +1,23 @@
-import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui';
+import {
+ GlFilteredSearchToken,
+ GlLoadingIcon,
+ GlFilteredSearchSuggestion,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
+} from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
mockRegularLabel,
mockLabels,
} from 'jest/vue_shared/components/sidebar/labels_select_vue/mock_data';
-import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ DEFAULT_NONE_ANY,
+ OPERATOR_IS,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
import {
getRecentlyUsedSuggestions,
setTokenValueToRecentlyUsed,
@@ -32,6 +43,7 @@ const defaultStubs = {
<div>
<slot name="view-token"></slot>
<slot name="view"></slot>
+ <slot name="suggestions"></slot>
</div>
`,
},
@@ -43,6 +55,7 @@ const defaultStubs = {
},
};
+const mockSuggestionListTestId = 'suggestion-list';
const defaultSlots = {
'view-token': `
<div class="js-view-token">${mockRegularLabel.title}</div>
@@ -52,6 +65,10 @@ const defaultSlots = {
`,
};
+const defaultScopedSlots = {
+ 'suggestions-list': `<div data-testid="${mockSuggestionListTestId}" :data-suggestions="JSON.stringify(props.suggestions)"></div>`,
+};
+
const mockProps = {
config: { ...mockLabelToken, recentSuggestionsStorageKey: mockStorageKey },
value: { data: '' },
@@ -62,8 +79,14 @@ const mockProps = {
getActiveTokenValue: (labels, data) => labels.find((label) => label.title === data),
};
-function createComponent({ props = {}, stubs = defaultStubs, slots = defaultSlots } = {}) {
- return mount(BaseToken, {
+function createComponent({
+ props = {},
+ stubs = defaultStubs,
+ slots = defaultSlots,
+ scopedSlots = defaultScopedSlots,
+ mountFn = mount,
+} = {}) {
+ return mountFn(BaseToken, {
propsData: {
...mockProps,
...props,
@@ -72,9 +95,14 @@ function createComponent({ props = {}, stubs = defaultStubs, slots = defaultSlot
portalName: 'fake target',
alignSuggestions: jest.fn(),
suggestionsListClass: () => 'custom-class',
+ filteredSearchSuggestionListInstance: {
+ register: jest.fn(),
+ unregister: jest.fn(),
+ },
},
stubs,
slots,
+ scopedSlots,
});
}
@@ -82,6 +110,9 @@ describe('BaseToken', () => {
let wrapper;
const findGlFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
+ const findMockSuggestionList = () => wrapper.findByTestId(mockSuggestionListTestId);
+ const getMockSuggestionListSuggestions = () =>
+ JSON.parse(findMockSuggestionList().attributes('data-suggestions'));
afterEach(() => {
wrapper.destroy();
@@ -136,6 +167,147 @@ describe('BaseToken', () => {
});
});
+ describe('suggestions', () => {
+ describe('with available suggestions', () => {
+ let mockSuggestions;
+
+ describe.each`
+ hasSuggestions | searchKey | shouldRenderSuggestions
+ ${true} | ${null} | ${true}
+ ${true} | ${'foo'} | ${true}
+ ${false} | ${null} | ${false}
+ `(
+ `when hasSuggestions is $hasSuggestions`,
+ ({ hasSuggestions, searchKey, shouldRenderSuggestions }) => {
+ beforeEach(async () => {
+ mockSuggestions = hasSuggestions ? [{ id: 'Foo' }] : [];
+ const props = { defaultSuggestions: [], suggestions: mockSuggestions };
+
+ getRecentlyUsedSuggestions.mockReturnValue([]);
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${shouldRenderSuggestions ? 'should' : 'should not'} render suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderSuggestions);
+
+ if (shouldRenderSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockSuggestions);
+ }
+ });
+ },
+ );
+ });
+
+ describe('with preloaded suggestions', () => {
+ const mockPreloadedSuggestions = [{ id: 'Foo' }, { id: 'Bar' }];
+
+ describe.each`
+ searchKey | shouldRenderPreloadedSuggestions
+ ${null} | ${true}
+ ${'foo'} | ${false}
+ `('when searchKey is $searchKey', ({ shouldRenderPreloadedSuggestions, searchKey }) => {
+ beforeEach(async () => {
+ const props = { preloadedSuggestions: mockPreloadedSuggestions };
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${
+ shouldRenderPreloadedSuggestions ? 'should' : 'should not'
+ } render preloaded suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderPreloadedSuggestions);
+
+ if (shouldRenderPreloadedSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockPreloadedSuggestions);
+ }
+ });
+ });
+ });
+
+ describe('with recent suggestions', () => {
+ let mockSuggestions;
+
+ describe.each`
+ searchKey | recentEnabled | shouldRenderRecentSuggestions
+ ${null} | ${true} | ${true}
+ ${'foo'} | ${true} | ${false}
+ ${null} | ${false} | ${false}
+ `(
+ 'when searchKey is $searchKey and recentEnabled is $recentEnabled',
+ ({ shouldRenderRecentSuggestions, recentEnabled, searchKey }) => {
+ beforeEach(async () => {
+ const props = { value: { data: '', operator: '=' }, defaultSuggestions: [] };
+
+ if (recentEnabled) {
+ mockSuggestions = [{ id: 'Foo' }, { id: 'Bar' }];
+ getRecentlyUsedSuggestions.mockReturnValue(mockSuggestions);
+ }
+
+ props.config = { recentSuggestionsStorageKey: recentEnabled ? mockStorageKey : null };
+
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${
+ shouldRenderRecentSuggestions ? 'should' : 'should not'
+ } render recent suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderRecentSuggestions);
+ expect(wrapper.findComponent(GlDropdownSectionHeader).exists()).toBe(
+ shouldRenderRecentSuggestions,
+ );
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(
+ shouldRenderRecentSuggestions,
+ );
+
+ if (shouldRenderRecentSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockSuggestions);
+ }
+ });
+ },
+ );
+ });
+
+ describe('with default suggestions', () => {
+ describe.each`
+ operator | shouldRenderFilteredSearchSuggestion
+ ${OPERATOR_IS} | ${true}
+ ${OPERATOR_IS_NOT} | ${false}
+ `('when operator is $operator', ({ shouldRenderFilteredSearchSuggestion, operator }) => {
+ beforeEach(() => {
+ const props = {
+ defaultSuggestions: DEFAULT_NONE_ANY,
+ value: { data: '', operator },
+ };
+
+ wrapper = createComponent({ props, mountFn: shallowMountExtended });
+ });
+
+ it(`${
+ shouldRenderFilteredSearchSuggestion ? 'should' : 'should not'
+ } render GlFilteredSearchSuggestion`, () => {
+ const filteredSearchSuggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion)
+ .wrappers;
+
+ if (shouldRenderFilteredSearchSuggestion) {
+ expect(filteredSearchSuggestions.map((c) => c.props())).toMatchObject(
+ DEFAULT_NONE_ANY.map((opt) => ({ value: opt.value })),
+ );
+ } else {
+ expect(filteredSearchSuggestions).toHaveLength(0);
+ }
+ });
+ });
+ });
+ });
+
describe('methods', () => {
describe('handleTokenValueSelected', () => {
const mockTokenValue = mockLabels[0];