diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-10 00:10:29 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-10 00:10:29 +0000 |
commit | 981771279a48c03263e29f3b4f41f54204ea3146 (patch) | |
tree | 5e48e8debb84850147d183b094ffcd9d8b084c48 /spec/frontend/snippets/components/snippet_header_spec.js | |
parent | a8648ba08604085c76be1e4f5253ffa89aa192e3 (diff) | |
download | gitlab-ce-981771279a48c03263e29f3b4f41f54204ea3146.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/snippets/components/snippet_header_spec.js')
-rw-r--r-- | spec/frontend/snippets/components/snippet_header_spec.js | 150 |
1 files changed, 120 insertions, 30 deletions
diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js index e77bae79f68..fb95be3a77c 100644 --- a/spec/frontend/snippets/components/snippet_header_spec.js +++ b/spec/frontend/snippets/components/snippet_header_spec.js @@ -1,4 +1,4 @@ -import { GlButton, GlModal } from '@gitlab/ui'; +import { GlButton, GlModal, GlDropdown } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import { ApolloMutation } from 'vue-apollo'; import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; @@ -8,8 +8,6 @@ import { differenceInMilliseconds } from '~/lib/utils/datetime_utility'; import SnippetHeader from '~/snippets/components/snippet_header.vue'; import DeleteSnippetMutation from '~/snippets/mutations/deleteSnippet.mutation.graphql'; -useMockLocationHelper(); - describe('Snippet header component', () => { let wrapper; let snippet; @@ -19,6 +17,7 @@ describe('Snippet header component', () => { let errorMsg; let err; const originalRelativeUrlRoot = gon.relative_url_root; + const reportAbusePath = '/-/snippets/42/mark_as_spam'; const GlEmoji = { template: '<img/>' }; @@ -27,6 +26,7 @@ describe('Snippet header component', () => { permissions = {}, mutationRes = mutationTypes.RESOLVE, snippetProps = {}, + provide = {}, } = {}) { const defaultProps = Object.assign(snippet, snippetProps); if (permissions) { @@ -45,6 +45,10 @@ describe('Snippet header component', () => { wrapper = mount(SnippetHeader, { mocks: { $apollo }, + provide: { + reportAbusePath, + ...provide, + }, propsData: { snippet: { ...defaultProps, @@ -57,9 +61,27 @@ describe('Snippet header component', () => { }); } - const findAuthorEmoji = () => wrapper.find(GlEmoji); + const findAuthorEmoji = () => wrapper.findComponent(GlEmoji); const findAuthoredMessage = () => wrapper.find('[data-testid="authored-message"]').text(); - const buttonCount = () => wrapper.findAll(GlButton).length; + const findButtons = () => wrapper.findAllComponents(GlButton); + const findButtonsAsModel = () => + findButtons().wrappers.map((x) => ({ + text: x.text(), + href: x.attributes('href'), + category: x.props('category'), + variant: x.props('variant'), + disabled: x.props('disabled'), + })); + const findResponsiveDropdown = () => wrapper.findComponent(GlDropdown); + // We can't search by component here since we are full mounting and the attributes are applied to a child of the GlDropdownItem + const findResponsiveDropdownItems = () => findResponsiveDropdown().findAll('[role="menuitem"]'); + const findResponsiveDropdownItemsAsModel = () => + findResponsiveDropdownItems().wrappers.map((x) => ({ + disabled: x.attributes('disabled'), + href: x.attributes('href'), + title: x.attributes('title'), + text: x.text(), + })); beforeEach(() => { gon.relative_url_root = '/foo/'; @@ -144,42 +166,108 @@ describe('Snippet header component', () => { expect(text).toBe('Authored 1 month ago'); }); - it('renders action buttons based on permissions', () => { - createComponent({ - permissions: { - adminSnippet: false, - updateSnippet: false, + it('renders a action buttons', () => { + createComponent(); + + expect(findButtonsAsModel()).toEqual([ + { + category: 'primary', + disabled: false, + href: `${snippet.webUrl}/edit`, + text: 'Edit', + variant: 'default', }, - }); - expect(buttonCount()).toEqual(0); + { + category: 'secondary', + disabled: false, + text: 'Delete', + variant: 'danger', + }, + { + category: 'primary', + disabled: false, + href: reportAbusePath, + text: 'Submit as spam', + variant: 'default', + }, + ]); + }); - createComponent({ - permissions: { - adminSnippet: true, - updateSnippet: false, + it('renders responsive dropdown for action buttons', () => { + createComponent(); + + expect(findResponsiveDropdownItemsAsModel()).toEqual([ + { + href: `${snippet.webUrl}/edit`, + text: 'Edit', }, - }); - expect(buttonCount()).toEqual(1); + { + text: 'Delete', + }, + { + href: reportAbusePath, + text: 'Submit as spam', + title: 'Submit as spam', + }, + ]); + }); + it.each` + permissions | buttons + ${{ adminSnippet: false, updateSnippet: false }} | ${['Submit as spam']} + ${{ adminSnippet: true, updateSnippet: false }} | ${['Delete', 'Submit as spam']} + ${{ adminSnippet: false, updateSnippet: true }} | ${['Edit', 'Submit as spam']} + `('with permissions ($permissions), renders buttons ($buttons)', ({ permissions, buttons }) => { createComponent({ permissions: { - adminSnippet: true, - updateSnippet: true, + ...permissions, }, }); - expect(buttonCount()).toEqual(2); - createComponent({ - permissions: { - adminSnippet: true, - updateSnippet: true, - }, + expect(findButtonsAsModel().map((x) => x.text)).toEqual(buttons); + }); + + it('with canCreateSnippet permission, renders create button', async () => { + createComponent(); + + // TODO: we should avoid `wrapper.setData` since they + // are component internals. Let's use the apollo mock helpers + // in a follow-up. + wrapper.setData({ canCreateSnippet: true }); + await wrapper.vm.$nextTick(); + + expect(findButtonsAsModel()).toEqual( + expect.arrayContaining([ + { + category: 'secondary', + disabled: false, + href: `/foo/-/snippets/new`, + text: 'New snippet', + variant: 'success', + }, + ]), + ); + }); + + describe('with guest user', () => { + beforeEach(() => { + createComponent({ + permissions: { + adminSnippet: false, + updateSnippet: false, + }, + provide: { + reportAbusePath: null, + }, + }); }); - wrapper.setData({ - canCreateSnippet: true, + + it('does not show any action buttons', () => { + expect(findButtons()).toHaveLength(0); }); - return wrapper.vm.$nextTick().then(() => { - expect(buttonCount()).toEqual(3); + + it('does not show responsive action dropdown', () => { + expect(findResponsiveDropdown().exists()).toBe(false); }); }); @@ -221,6 +309,8 @@ describe('Snippet header component', () => { }); describe('in case of successful mutation, closes modal and redirects to correct listing', () => { + useMockLocationHelper(); + const createDeleteSnippet = (snippetProps = {}) => { createComponent({ snippetProps, |