diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-14 12:09:14 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-14 12:09:14 +0000 |
commit | 49089d4fb1f5c17328ac61c955d95a68c6d4d545 (patch) | |
tree | 309d97ce6cbc1b22935dd0e11cc72abd767ffcf3 /spec/frontend/vue_shared/components | |
parent | 846a84f2e9d6149b00c63ccae2850421f6766bac (diff) | |
download | gitlab-ce-49089d4fb1f5c17328ac61c955d95a68c6d4d545.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/vue_shared/components')
6 files changed, 129 insertions, 33 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 eded5b87abc..92ef20aad6c 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 @@ -13,7 +13,7 @@ import { SortDirection } from '~/vue_shared/components/filtered_search_bar/const import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store'; import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; -import { mockAvailableTokens, mockSortOptions } from './mock_data'; +import { mockAvailableTokens, mockSortOptions, mockHistoryItems } from './mock_data'; const createComponent = ({ namespace = 'gitlab-org/gitlab-test', @@ -53,11 +53,17 @@ describe('FilteredSearchBarRoot', () => { describe('computed', () => { describe('tokenSymbols', () => { - it('returns array of map containing type and symbols from `tokens` prop', () => { + it('returns a map containing type and symbols from `tokens` prop', () => { expect(wrapper.vm.tokenSymbols).toEqual({ author_username: '@' }); }); }); + describe('tokenTitles', () => { + it('returns a map containing type and title from `tokens` prop', () => { + expect(wrapper.vm.tokenTitles).toEqual({ author_username: 'Author' }); + }); + }); + describe('sortDirectionIcon', () => { it('returns string "sort-lowest" when `selectedSortDirection` is "ascending"', () => { wrapper.setData({ @@ -172,6 +178,19 @@ describe('FilteredSearchBarRoot', () => { }); }); + describe('handleClearHistory', () => { + it('clears search history from recent searches store', () => { + jest.spyOn(wrapper.vm.recentSearchesStore, 'setRecentSearches').mockReturnValue([]); + jest.spyOn(wrapper.vm.recentSearchesService, 'save'); + + wrapper.vm.handleClearHistory(); + + expect(wrapper.vm.recentSearchesStore.setRecentSearches).toHaveBeenCalledWith([]); + expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([]); + expect(wrapper.vm.getRecentSearches()).toEqual([]); + }); + }); + describe('handleFilterSubmit', () => { const mockFilters = [ { @@ -186,14 +205,11 @@ describe('FilteredSearchBarRoot', () => { it('calls `recentSearchesStore.addRecentSearch` with serialized value of provided `filters` param', () => { jest.spyOn(wrapper.vm.recentSearchesStore, 'addRecentSearch'); - // jest.spyOn(wrapper.vm.recentSearchesService, 'save'); wrapper.vm.handleFilterSubmit(mockFilters); return wrapper.vm.recentSearchesPromise.then(() => { - expect(wrapper.vm.recentSearchesStore.addRecentSearch).toHaveBeenCalledWith( - 'author_username:=@root foo', - ); + expect(wrapper.vm.recentSearchesStore.addRecentSearch).toHaveBeenCalledWith(mockFilters); }); }); @@ -203,9 +219,7 @@ describe('FilteredSearchBarRoot', () => { wrapper.vm.handleFilterSubmit(mockFilters); return wrapper.vm.recentSearchesPromise.then(() => { - expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([ - 'author_username:=@root foo', - ]); + expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([mockFilters]); }); }); @@ -224,6 +238,8 @@ describe('FilteredSearchBarRoot', () => { selectedSortDirection: SortDirection.descending, }); + wrapper.vm.recentSearchesStore.setRecentSearches(mockHistoryItems); + return wrapper.vm.$nextTick(); }); @@ -232,6 +248,7 @@ describe('FilteredSearchBarRoot', () => { expect(glFilteredSearchEl.props('placeholder')).toBe('Filter requirements'); expect(glFilteredSearchEl.props('availableTokens')).toEqual(mockAvailableTokens); + expect(glFilteredSearchEl.props('historyItems')).toEqual(mockHistoryItems); }); it('renders sort dropdown component', () => { 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 edc0f119262..7e28c4e11e1 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 @@ -44,6 +44,29 @@ export const mockAuthorToken = { export const mockAvailableTokens = [mockAuthorToken]; +export const mockHistoryItems = [ + [ + { + type: 'author_username', + value: { + data: 'toby', + operator: '=', + }, + }, + 'duo', + ], + [ + { + type: 'author_username', + value: { + data: 'root', + operator: '=', + }, + }, + 'si', + ], +]; + export const mockSortOptions = [ { id: 1, 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 3650ef79136..45294096eda 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 @@ -11,11 +11,12 @@ import { mockAuthorToken, mockAuthors } from '../mock_data'; jest.mock('~/flash'); -const createComponent = ({ config = mockAuthorToken, value = { data: '' } } = {}) => +const createComponent = ({ config = mockAuthorToken, value = { data: '' }, active = false } = {}) => mount(AuthorToken, { propsData: { config, value, + active, }, provide: { portalName: 'fake target', @@ -51,29 +52,23 @@ describe('AuthorToken', () => { describe('computed', () => { describe('currentValue', () => { it('returns lowercase string for `value.data`', () => { - wrapper.setProps({ - value: { data: 'FOO' }, - }); + wrapper = createComponent({ value: { data: 'FOO' } }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.vm.currentValue).toBe('foo'); - }); + expect(wrapper.vm.currentValue).toBe('foo'); }); }); describe('activeAuthor', () => { - it('returns object for currently present `value.data`', () => { + it('returns object for currently present `value.data`', async () => { + wrapper = createComponent({ value: { data: mockAuthors[0].username } }); + wrapper.setData({ authors: mockAuthors, }); - wrapper.setProps({ - value: { data: mockAuthors[0].username }, - }); + await wrapper.vm.$nextTick(); - return wrapper.vm.$nextTick(() => { - expect(wrapper.vm.activeAuthor).toEqual(mockAuthors[0]); - }); + expect(wrapper.vm.activeAuthor).toEqual(mockAuthors[0]); }); }); }); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js index 244e37f18c6..2253db7cbd0 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js @@ -2,14 +2,17 @@ import { buildUneditableOpenTokens, buildUneditableCloseToken, buildUneditableCloseTokens, + buildUneditableInlineTokens, buildUneditableTokens, } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; import { + originInlineToken, originToken, uneditableOpenTokens, uneditableCloseToken, uneditableCloseTokens, + uneditableInlineTokens, uneditableTokens, } from './mock_data'; @@ -38,8 +41,17 @@ describe('Build Uneditable Token renderer helper', () => { }); }); + describe('buildUneditableInlineTokens', () => { + it('returns a 3-item array of tokens with the originInlineToken wrapped in the middle of inline tokens', () => { + const result = buildUneditableInlineTokens(originInlineToken); + + expect(result).toHaveLength(3); + expect(result).toStrictEqual(uneditableInlineTokens); + }); + }); + describe('buildUneditableTokens', () => { - it('returns a 3-item array of tokens with the originToken wrapped in the middle', () => { + it('returns a 3-item array of tokens with the originToken wrapped in the middle of block tokens', () => { const result = buildUneditableTokens(originToken); expect(result).toHaveLength(3); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js index e81d9f55c05..0c010a20d98 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js @@ -12,20 +12,36 @@ export const normalTextNode = buildMockTextNode('This is just normal text.'); // Token spec helpers -const uneditableOpenToken = { - type: 'openTag', - tagName: 'div', - attributes: { contenteditable: false }, - classNames: [ - 'gl-px-4 gl-py-2 gl-opacity-5 gl-bg-gray-100 gl-user-select-none gl-cursor-not-allowed', - ], +const buildUneditableOpenToken = type => { + return { + type: 'openTag', + tagName: type, + attributes: { contenteditable: false }, + classNames: [ + 'gl-px-4 gl-py-2 gl-opacity-5 gl-bg-gray-100 gl-user-select-none gl-cursor-not-allowed', + ], + }; +}; + +const buildUneditableCloseToken = type => { + return { type: 'closeTag', tagName: type }; }; -export const uneditableCloseToken = { type: 'closeTag', tagName: 'div' }; export const originToken = { type: 'text', content: '{:.no_toc .hidden-md .hidden-lg}', }; -export const uneditableOpenTokens = [uneditableOpenToken, originToken]; +export const uneditableCloseToken = buildUneditableCloseToken('div'); +export const uneditableOpenTokens = [buildUneditableOpenToken('div'), originToken]; export const uneditableCloseTokens = [originToken, uneditableCloseToken]; export const uneditableTokens = [...uneditableOpenTokens, uneditableCloseToken]; + +export const originInlineToken = { + type: 'text', + content: '<i>Inline</i> content', +}; +export const uneditableInlineTokens = [ + buildUneditableOpenToken('span'), + originInlineToken, + buildUneditableCloseToken('span'), +]; diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js new file mode 100644 index 00000000000..d6bb01259bb --- /dev/null +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js @@ -0,0 +1,33 @@ +import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline'; +import { buildUneditableInlineTokens } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; + +import { normalTextNode } from './mock_data'; + +const fontAwesomeInlineHtmlNode = { + firstChild: null, + literal: '<i class="far fa-paper-plane" id="biz-tech-icons">', + type: 'html', +}; + +describe('Render Font Awesome Inline HTML renderer', () => { + describe('canRender', () => { + it('should return true when the argument `literal` has font awesome inline html syntax', () => { + expect(renderer.canRender(fontAwesomeInlineHtmlNode)).toBe(true); + }); + + it('should return false when the argument `literal` lacks font awesome inline html syntax', () => { + expect(renderer.canRender(normalTextNode)).toBe(false); + }); + }); + + describe('render', () => { + it('should return uneditable inline tokens', () => { + const token = { type: 'text', tagName: null, content: fontAwesomeInlineHtmlNode.literal }; + const context = { origin: () => token }; + + expect(renderer.render(fontAwesomeInlineHtmlNode, context)).toStrictEqual( + buildUneditableInlineTokens(token), + ); + }); + }); +}); |