diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-27 18:14:37 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-27 18:14:37 +0000 |
commit | 956c34e4688544cba1ceee3205242df3b3a9fe30 (patch) | |
tree | be677c3ef09d2b2348c4ef6adcfb79092ad37b5e /spec/frontend/vue_shared | |
parent | 48f93eadd0c117a41b4e29e3d335f451a5e6e52f (diff) | |
download | gitlab-ce-956c34e4688544cba1ceee3205242df3b3a9fe30.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/vue_shared')
4 files changed, 84 insertions, 541 deletions
diff --git a/spec/frontend/vue_shared/components/gfm_autocomplete/__snapshots__/utils_spec.js.snap b/spec/frontend/vue_shared/components/gfm_autocomplete/__snapshots__/utils_spec.js.snap deleted file mode 100644 index 370b6eb01bc..00000000000 --- a/spec/frontend/vue_shared/components/gfm_autocomplete/__snapshots__/utils_spec.js.snap +++ /dev/null @@ -1,54 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`gfm_autocomplete/utils emojis config shows the emoji name and icon in the menu item 1`] = `"raised_hands <gl-emoji data-name=\\"raised_hands\\"></gl-emoji>"`; - -exports[`gfm_autocomplete/utils issues config shows the iid and title in the menu item within a project context 1`] = `"<small>123456</small> Project context issue title <script>alert('hi')</script>"`; - -exports[`gfm_autocomplete/utils issues config shows the reference and title in the menu item within a group context 1`] = `"<small>gitlab#987654</small> Group context issue title <script>alert('hi')</script>"`; - -exports[`gfm_autocomplete/utils labels config shows the title in the menu item 1`] = ` -" - <span class=\\"dropdown-label-box\\" style=\\"background: #123456;\\"></span> - bug <script>alert('hi')</script>" -`; - -exports[`gfm_autocomplete/utils members config shows an avatar character, name, parent name, and count in the menu item for a group 1`] = ` -" - <div class=\\"gl-display-flex gl-align-items-center\\"> - <div class=\\"gl-avatar gl-avatar-s32 gl-flex-shrink-0 gl-rounded-small - gl-display-flex gl-align-items-center gl-justify-content-center\\" aria-hidden=\\"true\\"> - G</div> - <div class=\\"gl-line-height-normal gl-ml-4\\"> - <div>1-1s <script>alert('hi')</script> (2)</div> - <div class=\\"gl-text-gray-700\\">GitLab Support Team</div> - </div> - - </div> - " -`; - -exports[`gfm_autocomplete/utils members config shows the avatar, name and username in the menu item for a user 1`] = ` -" - <div class=\\"gl-display-flex gl-align-items-center\\"> - <img class=\\"gl-avatar gl-avatar-s32 gl-flex-shrink-0 gl-avatar-circle\\" src=\\"/uploads/-/system/user/avatar/123456/avatar.png\\" alt=\\"\\" /> - <div class=\\"gl-line-height-normal gl-ml-4\\"> - <div>My Name <script>alert('hi')</script></div> - <div class=\\"gl-text-gray-700\\">@myusername</div> - </div> - - </div> - " -`; - -exports[`gfm_autocomplete/utils merge requests config shows the iid and title in the menu item within a project context 1`] = `"<small>123456</small> Project context merge request title <script>alert('hi')</script>"`; - -exports[`gfm_autocomplete/utils merge requests config shows the reference and title in the menu item within a group context 1`] = `"<small>gitlab!456789</small> Group context merge request title <script>alert('hi')</script>"`; - -exports[`gfm_autocomplete/utils milestones config shows the title in the menu item 1`] = `"13.2 <script>alert('hi')</script>"`; - -exports[`gfm_autocomplete/utils quick actions config shows the name, aliases, params and description in the menu item 1`] = ` -"<div>/unlabel <small>(or /remove_label)</small> <small>~label1 ~\\"label 2\\"</small></div> - <div><small><em>Remove all or specific label(s)</em></small></div>" -`; - -exports[`gfm_autocomplete/utils snippets config shows the id and title in the menu item 1`] = `"<small>123456</small> Snippet title <script>alert('hi')</script>"`; diff --git a/spec/frontend/vue_shared/components/gfm_autocomplete/gfm_autocomplete_spec.js b/spec/frontend/vue_shared/components/gfm_autocomplete/gfm_autocomplete_spec.js deleted file mode 100644 index b4002fdf4ec..00000000000 --- a/spec/frontend/vue_shared/components/gfm_autocomplete/gfm_autocomplete_spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import Tribute from '@gitlab/tributejs'; -import { shallowMount } from '@vue/test-utils'; -import GfmAutocomplete from '~/vue_shared/components/gfm_autocomplete/gfm_autocomplete.vue'; - -describe('GfmAutocomplete', () => { - let wrapper; - - describe('tribute', () => { - const mentions = '/gitlab-org/gitlab-test/-/autocomplete_sources/members?type=Issue&type_id=1'; - - beforeEach(() => { - wrapper = shallowMount(GfmAutocomplete, { - propsData: { - dataSources: { - mentions, - }, - }, - slots: { - default: ['<input/>'], - }, - }); - }); - - it('is set to tribute instance variable', () => { - expect(wrapper.vm.tribute instanceof Tribute).toBe(true); - }); - - it('contains the slot input element', () => { - wrapper.find('input').setValue('@'); - - expect(wrapper.vm.tribute.current.element).toBe(wrapper.find('input').element); - }); - }); -}); diff --git a/spec/frontend/vue_shared/components/gfm_autocomplete/utils_spec.js b/spec/frontend/vue_shared/components/gfm_autocomplete/utils_spec.js deleted file mode 100644 index 7ec3fbd4e3b..00000000000 --- a/spec/frontend/vue_shared/components/gfm_autocomplete/utils_spec.js +++ /dev/null @@ -1,427 +0,0 @@ -import { escape, last } from 'lodash'; -import { GfmAutocompleteType, tributeConfig } from '~/vue_shared/components/gfm_autocomplete/utils'; - -describe('gfm_autocomplete/utils', () => { - describe('emojis config', () => { - const emojisConfig = tributeConfig[GfmAutocompleteType.Emojis].config; - const emoji = 'raised_hands'; - - it('uses : as the trigger', () => { - expect(emojisConfig.trigger).toBe(':'); - }); - - it('searches using the emoji name', () => { - expect(emojisConfig.lookup(emoji)).toBe(emoji); - }); - - it('limits the number of rendered items to 100', () => { - expect(emojisConfig.menuItemLimit).toBe(100); - }); - - it('shows the emoji name and icon in the menu item', () => { - expect(emojisConfig.menuItemTemplate({ original: emoji })).toMatchSnapshot(); - }); - - it('inserts the emoji name on autocomplete selection', () => { - expect(emojisConfig.selectTemplate({ original: emoji })).toBe(`:${emoji}:`); - }); - }); - - describe('issues config', () => { - const issuesConfig = tributeConfig[GfmAutocompleteType.Issues].config; - const groupContextIssue = { - iid: 987654, - reference: 'gitlab#987654', - title: "Group context issue title <script>alert('hi')</script>", - }; - const projectContextIssue = { - id: null, - iid: 123456, - time_estimate: 0, - title: "Project context issue title <script>alert('hi')</script>", - }; - - it('uses # as the trigger', () => { - expect(issuesConfig.trigger).toBe('#'); - }); - - it('searches using both the iid and title', () => { - expect(issuesConfig.lookup(projectContextIssue)).toBe( - `${projectContextIssue.iid}${projectContextIssue.title}`, - ); - }); - - it('limits the number of rendered items to 100', () => { - expect(issuesConfig.menuItemLimit).toBe(100); - }); - - it('shows the reference and title in the menu item within a group context', () => { - expect(issuesConfig.menuItemTemplate({ original: groupContextIssue })).toMatchSnapshot(); - }); - - it('shows the iid and title in the menu item within a project context', () => { - expect(issuesConfig.menuItemTemplate({ original: projectContextIssue })).toMatchSnapshot(); - }); - - it('inserts the reference on autocomplete selection within a group context', () => { - expect(issuesConfig.selectTemplate({ original: groupContextIssue })).toBe( - groupContextIssue.reference, - ); - }); - - it('inserts the iid on autocomplete selection within a project context', () => { - expect(issuesConfig.selectTemplate({ original: projectContextIssue })).toBe( - `#${projectContextIssue.iid}`, - ); - }); - }); - - describe('labels config', () => { - const labelsConfig = tributeConfig[GfmAutocompleteType.Labels].config; - const labelsFilter = tributeConfig[GfmAutocompleteType.Labels].filterValues; - const label = { - color: '#123456', - textColor: '#FFFFFF', - title: `bug <script>alert('hi')</script>`, - type: 'GroupLabel', - }; - const singleWordLabel = { - color: '#456789', - textColor: '#DDD', - title: `bug`, - type: 'GroupLabel', - }; - const numericalLabel = { - color: '#abcdef', - textColor: '#AAA', - title: 123456, - type: 'ProjectLabel', - }; - - it('uses ~ as the trigger', () => { - expect(labelsConfig.trigger).toBe('~'); - }); - - it('searches using `title`', () => { - expect(labelsConfig.lookup).toBe('title'); - }); - - it('limits the number of rendered items to 100', () => { - expect(labelsConfig.menuItemLimit).toBe(100); - }); - - it('shows the title in the menu item', () => { - expect(labelsConfig.menuItemTemplate({ original: label })).toMatchSnapshot(); - }); - - it('inserts the title on autocomplete selection', () => { - expect(labelsConfig.selectTemplate({ original: singleWordLabel })).toBe( - `~${escape(singleWordLabel.title)}`, - ); - }); - - it('inserts the title enclosed with quotes on autocomplete selection when the title is numerical', () => { - expect(labelsConfig.selectTemplate({ original: numericalLabel })).toBe( - `~"${escape(numericalLabel.title)}"`, - ); - }); - - it('inserts the title enclosed with quotes on autocomplete selection when the title contains multiple words', () => { - expect(labelsConfig.selectTemplate({ original: label })).toBe(`~"${escape(label.title)}"`); - }); - - describe('filter', () => { - const collection = [label, singleWordLabel, { ...numericalLabel, set: true }]; - - describe('/label quick action', () => { - describe('when the line starts with `/label`', () => { - it('shows labels that are not currently selected', () => { - const fullText = '/label ~'; - const selectionStart = 8; - - expect(labelsFilter({ collection, fullText, selectionStart })).toEqual([ - collection[0], - collection[1], - ]); - }); - }); - - describe('when the line does not start with `/label`', () => { - it('shows all labels', () => { - const fullText = '~'; - const selectionStart = 1; - - expect(labelsFilter({ collection, fullText, selectionStart })).toEqual(collection); - }); - }); - }); - - describe('/unlabel quick action', () => { - describe('when the line starts with `/unlabel`', () => { - it('shows labels that are currently selected', () => { - const fullText = '/unlabel ~'; - const selectionStart = 10; - - expect(labelsFilter({ collection, fullText, selectionStart })).toEqual([collection[2]]); - }); - }); - - describe('when the line does not start with `/unlabel`', () => { - it('shows all labels', () => { - const fullText = '~'; - const selectionStart = 1; - - expect(labelsFilter({ collection, fullText, selectionStart })).toEqual(collection); - }); - }); - }); - }); - }); - - describe('members config', () => { - const membersConfig = tributeConfig[GfmAutocompleteType.Members].config; - const membersFilter = tributeConfig[GfmAutocompleteType.Members].filterValues; - const userMember = { - type: 'User', - username: 'myusername', - name: "My Name <script>alert('hi')</script>", - avatar_url: '/uploads/-/system/user/avatar/123456/avatar.png', - availability: null, - }; - const groupMember = { - type: 'Group', - username: 'gitlab-com/support/1-1s', - name: "GitLab.com / GitLab Support Team / 1-1s <script>alert('hi')</script>", - avatar_url: null, - count: 2, - mentionsDisabled: null, - }; - - it('uses @ as the trigger', () => { - expect(membersConfig.trigger).toBe('@'); - }); - - it('inserts the username on autocomplete selection', () => { - expect(membersConfig.fillAttr).toBe('username'); - }); - - it('searches using both the name and username for a user', () => { - expect(membersConfig.lookup(userMember)).toBe(`${userMember.name}${userMember.username}`); - }); - - it('searches using only its own name and not its ancestors for a group', () => { - expect(membersConfig.lookup(groupMember)).toBe(last(groupMember.name.split(' / '))); - }); - - it('limits the items in the autocomplete menu to 10', () => { - expect(membersConfig.menuItemLimit).toBe(10); - }); - - it('shows the avatar, name and username in the menu item for a user', () => { - expect(membersConfig.menuItemTemplate({ original: userMember })).toMatchSnapshot(); - }); - - it('shows an avatar character, name, parent name, and count in the menu item for a group', () => { - expect(membersConfig.menuItemTemplate({ original: groupMember })).toMatchSnapshot(); - }); - - describe('filter', () => { - const assignees = [userMember.username]; - const collection = [userMember, groupMember]; - - describe('/assign quick action', () => { - describe('when the line starts with `/assign`', () => { - it('shows members that are not currently selected', () => { - const fullText = '/assign @'; - const selectionStart = 9; - - expect(membersFilter({ assignees, collection, fullText, selectionStart })).toEqual([ - collection[1], - ]); - }); - }); - - describe('when the line does not start with `/assign`', () => { - it('shows all labels', () => { - const fullText = '@'; - const selectionStart = 1; - - expect(membersFilter({ assignees, collection, fullText, selectionStart })).toEqual( - collection, - ); - }); - }); - }); - - describe('/unassign quick action', () => { - describe('when the line starts with `/unassign`', () => { - it('shows members that are currently selected', () => { - const fullText = '/unassign @'; - const selectionStart = 11; - - expect(membersFilter({ assignees, collection, fullText, selectionStart })).toEqual([ - collection[0], - ]); - }); - }); - - describe('when the line does not start with `/unassign`', () => { - it('shows all members', () => { - const fullText = '@'; - const selectionStart = 1; - - expect(membersFilter({ assignees, collection, fullText, selectionStart })).toEqual( - collection, - ); - }); - }); - }); - }); - }); - - describe('merge requests config', () => { - const mergeRequestsConfig = tributeConfig[GfmAutocompleteType.MergeRequests].config; - const groupContextMergeRequest = { - iid: 456789, - reference: 'gitlab!456789', - title: "Group context merge request title <script>alert('hi')</script>", - }; - const projectContextMergeRequest = { - id: null, - iid: 123456, - time_estimate: 0, - title: "Project context merge request title <script>alert('hi')</script>", - }; - - it('uses ! as the trigger', () => { - expect(mergeRequestsConfig.trigger).toBe('!'); - }); - - it('searches using both the iid and title', () => { - expect(mergeRequestsConfig.lookup(projectContextMergeRequest)).toBe( - `${projectContextMergeRequest.iid}${projectContextMergeRequest.title}`, - ); - }); - - it('limits the number of rendered items to 100', () => { - expect(mergeRequestsConfig.menuItemLimit).toBe(100); - }); - - it('shows the reference and title in the menu item within a group context', () => { - expect( - mergeRequestsConfig.menuItemTemplate({ original: groupContextMergeRequest }), - ).toMatchSnapshot(); - }); - - it('shows the iid and title in the menu item within a project context', () => { - expect( - mergeRequestsConfig.menuItemTemplate({ original: projectContextMergeRequest }), - ).toMatchSnapshot(); - }); - - it('inserts the reference on autocomplete selection within a group context', () => { - expect(mergeRequestsConfig.selectTemplate({ original: groupContextMergeRequest })).toBe( - groupContextMergeRequest.reference, - ); - }); - - it('inserts the iid on autocomplete selection within a project context', () => { - expect(mergeRequestsConfig.selectTemplate({ original: projectContextMergeRequest })).toBe( - `!${projectContextMergeRequest.iid}`, - ); - }); - }); - - describe('milestones config', () => { - const milestonesConfig = tributeConfig[GfmAutocompleteType.Milestones].config; - const milestone = { - id: null, - iid: 49, - title: "13.2 <script>alert('hi')</script>", - }; - - it('uses % as the trigger', () => { - expect(milestonesConfig.trigger).toBe('%'); - }); - - it('searches using the title', () => { - expect(milestonesConfig.lookup).toBe('title'); - }); - - it('limits the number of rendered items to 100', () => { - expect(milestonesConfig.menuItemLimit).toBe(100); - }); - - it('shows the title in the menu item', () => { - expect(milestonesConfig.menuItemTemplate({ original: milestone })).toMatchSnapshot(); - }); - - it('inserts the title on autocomplete selection', () => { - expect(milestonesConfig.selectTemplate({ original: milestone })).toBe( - `%"${escape(milestone.title)}"`, - ); - }); - }); - - describe('quick actions config', () => { - const quickActionsConfig = tributeConfig[GfmAutocompleteType.QuickActions].config; - const quickAction = { - name: 'unlabel', - aliases: ['remove_label'], - description: 'Remove all or specific label(s)', - warning: '', - icon: '', - params: ['~label1 ~"label 2"'], - }; - - it('uses / as the trigger', () => { - expect(quickActionsConfig.trigger).toBe('/'); - }); - - it('inserts the name on autocomplete selection', () => { - expect(quickActionsConfig.fillAttr).toBe('name'); - }); - - it('searches using both the name and aliases', () => { - expect(quickActionsConfig.lookup(quickAction)).toBe( - `${quickAction.name}${quickAction.aliases.join(', /')}`, - ); - }); - - it('limits the number of rendered items to 100', () => { - expect(quickActionsConfig.menuItemLimit).toBe(100); - }); - - it('shows the name, aliases, params and description in the menu item', () => { - expect(quickActionsConfig.menuItemTemplate({ original: quickAction })).toMatchSnapshot(); - }); - }); - - describe('snippets config', () => { - const snippetsConfig = tributeConfig[GfmAutocompleteType.Snippets].config; - const snippet = { - id: 123456, - title: "Snippet title <script>alert('hi')</script>", - }; - - it('uses $ as the trigger', () => { - expect(snippetsConfig.trigger).toBe('$'); - }); - - it('inserts the id on autocomplete selection', () => { - expect(snippetsConfig.fillAttr).toBe('id'); - }); - - it('searches using both the id and title', () => { - expect(snippetsConfig.lookup(snippet)).toBe(`${snippet.id}${snippet.title}`); - }); - - it('limits the number of rendered items to 100', () => { - expect(snippetsConfig.menuItemLimit).toBe(100); - }); - - it('shows the id and title in the menu item', () => { - expect(snippetsConfig.menuItemTemplate({ original: snippet })).toMatchSnapshot(); - }); - }); -}); diff --git a/spec/frontend/vue_shared/components/help_popover_spec.js b/spec/frontend/vue_shared/components/help_popover_spec.js index 30c6fa04032..597fb63d95c 100644 --- a/spec/frontend/vue_shared/components/help_popover_spec.js +++ b/spec/frontend/vue_shared/components/help_popover_spec.js @@ -9,59 +9,117 @@ describe('HelpPopover', () => { const findQuestionButton = () => wrapper.find(GlButton); const findPopover = () => wrapper.find(GlPopover); - const buildWrapper = (options = {}) => { + + const createComponent = ({ props, ...opts } = {}) => { wrapper = mount(HelpPopover, { propsData: { options: { title, content, - ...options, }, + ...props, }, + ...opts, }); }; - beforeEach(() => { - buildWrapper(); - }); - afterEach(() => { wrapper.destroy(); }); - it('renders a link button with an icon question', () => { - expect(findQuestionButton().props()).toMatchObject({ - icon: 'question', - variant: 'link', + describe('with title and content', () => { + beforeEach(() => { + createComponent(); }); - }); - it('renders popover that uses the question button as target', () => { - expect(findPopover().props().target()).toBe(findQuestionButton().vm.$el); - }); + it('renders a link button with an icon question', () => { + expect(findQuestionButton().props()).toMatchObject({ + icon: 'question', + variant: 'link', + }); + }); - it('allows rendering title with HTML tags', () => { - expect(findPopover().find('strong').exists()).toBe(true); - }); + it('renders popover that uses the question button as target', () => { + expect(findPopover().props().target()).toBe(findQuestionButton().vm.$el); + }); - it('allows rendering content with HTML tags', () => { - expect(findPopover().find('b').exists()).toBe(true); + it('shows title and content', () => { + expect(findPopover().html()).toContain(title); + expect(findPopover().html()).toContain(content); + }); + + it('allows rendering title with HTML tags', () => { + expect(findPopover().find('strong').exists()).toBe(true); + }); + + it('allows rendering content with HTML tags', () => { + expect(findPopover().find('b').exists()).toBe(true); + }); }); describe('without title', () => { - it('does not render title', () => { - buildWrapper({ title: null }); + beforeEach(() => { + createComponent({ + props: { + options: { + title: null, + content, + }, + }, + }); + }); + + it('does not show title', () => { + expect(findPopover().html()).not.toContain(title); + }); - expect(findPopover().find('span').exists()).toBe(false); + it('shows content', () => { + expect(findPopover().html()).toContain(content); }); }); - it('binds other popover options to the popover instance', () => { + describe('with other options', () => { const placement = 'bottom'; - wrapper.destroy(); - buildWrapper({ placement }); + beforeEach(() => { + createComponent({ + props: { + options: { + placement, + }, + }, + }); + }); + + it('options bind to the popover', () => { + expect(findPopover().props().placement).toBe(placement); + }); + }); + + describe('with custom slots', () => { + const titleSlot = '<h1>title</h1>'; + const defaultSlot = '<strong>content</strong>'; - expect(findPopover().props().placement).toBe(placement); + beforeEach(() => { + createComponent({ + slots: { + title: titleSlot, + default: defaultSlot, + }, + }); + }); + + it('shows title slot', () => { + expect(findPopover().html()).toContain(titleSlot); + }); + + it('shows default content slot', () => { + expect(findPopover().html()).toContain(defaultSlot); + }); + + it('overrides title and content from options', () => { + expect(findPopover().html()).not.toContain(title); + expect(findPopover().html()).toContain(content); + }); }); }); |