diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-16 12:08:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-16 12:08:34 +0300 |
commit | ae30db7b18f1963c2afebb19968039deaabbf82d (patch) | |
tree | dfba19673438373b0ab2be3f7e5beede4829aca3 /spec/frontend/editor | |
parent | 38261f234b4be76c4faed84d61553166bb3b0dff (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/editor')
3 files changed, 274 insertions, 0 deletions
diff --git a/spec/frontend/editor/components/helpers.js b/spec/frontend/editor/components/helpers.js new file mode 100644 index 00000000000..3e6cd2a236d --- /dev/null +++ b/spec/frontend/editor/components/helpers.js @@ -0,0 +1,12 @@ +import { EDITOR_TOOLBAR_RIGHT_GROUP } from '~/editor/constants'; + +export const buildButton = (id = 'foo-bar-btn', options = {}) => { + return { + __typename: 'Item', + id, + label: options.label || 'Foo Bar Button', + icon: options.icon || 'foo-bar', + selected: options.selected || false, + group: options.group || EDITOR_TOOLBAR_RIGHT_GROUP, + }; +}; diff --git a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js new file mode 100644 index 00000000000..5135091af4a --- /dev/null +++ b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js @@ -0,0 +1,146 @@ +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; +import { GlButton } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import SourceEditorToolbarButton from '~/editor/components/source_editor_toolbar_button.vue'; +import getToolbarItemQuery from '~/editor/graphql/get_item.query.graphql'; +import updateToolbarItemMutation from '~/editor/graphql/update_item.mutation.graphql'; +import { buildButton } from './helpers'; + +Vue.use(VueApollo); + +describe('Source Editor Toolbar button', () => { + let wrapper; + let mockApollo; + const defaultBtn = buildButton(); + + const findButton = () => wrapper.findComponent(GlButton); + + const createComponentWithApollo = ({ propsData } = {}) => { + mockApollo = createMockApollo(); + mockApollo.clients.defaultClient.cache.writeQuery({ + query: getToolbarItemQuery, + variables: { id: defaultBtn.id }, + data: { + item: { + ...defaultBtn, + }, + }, + }); + + wrapper = shallowMount(SourceEditorToolbarButton, { + propsData, + apolloProvider: mockApollo, + }); + }; + + afterEach(() => { + wrapper.destroy(); + mockApollo = null; + }); + + describe('default', () => { + const defaultProps = { + category: 'primary', + variant: 'default', + }; + const customProps = { + category: 'secondary', + variant: 'info', + }; + it('renders a default button without props', async () => { + createComponentWithApollo(); + const btn = findButton(); + expect(btn.exists()).toBe(true); + expect(btn.props()).toMatchObject(defaultProps); + }); + + it('renders a button based on the props passed', async () => { + createComponentWithApollo({ + propsData: { + button: customProps, + }, + }); + const btn = findButton(); + expect(btn.props()).toMatchObject(customProps); + }); + }); + + describe('button updates', () => { + it('it properly updates button on Apollo cache update', async () => { + const { id } = defaultBtn; + + createComponentWithApollo({ + propsData: { + button: { + id, + }, + }, + }); + + expect(findButton().props('selected')).toBe(false); + + mockApollo.clients.defaultClient.cache.writeQuery({ + query: getToolbarItemQuery, + variables: { id }, + data: { + item: { + ...defaultBtn, + selected: true, + }, + }, + }); + + jest.runOnlyPendingTimers(); + await nextTick(); + + expect(findButton().props('selected')).toBe(true); + }); + }); + + describe('click handler', () => { + it('fires the click handler on the button when available', () => { + const spy = jest.fn(); + createComponentWithApollo({ + propsData: { + button: { + onClick: spy, + }, + }, + }); + expect(spy).not.toHaveBeenCalled(); + findButton().vm.$emit('click'); + expect(spy).toHaveBeenCalled(); + }); + it('emits the "click" event', () => { + createComponentWithApollo(); + jest.spyOn(wrapper.vm, '$emit'); + expect(wrapper.vm.$emit).not.toHaveBeenCalled(); + findButton().vm.$emit('click'); + expect(wrapper.vm.$emit).toHaveBeenCalledWith('click'); + }); + it('triggers the mutation exposing the changed "selected" prop', () => { + const { id } = defaultBtn; + createComponentWithApollo({ + propsData: { + button: { + id, + }, + }, + }); + jest.spyOn(wrapper.vm.$apollo, 'mutate'); + expect(wrapper.vm.$apollo.mutate).not.toHaveBeenCalled(); + findButton().vm.$emit('click'); + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateToolbarItemMutation, + variables: { + id, + propsToUpdate: { + selected: true, + }, + }, + }); + }); + }); +}); diff --git a/spec/frontend/editor/components/source_editor_toolbar_spec.js b/spec/frontend/editor/components/source_editor_toolbar_spec.js new file mode 100644 index 00000000000..6e99eadbd97 --- /dev/null +++ b/spec/frontend/editor/components/source_editor_toolbar_spec.js @@ -0,0 +1,116 @@ +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; +import { GlButtonGroup } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import SourceEditorToolbar from '~/editor/components/source_editor_toolbar.vue'; +import SourceEditorToolbarButton from '~/editor/components/source_editor_toolbar_button.vue'; +import { EDITOR_TOOLBAR_LEFT_GROUP, EDITOR_TOOLBAR_RIGHT_GROUP } from '~/editor/constants'; +import getToolbarItemsQuery from '~/editor/graphql/get_items.query.graphql'; +import { buildButton } from './helpers'; + +Vue.use(VueApollo); + +describe('Source Editor Toolbar', () => { + let wrapper; + let mockApollo; + + const findButtons = () => wrapper.findAllComponents(SourceEditorToolbarButton); + + const createApolloMockWithCache = (items = []) => { + mockApollo = createMockApollo(); + mockApollo.clients.defaultClient.cache.writeQuery({ + query: getToolbarItemsQuery, + data: { + items: { + nodes: items, + }, + }, + }); + }; + + const createComponentWithApollo = (items = []) => { + createApolloMockWithCache(items); + wrapper = shallowMount(SourceEditorToolbar, { + apolloProvider: mockApollo, + stubs: { + GlButtonGroup, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + mockApollo = null; + }); + + describe('groups', () => { + it.each` + group | expectedGroup + ${EDITOR_TOOLBAR_LEFT_GROUP} | ${EDITOR_TOOLBAR_LEFT_GROUP} + ${EDITOR_TOOLBAR_RIGHT_GROUP} | ${EDITOR_TOOLBAR_RIGHT_GROUP} + ${undefined} | ${EDITOR_TOOLBAR_RIGHT_GROUP} + ${'non-existing'} | ${EDITOR_TOOLBAR_RIGHT_GROUP} + `('puts item with group="$group" into $expectedGroup group', ({ group, expectedGroup }) => { + const item = buildButton('first', { + group, + }); + createComponentWithApollo([item]); + expect(findButtons()).toHaveLength(1); + [EDITOR_TOOLBAR_RIGHT_GROUP, EDITOR_TOOLBAR_LEFT_GROUP].forEach((g) => { + if (g === expectedGroup) { + expect(wrapper.vm.getGroupItems(g)).toEqual([expect.objectContaining({ id: 'first' })]); + } else { + expect(wrapper.vm.getGroupItems(g)).toHaveLength(0); + } + }); + }); + }); + + describe('buttons update', () => { + it('it properly updates buttons on Apollo cache update', async () => { + const item = buildButton('first', { + group: EDITOR_TOOLBAR_RIGHT_GROUP, + }); + createComponentWithApollo(); + + expect(findButtons()).toHaveLength(0); + + mockApollo.clients.defaultClient.cache.writeQuery({ + query: getToolbarItemsQuery, + data: { + items: { + nodes: [item], + }, + }, + }); + + jest.runOnlyPendingTimers(); + await nextTick(); + + expect(findButtons()).toHaveLength(1); + }); + }); + + describe('click handler', () => { + it('emits the "click" event when a button is clicked', () => { + const item1 = buildButton('first', { + group: EDITOR_TOOLBAR_LEFT_GROUP, + }); + const item2 = buildButton('second', { + group: EDITOR_TOOLBAR_RIGHT_GROUP, + }); + createComponentWithApollo([item1, item2]); + jest.spyOn(wrapper.vm, '$emit'); + expect(wrapper.vm.$emit).not.toHaveBeenCalled(); + + findButtons().at(0).vm.$emit('click'); + expect(wrapper.vm.$emit).toHaveBeenCalledWith('click', item1); + + findButtons().at(1).vm.$emit('click'); + expect(wrapper.vm.$emit).toHaveBeenCalledWith('click', item2); + + expect(wrapper.vm.$emit.mock.calls).toHaveLength(2); + }); + }); +}); |