diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/color_select_dropdown/color_select_root_spec.js')
-rw-r--r-- | spec/frontend/vue_shared/components/color_select_dropdown/color_select_root_spec.js | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/components/color_select_dropdown/color_select_root_spec.js b/spec/frontend/vue_shared/components/color_select_dropdown/color_select_root_spec.js new file mode 100644 index 00000000000..93b59800c27 --- /dev/null +++ b/spec/frontend/vue_shared/components/color_select_dropdown/color_select_root_spec.js @@ -0,0 +1,192 @@ +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import createFlash from '~/flash'; +import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue'; +import DropdownContents from '~/vue_shared/components/color_select_dropdown/dropdown_contents.vue'; +import DropdownValue from '~/vue_shared/components/color_select_dropdown/dropdown_value.vue'; +import epicColorQuery from '~/vue_shared/components/color_select_dropdown/graphql/epic_color.query.graphql'; +import updateEpicColorMutation from '~/vue_shared/components/color_select_dropdown/graphql/epic_update_color.mutation.graphql'; +import ColorSelectRoot from '~/vue_shared/components/color_select_dropdown/color_select_root.vue'; +import { DROPDOWN_VARIANT } from '~/vue_shared/components/color_select_dropdown/constants'; +import { colorQueryResponse, updateColorMutationResponse, color } from './mock_data'; + +jest.mock('~/flash'); + +Vue.use(VueApollo); + +const successfulQueryHandler = jest.fn().mockResolvedValue(colorQueryResponse); +const successfulMutationHandler = jest.fn().mockResolvedValue(updateColorMutationResponse); +const errorQueryHandler = jest.fn().mockRejectedValue('Error fetching epic color.'); +const errorMutationHandler = jest.fn().mockRejectedValue('An error occurred while updating color.'); + +const defaultProps = { + allowEdit: true, + iid: '1', + fullPath: 'workspace-1', +}; + +describe('LabelsSelectRoot', () => { + let wrapper; + + const findSidebarEditableItem = () => wrapper.findComponent(SidebarEditableItem); + const findDropdownValue = () => wrapper.findComponent(DropdownValue); + const findDropdownContents = () => wrapper.findComponent(DropdownContents); + + const createComponent = ({ + queryHandler = successfulQueryHandler, + mutationHandler = successfulMutationHandler, + propsData, + } = {}) => { + const mockApollo = createMockApollo([ + [epicColorQuery, queryHandler], + [updateEpicColorMutation, mutationHandler], + ]); + + wrapper = shallowMount(ColorSelectRoot, { + apolloProvider: mockApollo, + propsData: { + ...defaultProps, + ...propsData, + }, + provide: { + canUpdate: true, + }, + stubs: { + SidebarEditableItem, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('template', () => { + const defaultClasses = ['labels-select-wrapper', 'gl-relative']; + + it.each` + variant | cssClass + ${'sidebar'} | ${defaultClasses} + ${'embedded'} | ${[...defaultClasses, 'is-embedded']} + `( + 'renders component root element with CSS class `$cssClass` when variant is "$variant"', + async ({ variant, cssClass }) => { + createComponent({ + propsData: { variant }, + }); + + expect(wrapper.classes()).toEqual(cssClass); + }, + ); + }); + + describe('if the variant is `sidebar`', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders SidebarEditableItem component', () => { + expect(findSidebarEditableItem().exists()).toBe(true); + }); + + it('renders correct props for the SidebarEditableItem component', () => { + expect(findSidebarEditableItem().props()).toMatchObject({ + title: wrapper.vm.$options.i18n.widgetTitle, + canEdit: defaultProps.allowEdit, + loading: true, + }); + }); + + describe('when colors are loaded', () => { + beforeEach(async () => { + createComponent(); + await waitForPromises(); + }); + + it('passes false `loading` prop to sidebar editable item', () => { + expect(findSidebarEditableItem().props('loading')).toBe(false); + }); + + it('renders dropdown value component when query colors is resolved', () => { + expect(findDropdownValue().props('selectedColor')).toMatchObject(color); + }); + }); + }); + + describe('if the variant is `embedded`', () => { + beforeEach(() => { + createComponent({ propsData: { iid: undefined, variant: DROPDOWN_VARIANT.Embedded } }); + }); + + it('renders DropdownContents component', () => { + expect(findDropdownContents().exists()).toBe(true); + }); + + it('renders correct props for the DropdownContents component', () => { + expect(findDropdownContents().props()).toMatchObject({ + variant: DROPDOWN_VARIANT.Embedded, + dropdownTitle: wrapper.vm.$options.i18n.assignColor, + dropdownButtonText: wrapper.vm.$options.i18n.dropdownButtonText, + }); + }); + + it('handles DropdownContents setColor', () => { + findDropdownContents().vm.$emit('setColor', color); + expect(wrapper.emitted('updateSelectedColor')).toEqual([[color]]); + }); + }); + + describe('when epicColorQuery errored', () => { + beforeEach(async () => { + createComponent({ queryHandler: errorQueryHandler }); + await waitForPromises(); + }); + + it('creates flash with error message', () => { + expect(createFlash).toHaveBeenCalledWith({ + captureError: true, + message: 'Error fetching epic color.', + }); + }); + }); + + it('emits `updateSelectedColor` event on dropdown contents `setColor` event if iid is not set', () => { + createComponent({ propsData: { iid: undefined } }); + + findDropdownContents().vm.$emit('setColor', color); + expect(wrapper.emitted('updateSelectedColor')).toEqual([[color]]); + }); + + describe('when updating color for epic', () => { + beforeEach(() => { + createComponent(); + findDropdownContents().vm.$emit('setColor', color); + }); + + it('sets the loading state', () => { + expect(findSidebarEditableItem().props('loading')).toBe(true); + }); + + it('updates color correctly after successful mutation', async () => { + await waitForPromises(); + expect(findDropdownValue().props('selectedColor').color).toEqual( + updateColorMutationResponse.data.updateIssuableColor.issuable.color, + ); + }); + + it('displays an error if mutation was rejected', async () => { + createComponent({ mutationHandler: errorMutationHandler }); + findDropdownContents().vm.$emit('setColor', color); + await waitForPromises(); + + expect(createFlash).toHaveBeenCalledWith({ + captureError: true, + error: expect.anything(), + message: 'An error occurred while updating color.', + }); + }); + }); +}); |