diff options
Diffstat (limited to 'spec/frontend/issue_show/components/edit_actions_spec.js')
-rw-r--r-- | spec/frontend/issue_show/components/edit_actions_spec.js | 180 |
1 files changed, 115 insertions, 65 deletions
diff --git a/spec/frontend/issue_show/components/edit_actions_spec.js b/spec/frontend/issue_show/components/edit_actions_spec.js index 54707879f63..50c27cb5bda 100644 --- a/spec/frontend/issue_show/components/edit_actions_spec.js +++ b/spec/frontend/issue_show/components/edit_actions_spec.js @@ -1,113 +1,163 @@ -import Vue from 'vue'; -import editActions from '~/issue_show/components/edit_actions.vue'; +import { GlButton, GlModal } from '@gitlab/ui'; +import { createLocalVue } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import IssuableEditActions from '~/issue_show/components/edit_actions.vue'; import eventHub from '~/issue_show/event_hub'; -import Store from '~/issue_show/stores'; -describe('Edit Actions components', () => { - let vm; +import { + getIssueStateQueryResponse, + updateIssueStateQueryResponse, +} from '../mock_data/apollo_mock'; + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +describe('Edit Actions component', () => { + let wrapper; + let fakeApollo; + let mockIssueStateData; + + const mockResolvers = { + Query: { + issueState() { + return { + __typename: 'IssueState', + rawData: mockIssueStateData(), + }; + }, + }, + }; - beforeEach((done) => { - const Component = Vue.extend(editActions); - const store = new Store({ - titleHtml: '', - descriptionHtml: '', - issuableRef: '', - }); - store.formState.title = 'test'; + const modalId = 'delete-issuable-modal-1'; - jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + const createComponent = ({ props, data } = {}) => { + fakeApollo = createMockApollo([], mockResolvers); - vm = new Component({ + wrapper = shallowMountExtended(IssuableEditActions, { + apolloProvider: fakeApollo, propsData: { + formState: { + title: 'GitLab Issue', + }, canDestroy: true, - formState: store.formState, issuableType: 'issue', + ...props, }, - }).$mount(); + data() { + return { + issueState: {}, + modalId, + ...data, + }; + }, + }); + }; - Vue.nextTick(done); - }); + async function deleteIssuable(localWrapper) { + localWrapper.findComponent(GlModal).vm.$emit('primary'); + } - it('renders all buttons as enabled', () => { - expect(vm.$el.querySelectorAll('.disabled').length).toBe(0); + const findModal = () => wrapper.findComponent(GlModal); + const findEditButtons = () => wrapper.findAllComponents(GlButton); + const findDeleteButton = () => wrapper.findByTestId('issuable-delete-button'); + const findSaveButton = () => wrapper.findByTestId('issuable-save-button'); + const findCancelButton = () => wrapper.findByTestId('issuable-cancel-button'); - expect(vm.$el.querySelectorAll('[disabled]').length).toBe(0); + beforeEach(() => { + mockIssueStateData = jest.fn(); + createComponent(); }); - it('does not render delete button if canUpdate is false', (done) => { - vm.canDestroy = false; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn-danger')).toBeNull(); + afterEach(() => { + wrapper.destroy(); + }); - done(); + it('renders all buttons as enabled', () => { + const buttons = findEditButtons().wrappers; + buttons.forEach((button) => { + expect(button.attributes('disabled')).toBeFalsy(); }); }); - it('disables submit button when title is blank', (done) => { - vm.formState.title = ''; + it('does not render the delete button if canDestroy is false', () => { + createComponent({ props: { canDestroy: false } }); + expect(findDeleteButton().exists()).toBe(false); + }); - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn-confirm').getAttribute('disabled')).toBe('disabled'); + it('disables save button when title is blank', () => { + createComponent({ props: { formState: { title: '', issue_type: '' } } }); - done(); - }); + expect(findSaveButton().attributes('disabled')).toBe('true'); }); - it('should not show delete button if showDeleteButton is false', (done) => { - vm.showDeleteButton = false; + it('does not render the delete button if showDeleteButton is false', () => { + createComponent({ props: { showDeleteButton: false } }); - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn-danger')).toBeNull(); - done(); - }); + expect(findDeleteButton().exists()).toBe(false); }); describe('updateIssuable', () => { - it('sends update.issauble event when clicking save button', () => { - vm.$el.querySelector('.btn-confirm').click(); - - expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable'); + beforeEach(() => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); }); - it('disabled button after clicking save button', (done) => { - vm.$el.querySelector('.btn-confirm').click(); - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn-confirm').getAttribute('disabled')).toBe('disabled'); + it('sends update.issauble event when clicking save button', () => { + findSaveButton().vm.$emit('click', { preventDefault: jest.fn() }); - done(); - }); + expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable'); }); }); describe('closeForm', () => { + beforeEach(() => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + }); + it('emits close.form when clicking cancel', () => { - vm.$el.querySelector('.btn-default').click(); + findCancelButton().vm.$emit('click'); expect(eventHub.$emit).toHaveBeenCalledWith('close.form'); }); }); - describe('deleteIssuable', () => { - it('sends delete.issuable event when clicking save button', () => { - jest.spyOn(window, 'confirm').mockReturnValue(true); - vm.$el.querySelector('.btn-danger').click(); + describe('renders create modal with the correct information', () => { + it('renders correct modal id', () => { + expect(findModal().attributes('modalid')).toBe(modalId); + }); + }); - expect(eventHub.$emit).toHaveBeenCalledWith('delete.issuable', { destroy_confirm: true }); + describe('deleteIssuable', () => { + beforeEach(() => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); }); - it('does no actions when confirm is false', (done) => { - jest.spyOn(window, 'confirm').mockReturnValue(false); - vm.$el.querySelector('.btn-danger').click(); + it('does not send the `delete.issuable` event when clicking delete button', () => { + findDeleteButton().vm.$emit('click'); + expect(eventHub.$emit).not.toHaveBeenCalled(); + }); - Vue.nextTick(() => { - expect(eventHub.$emit).not.toHaveBeenCalledWith('delete.issuable'); + it('sends the `delete.issuable` event when clicking the delete confirm button', async () => { + expect(eventHub.$emit).toHaveBeenCalledTimes(0); + await deleteIssuable(wrapper); + expect(eventHub.$emit).toHaveBeenCalledWith('delete.issuable', { destroy_confirm: true }); + expect(eventHub.$emit).toHaveBeenCalledTimes(1); + }); + }); - expect(vm.$el.querySelector('.btn-danger .fa')).toBeNull(); + describe('with Apollo cache mock', () => { + it('renders the right delete button text per apollo cache type', async () => { + mockIssueStateData.mockResolvedValue(getIssueStateQueryResponse); + await waitForPromises(); + expect(findDeleteButton().text()).toBe('Delete issue'); + }); - done(); - }); + it('should not change the delete button text per apollo cache mutation', async () => { + mockIssueStateData.mockResolvedValue(updateIssueStateQueryResponse); + await waitForPromises(); + expect(findDeleteButton().text()).toBe('Delete issue'); }); }); }); |