diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/filtered_search_bar')
8 files changed, 280 insertions, 148 deletions
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js index b2ed79cd75a..93cddff8421 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js @@ -1,6 +1,9 @@ import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import AccessorUtilities from '~/lib/utils/accessor'; + +import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants'; + import { stripQuotes, uniqueTokens, @@ -210,6 +213,19 @@ describe('filterToQueryObject', () => { const res = filterToQueryObject({ [token]: value }); expect(res).toEqual(result); }); + + it.each([ + [FILTERED_SEARCH_TERM, [{ value: '' }], { search: '' }], + [FILTERED_SEARCH_TERM, [{ value: 'bar' }], { search: 'bar' }], + [FILTERED_SEARCH_TERM, [{ value: 'bar' }, { value: '' }], { search: 'bar' }], + [FILTERED_SEARCH_TERM, [{ value: 'bar' }, { value: 'baz' }], { search: 'bar baz' }], + ])( + 'when filteredSearchTermKey=search gathers filter values %s=%j into query object=%j', + (token, value, result) => { + const res = filterToQueryObject({ [token]: value }, { filteredSearchTermKey: 'search' }); + expect(res).toEqual(result); + }, + ); }); describe('urlQueryToFilter', () => { @@ -255,10 +271,61 @@ describe('urlQueryToFilter', () => { }, ], ['not[foo][]=bar', { foo: [{ value: 'bar', operator: '!=' }] }], - ])('gathers filter values %s into query object=%j', (query, result) => { - const res = urlQueryToFilter(query); - expect(res).toEqual(result); - }); + ['nop=1¬[nop]=2', {}, { filterNamesAllowList: ['foo'] }], + [ + 'foo[]=bar¬[foo][]=baz&nop=xxx¬[nop]=yyy', + { + foo: [ + { value: 'bar', operator: '=' }, + { value: 'baz', operator: '!=' }, + ], + }, + { filterNamesAllowList: ['foo'] }, + ], + [ + 'search=term&foo=bar', + { + [FILTERED_SEARCH_TERM]: [{ value: 'term' }], + foo: { value: 'bar', operator: '=' }, + }, + { filteredSearchTermKey: 'search' }, + ], + [ + 'search=my terms', + { + [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }], + }, + { filteredSearchTermKey: 'search' }, + ], + [ + 'search[]=my&search[]=terms', + { + [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }], + }, + { filteredSearchTermKey: 'search' }, + ], + [ + 'search=my+terms', + { + [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }], + }, + { filteredSearchTermKey: 'search', legacySpacesDecode: false }, + ], + [ + 'search=my terms&foo=bar&nop=xxx', + { + [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }], + foo: { value: 'bar', operator: '=' }, + }, + { filteredSearchTermKey: 'search', filterNamesAllowList: ['foo'] }, + ], + ])( + 'gathers filter values %s into query object=%j when options %j', + (query, result, options = undefined) => { + const res = urlQueryToFilter(query, options); + expect(res).toEqual(result); + }, + ); }); describe('getRecentlyUsedTokenValues', () => { diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js index 23e4deab9c1..134c6c8b929 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js @@ -65,8 +65,8 @@ export const mockMilestones = [ ]; export const mockEpics = [ - { iid: 1, id: 1, title: 'Foo' }, - { iid: 2, id: 2, title: 'Bar' }, + { iid: 1, id: 1, title: 'Foo', group_full_path: 'gitlab-org' }, + { iid: 2, id: 2, title: 'Bar', group_full_path: 'gitlab-org/design' }, ]; export const mockEmoji1 = { diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js index 05bad572472..4140ec09b4e 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js @@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter'; import testAction from 'helpers/vuex_action_helper'; import { mockBranches } from 'jest/vue_shared/components/filtered_search_bar/mock_data'; import Api from '~/api'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; +import createFlash from '~/flash'; import httpStatusCodes from '~/lib/utils/http_status'; import * as actions from '~/vue_shared/components/filtered_search_bar/store/modules/filters/actions'; import * as types from '~/vue_shared/components/filtered_search_bar/store/modules/filters/mutation_types'; diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js index 3b50927dcc6..f50eafdbc52 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js @@ -1,13 +1,13 @@ import { - GlFilteredSearchToken, GlFilteredSearchTokenSegment, GlFilteredSearchSuggestion, GlDropdownDivider, + GlAvatar, } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import waitForPromises from 'helpers/wait_for_promises'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; +import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { @@ -15,6 +15,7 @@ import { DEFAULT_NONE_ANY, } from '~/vue_shared/components/filtered_search_bar/constants'; import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue'; +import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue'; import { mockAuthorToken, mockAuthors } from '../mock_data'; @@ -29,12 +30,22 @@ const defaultStubs = { }, }; +const mockPreloadedAuthors = [ + { + id: 13, + name: 'Administrator', + username: 'root', + avatar_url: 'avatar/url', + }, +]; + function createComponent(options = {}) { const { config = mockAuthorToken, value = { data: '' }, active = false, stubs = defaultStubs, + data = {}, } = options; return mount(AuthorToken, { propsData: { @@ -47,132 +58,172 @@ function createComponent(options = {}) { alignSuggestions: function fakeAlignSuggestions() {}, suggestionsListClass: 'custom-class', }, + data() { + return { ...data }; + }, stubs, }); } describe('AuthorToken', () => { + const originalGon = window.gon; + const currentUserLength = 1; let mock; let wrapper; + const getBaseToken = () => wrapper.findComponent(BaseToken); + beforeEach(() => { mock = new MockAdapter(axios); - wrapper = createComponent(); }); afterEach(() => { + window.gon = originalGon; mock.restore(); wrapper.destroy(); }); - describe('computed', () => { - describe('currentValue', () => { - it('returns lowercase string for `value.data`', () => { - wrapper = createComponent({ value: { data: 'FOO' } }); - - expect(wrapper.vm.currentValue).toBe('foo'); + describe('methods', () => { + describe('fetchAuthorBySearchTerm', () => { + beforeEach(() => { + wrapper = createComponent(); }); - }); - describe('activeAuthor', () => { - it('returns object for currently present `value.data`', async () => { - wrapper = createComponent({ value: { data: mockAuthors[0].username } }); - - wrapper.setData({ - authors: mockAuthors, - }); + it('calls `config.fetchAuthors` with provided searchTerm param', () => { + jest.spyOn(wrapper.vm.config, 'fetchAuthors'); - await wrapper.vm.$nextTick(); + getBaseToken().vm.$emit('fetch-token-values', mockAuthors[0].username); - expect(wrapper.vm.activeAuthor).toEqual(mockAuthors[0]); + expect(wrapper.vm.config.fetchAuthors).toHaveBeenCalledWith( + mockAuthorToken.fetchPath, + mockAuthors[0].username, + ); }); - }); - }); - - describe('fetchAuthorBySearchTerm', () => { - it('calls `config.fetchAuthors` with provided searchTerm param', () => { - jest.spyOn(wrapper.vm.config, 'fetchAuthors'); - - wrapper.vm.fetchAuthorBySearchTerm(mockAuthors[0].username); - expect(wrapper.vm.config.fetchAuthors).toHaveBeenCalledWith( - mockAuthorToken.fetchPath, - mockAuthors[0].username, - ); - }); - - it('sets response to `authors` when request is succesful', () => { - jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockResolvedValue(mockAuthors); + it('sets response to `authors` when request is succesful', () => { + jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockResolvedValue(mockAuthors); - wrapper.vm.fetchAuthorBySearchTerm('root'); + getBaseToken().vm.$emit('fetch-token-values', 'root'); - return waitForPromises().then(() => { - expect(wrapper.vm.authors).toEqual(mockAuthors); + return waitForPromises().then(() => { + expect(getBaseToken().props('tokenValues')).toEqual(mockAuthors); + }); }); - }); - it('calls `createFlash` with flash error message when request fails', () => { - jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({}); + it('calls `createFlash` with flash error message when request fails', () => { + jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({}); - wrapper.vm.fetchAuthorBySearchTerm('root'); + getBaseToken().vm.$emit('fetch-token-values', 'root'); - return waitForPromises().then(() => { - expect(createFlash).toHaveBeenCalledWith('There was a problem fetching users.'); + return waitForPromises().then(() => { + expect(createFlash).toHaveBeenCalledWith({ + message: 'There was a problem fetching users.', + }); + }); }); - }); - it('sets `loading` to false when request completes', () => { - jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({}); + it('sets `loading` to false when request completes', async () => { + jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({}); - wrapper.vm.fetchAuthorBySearchTerm('root'); + getBaseToken().vm.$emit('fetch-token-values', 'root'); - return waitForPromises().then(() => { - expect(wrapper.vm.loading).toBe(false); + await waitForPromises(); + + expect(getBaseToken().props('tokensListLoading')).toBe(false); }); }); }); describe('template', () => { - beforeEach(() => { - wrapper.setData({ - authors: mockAuthors, + const activateTokenValuesList = async () => { + const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment); + const suggestionsSegment = tokenSegments.at(2); + suggestionsSegment.vm.$emit('activate'); + await wrapper.vm.$nextTick(); + }; + + it('renders base-token component', () => { + wrapper = createComponent({ + value: { data: mockAuthors[0].username }, + data: { authors: mockAuthors }, }); - return wrapper.vm.$nextTick(); - }); + const baseTokenEl = getBaseToken(); - it('renders gl-filtered-search-token component', () => { - expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true); + expect(baseTokenEl.exists()).toBe(true); + expect(baseTokenEl.props()).toMatchObject({ + tokenValues: mockAuthors, + fnActiveTokenValue: wrapper.vm.getActiveAuthor, + }); }); it('renders token item when value is selected', () => { - wrapper.setProps({ + wrapper = createComponent({ value: { data: mockAuthors[0].username }, + data: { authors: mockAuthors }, + stubs: { Portal: true }, }); return wrapper.vm.$nextTick(() => { const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment); expect(tokenSegments).toHaveLength(3); // Author, =, "Administrator" - expect(tokenSegments.at(2).text()).toBe(mockAuthors[0].name); // "Administrator" + + const tokenValue = tokenSegments.at(2); + + expect(tokenValue.findComponent(GlAvatar).props('src')).toBe(mockAuthors[0].avatar_url); + expect(tokenValue.text()).toBe(mockAuthors[0].name); // "Administrator" }); }); + it('renders token value with correct avatarUrl from author object', async () => { + const getAvatarEl = () => + wrapper.findAll(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar); + + wrapper = createComponent({ + value: { data: mockAuthors[0].username }, + data: { + authors: [ + { + ...mockAuthors[0], + }, + ], + }, + stubs: { Portal: true }, + }); + + await wrapper.vm.$nextTick(); + + expect(getAvatarEl().props('src')).toBe(mockAuthors[0].avatar_url); + + wrapper.setData({ + authors: [ + { + ...mockAuthors[0], + avatarUrl: mockAuthors[0].avatar_url, + avatar_url: undefined, + }, + ], + }); + + await wrapper.vm.$nextTick(); + + expect(getAvatarEl().props('src')).toBe(mockAuthors[0].avatar_url); + }); + it('renders provided defaultAuthors as suggestions', async () => { const defaultAuthors = DEFAULT_NONE_ANY; wrapper = createComponent({ active: true, - config: { ...mockAuthorToken, defaultAuthors }, + config: { ...mockAuthorToken, defaultAuthors, preloadedAuthors: mockPreloadedAuthors }, stubs: { Portal: true }, }); - const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment); - const suggestionsSegment = tokenSegments.at(2); - suggestionsSegment.vm.$emit('activate'); - await wrapper.vm.$nextTick(); + + await activateTokenValuesList(); const suggestions = wrapper.findAll(GlFilteredSearchSuggestion); - expect(suggestions).toHaveLength(defaultAuthors.length); + expect(suggestions).toHaveLength(defaultAuthors.length + currentUserLength); defaultAuthors.forEach((label, index) => { expect(suggestions.at(index).text()).toBe(label.text); }); @@ -189,25 +240,42 @@ describe('AuthorToken', () => { suggestionsSegment.vm.$emit('activate'); await wrapper.vm.$nextTick(); - expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false); expect(wrapper.find(GlDropdownDivider).exists()).toBe(false); }); it('renders `DEFAULT_LABEL_ANY` as default suggestions', async () => { wrapper = createComponent({ active: true, - config: { ...mockAuthorToken }, + config: { ...mockAuthorToken, preloadedAuthors: mockPreloadedAuthors }, stubs: { Portal: true }, }); - const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment); - const suggestionsSegment = tokenSegments.at(2); - suggestionsSegment.vm.$emit('activate'); - await wrapper.vm.$nextTick(); + + await activateTokenValuesList(); const suggestions = wrapper.findAll(GlFilteredSearchSuggestion); - expect(suggestions).toHaveLength(1); + expect(suggestions).toHaveLength(1 + currentUserLength); expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_ANY.text); }); + + describe('when loading', () => { + beforeEach(() => { + wrapper = createComponent({ + active: true, + config: { + ...mockAuthorToken, + preloadedAuthors: mockPreloadedAuthors, + defaultAuthors: [], + }, + stubs: { Portal: true }, + }); + }); + + it('shows current user', () => { + const firstSuggestion = wrapper.findComponent(GlFilteredSearchSuggestion).text(); + expect(firstSuggestion).toContain('Administrator'); + expect(firstSuggestion).toContain('@root'); + }); + }); }); }); 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 0db47f1f189..602864f4fa5 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 @@ -175,6 +175,23 @@ describe('BaseToken', () => { expect(setTokenValueToRecentlyUsed).toHaveBeenCalledWith(mockStorageKey, mockTokenValue); }); + + it('does not add token from preloadedTokenValues', async () => { + const mockTokenValue = { + id: 1, + title: 'Foo', + }; + + wrapper.setProps({ + preloadedTokenValues: [mockTokenValue], + }); + + await wrapper.vm.$nextTick(); + + wrapper.vm.handleTokenValueSelected(mockTokenValue); + + expect(setTokenValueToRecentlyUsed).not.toHaveBeenCalled(); + }); }); }); diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js index fb48aea8e4f..778a214f97e 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js @@ -7,7 +7,7 @@ import { import { mount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import waitForPromises from 'helpers/wait_for_promises'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; +import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { @@ -121,7 +121,9 @@ describe('EmojiToken', () => { wrapper.vm.fetchEmojiBySearchTerm('foo'); return waitForPromises().then(() => { - expect(createFlash).toHaveBeenCalledWith('There was a problem fetching emojis.'); + expect(createFlash).toHaveBeenCalledWith({ + message: 'There was a problem fetching emojis.', + }); }); }); diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/epic_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/epic_token_spec.js index addc058f658..68ed46fc3a2 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/epic_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/epic_token_spec.js @@ -67,18 +67,6 @@ describe('EpicToken', () => { await wrapper.vm.$nextTick(); }); - - describe('activeEpic', () => { - it('returns object for currently present `value.data`', async () => { - wrapper.setProps({ - value: { data: `${mockEpics[0].iid}` }, - }); - - await wrapper.vm.$nextTick(); - - expect(wrapper.vm.activeEpic).toEqual(mockEpics[0]); - }); - }); }); describe('methods', () => { @@ -86,9 +74,12 @@ describe('EpicToken', () => { it('calls `config.fetchEpics` with provided searchTerm param', () => { jest.spyOn(wrapper.vm.config, 'fetchEpics'); - wrapper.vm.fetchEpicsBySearchTerm('foo'); + wrapper.vm.fetchEpicsBySearchTerm({ search: 'foo' }); - expect(wrapper.vm.config.fetchEpics).toHaveBeenCalledWith('foo'); + expect(wrapper.vm.config.fetchEpics).toHaveBeenCalledWith({ + epicPath: '', + search: 'foo', + }); }); it('sets response to `epics` when request is successful', async () => { @@ -96,7 +87,7 @@ describe('EpicToken', () => { data: mockEpics, }); - wrapper.vm.fetchEpicsBySearchTerm(); + wrapper.vm.fetchEpicsBySearchTerm({}); await waitForPromises(); @@ -106,7 +97,7 @@ describe('EpicToken', () => { it('calls `createFlash` with flash error message when request fails', async () => { jest.spyOn(wrapper.vm.config, 'fetchEpics').mockRejectedValue({}); - wrapper.vm.fetchEpicsBySearchTerm('foo'); + wrapper.vm.fetchEpicsBySearchTerm({ search: 'foo' }); await waitForPromises(); @@ -118,7 +109,7 @@ describe('EpicToken', () => { it('sets `loading` to false when request completes', async () => { jest.spyOn(wrapper.vm.config, 'fetchEpics').mockRejectedValue({}); - wrapper.vm.fetchEpicsBySearchTerm('foo'); + wrapper.vm.fetchEpicsBySearchTerm({ search: 'foo' }); await waitForPromises(); @@ -128,9 +119,11 @@ describe('EpicToken', () => { }); describe('template', () => { + const getTokenValueEl = () => wrapper.findAllComponents(GlFilteredSearchTokenSegment).at(2); + beforeEach(async () => { wrapper = createComponent({ - value: { data: `${mockEpics[0].iid}` }, + value: { data: `${mockEpics[0].group_full_path}::&${mockEpics[0].iid}` }, data: { epics: mockEpics }, }); @@ -147,5 +140,19 @@ describe('EpicToken', () => { expect(tokenSegments).toHaveLength(3); expect(tokenSegments.at(2).text()).toBe(`${mockEpics[0].title}::&${mockEpics[0].iid}`); }); + + it.each` + value | valueType | tokenValueString + ${`${mockEpics[0].group_full_path}::&${mockEpics[0].iid}`} | ${'string'} | ${`${mockEpics[0].title}::&${mockEpics[0].iid}`} + ${`${mockEpics[1].group_full_path}::&${mockEpics[1].iid}`} | ${'number'} | ${`${mockEpics[1].title}::&${mockEpics[1].iid}`} + `('renders token item when selection is a $valueType', async ({ value, tokenValueString }) => { + wrapper.setProps({ + value: { data: value }, + }); + + await wrapper.vm.$nextTick(); + + expect(getTokenValueEl().text()).toBe(tokenValueString); + }); }); }); diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js index 57514a0c499..dd1c61b92b8 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js @@ -1,5 +1,4 @@ import { - GlFilteredSearchToken, GlFilteredSearchSuggestion, GlFilteredSearchTokenSegment, GlDropdownDivider, @@ -11,13 +10,14 @@ import { mockRegularLabel, mockLabels, } from 'jest/vue_shared/components/sidebar/labels_select_vue/mock_data'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; +import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { DEFAULT_LABELS, DEFAULT_NONE_ANY, } from '~/vue_shared/components/filtered_search_bar/constants'; +import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue'; import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue'; import { mockLabelToken } from '../mock_data'; @@ -25,6 +25,7 @@ import { mockLabelToken } from '../mock_data'; jest.mock('~/flash'); const defaultStubs = { Portal: true, + BaseToken, GlFilteredSearchSuggestionList: { template: '<div></div>', methods: { @@ -68,55 +69,17 @@ describe('LabelToken', () => { wrapper.destroy(); }); - describe('computed', () => { - beforeEach(async () => { - // Label title with spaces is always enclosed in quotations by component. - wrapper = createComponent({ value: { data: `"${mockRegularLabel.title}"` } }); - - wrapper.setData({ - labels: mockLabels, - }); - - await wrapper.vm.$nextTick(); - }); - - describe('currentValue', () => { - it('returns lowercase string for `value.data`', () => { - expect(wrapper.vm.currentValue).toBe('"foo label"'); - }); - }); - - describe('activeLabel', () => { - it('returns object for currently present `value.data`', () => { - expect(wrapper.vm.activeLabel).toEqual(mockRegularLabel); - }); - }); - - describe('containerStyle', () => { - it('returns object containing `backgroundColor` and `color` properties based on `activeLabel` value', () => { - expect(wrapper.vm.containerStyle).toEqual({ - backgroundColor: mockRegularLabel.color, - color: mockRegularLabel.textColor, - }); - }); - - it('returns empty object when `activeLabel` is not set', async () => { - wrapper.setData({ - labels: [], - }); - - await wrapper.vm.$nextTick(); - - expect(wrapper.vm.containerStyle).toEqual({}); - }); - }); - }); - describe('methods', () => { beforeEach(() => { wrapper = createComponent(); }); + describe('getActiveLabel', () => { + it('returns label object from labels array based on provided `currentValue` param', () => { + expect(wrapper.vm.getActiveLabel(mockLabels, 'foo label')).toEqual(mockRegularLabel); + }); + }); + describe('getLabelName', () => { it('returns value of `name` or `title` property present in provided label param', () => { let mockLabel = { @@ -158,7 +121,9 @@ describe('LabelToken', () => { wrapper.vm.fetchLabelBySearchTerm('foo'); return waitForPromises().then(() => { - expect(createFlash).toHaveBeenCalledWith('There was a problem fetching labels.'); + expect(createFlash).toHaveBeenCalledWith({ + message: 'There was a problem fetching labels.', + }); }); }); @@ -187,8 +152,14 @@ describe('LabelToken', () => { await wrapper.vm.$nextTick(); }); - it('renders gl-filtered-search-token component', () => { - expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true); + it('renders base-token component', () => { + const baseTokenEl = wrapper.find(BaseToken); + + expect(baseTokenEl.exists()).toBe(true); + expect(baseTokenEl.props()).toMatchObject({ + tokenValues: mockLabels, + fnActiveTokenValue: wrapper.vm.getActiveLabel, + }); }); it('renders token item when value is selected', () => { |