diff options
Diffstat (limited to 'spec/frontend/packages_and_registries')
3 files changed, 119 insertions, 64 deletions
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js index fb5ee4e6884..0164d92ce34 100644 --- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js +++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js @@ -1,12 +1,13 @@ -import { GlTable, GlPagination, GlModal } from '@gitlab/ui'; +import { GlTable, GlPagination } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; +import Vue from 'vue'; import { last } from 'lodash'; import Vuex from 'vuex'; import stubChildren from 'helpers/stub_children'; import PackagesList from '~/packages_and_registries/infrastructure_registry/list/components/packages_list.vue'; import PackagesListRow from '~/packages_and_registries/infrastructure_registry/shared/package_list_row.vue'; import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue'; +import DeletePackageModal from '~/packages_and_registries/shared/components/delete_package_modal.vue'; import { TRACKING_ACTIONS } from '~/packages_and_registries/shared/constants'; import { TRACK_CATEGORY } from '~/packages_and_registries/infrastructure_registry/shared/constants'; import Tracking from '~/tracking'; @@ -22,7 +23,7 @@ describe('packages_list', () => { const findPackagesListLoader = () => wrapper.findComponent(PackagesListLoader); const findPackageListPagination = () => wrapper.findComponent(GlPagination); - const findPackageListDeleteModal = () => wrapper.findComponent(GlModal); + const findPackageListDeleteModal = () => wrapper.findComponent(DeletePackageModal); const findEmptySlot = () => wrapper.findComponent(EmptySlotStub); const findPackagesListRow = () => wrapper.findComponent(PackagesListRow); @@ -65,7 +66,7 @@ describe('packages_list', () => { stubs: { ...stubChildren(PackagesList), GlTable, - GlModal, + DeletePackageModal, }, ...options, }); @@ -109,52 +110,38 @@ describe('packages_list', () => { expect(sorting.exists()).toBe(true); }); - it('contains a modal component', () => { - const sorting = findPackageListDeleteModal(); - expect(sorting.exists()).toBe(true); + it("doesn't contain a modal component", () => { + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toBeNull(); }); }); describe('when the user can destroy the package', () => { - beforeEach(() => { + let itemToBeDeleted; + + beforeEach(async () => { mountComponent(); + itemToBeDeleted = last(packageList); + await findPackagesListRow().vm.$emit('packageToDelete', itemToBeDeleted); }); - it('setItemToBeDeleted sets itemToBeDeleted and open the modal', async () => { - const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show'); - const item = last(wrapper.vm.list); - - findPackagesListRow().vm.$emit('packageToDelete', item); - - await nextTick(); - expect(wrapper.vm.itemToBeDeleted).toEqual(item); - expect(mockModalShow).toHaveBeenCalled(); + afterEach(() => { + itemToBeDeleted = null; }); - it('deleteItemConfirmation resets itemToBeDeleted', () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ itemToBeDeleted: 1 }); - wrapper.vm.deleteItemConfirmation(); - expect(wrapper.vm.itemToBeDeleted).toEqual(null); + it('passes itemToBeDeleted to the modal', () => { + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toStrictEqual(itemToBeDeleted); }); it('deleteItemConfirmation emit package:delete', async () => { - const itemToBeDeleted = { id: 2 }; - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ itemToBeDeleted }); - wrapper.vm.deleteItemConfirmation(); - await nextTick(); + await findPackageListDeleteModal().vm.$emit('ok'); + expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]); }); - it('deleteItemCanceled resets itemToBeDeleted', () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ itemToBeDeleted: 1 }); - wrapper.vm.deleteItemCanceled(); - expect(wrapper.vm.itemToBeDeleted).toEqual(null); + it.each(['ok', 'cancel'])('resets itemToBeDeleted when modal emits %s', async (event) => { + await findPackageListDeleteModal().vm.$emit(event); + + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toBeNull(); }); }); diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js index 3e3607a361c..e086ee84073 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js @@ -1,8 +1,9 @@ -import { GlAlert, GlKeysetPagination, GlModal, GlSprintf } from '@gitlab/ui'; +import { GlAlert, GlKeysetPagination, GlSprintf } from '@gitlab/ui'; import { nextTick } from 'vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue'; import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue'; +import DeletePackageModal from '~/packages_and_registries/shared/components/delete_package_modal.vue'; import { DELETE_PACKAGE_TRACKING_ACTION, REQUEST_DELETE_PACKAGE_TRACKING_ACTION, @@ -35,15 +36,10 @@ describe('packages_list', () => { }; const EmptySlotStub = { name: 'empty-slot-stub', template: '<div>bar</div>' }; - const GlModalStub = { - name: GlModal.name, - template: '<div><slot></slot></div>', - methods: { show: jest.fn() }, - }; const findPackagesListLoader = () => wrapper.findComponent(PackagesListLoader); const findPackageListPagination = () => wrapper.findComponent(GlKeysetPagination); - const findPackageListDeleteModal = () => wrapper.findComponent(GlModalStub); + const findPackageListDeleteModal = () => wrapper.findComponent(DeletePackageModal); const findEmptySlot = () => wrapper.findComponent(EmptySlotStub); const findPackagesListRow = () => wrapper.findComponent(PackagesListRow); const findErrorPackageAlert = () => wrapper.findComponent(GlAlert); @@ -55,7 +51,7 @@ describe('packages_list', () => { ...props, }, stubs: { - GlModal: GlModalStub, + DeletePackageModal, GlSprintf, }, slots: { @@ -64,10 +60,6 @@ describe('packages_list', () => { }); }; - beforeEach(() => { - GlModalStub.methods.show.mockReset(); - }); - afterEach(() => { wrapper.destroy(); }); @@ -111,10 +103,10 @@ describe('packages_list', () => { expect(findPackageListPagination().exists()).toBe(true); }); - it('contains a modal component', () => { + it("doesn't contain a visible modal component", () => { mountComponent(); - expect(findPackageListDeleteModal().exists()).toBe(true); + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toBeNull(); }); it('does not have an error alert displayed', () => { @@ -125,31 +117,25 @@ describe('packages_list', () => { }); describe('when the user can destroy the package', () => { - beforeEach(() => { + beforeEach(async () => { mountComponent(); - findPackagesListRow().vm.$emit('packageToDelete', firstPackage); - return nextTick(); + await findPackagesListRow().vm.$emit('packageToDelete', firstPackage); }); - it('deleting a package opens the modal', () => { - expect(findPackageListDeleteModal().text()).toContain(firstPackage.name); + it('passes itemToBeDeleted to the modla', () => { + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toStrictEqual(firstPackage); }); - it('confirming on the modal emits package:delete', async () => { - findPackageListDeleteModal().vm.$emit('ok'); - - await nextTick(); + it('emits package:delete when modal confirms', async () => { + await findPackageListDeleteModal().vm.$emit('ok'); expect(wrapper.emitted('package:delete')[0]).toEqual([firstPackage]); }); - it('closing the modal resets itemToBeDeleted', async () => { - // triggering the v-model - findPackageListDeleteModal().vm.$emit('input', false); - - await nextTick(); + it.each(['ok', 'cancel'])('resets itemToBeDeleted when modal emits %s', async (event) => { + await findPackageListDeleteModal().vm.$emit(event); - expect(findPackageListDeleteModal().text()).not.toContain(firstPackage.name); + expect(findPackageListDeleteModal().props('itemToBeDeleted')).toBeNull(); }); }); diff --git a/spec/frontend/packages_and_registries/shared/components/delete_package_modal_spec.js b/spec/frontend/packages_and_registries/shared/components/delete_package_modal_spec.js new file mode 100644 index 00000000000..357dab593e8 --- /dev/null +++ b/spec/frontend/packages_and_registries/shared/components/delete_package_modal_spec.js @@ -0,0 +1,82 @@ +import { GlSprintf, GlModal } from '@gitlab/ui'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import DeletePackageModal from '~/packages_and_registries/shared/components/delete_package_modal.vue'; + +describe('DeletePackageModal', () => { + let wrapper; + + const defaultItemToBeDeleted = { + name: 'package 01', + }; + + const findModal = () => wrapper.findComponent(GlModal); + + const mountComponent = ({ itemToBeDeleted = defaultItemToBeDeleted } = {}) => { + wrapper = shallowMountExtended(DeletePackageModal, { + propsData: { + itemToBeDeleted, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('when itemToBeDeleted prop is defined', () => { + beforeEach(() => { + mountComponent(); + }); + + it('displays modal', () => { + expect(findModal().props('visible')).toBe(true); + }); + + it('passes title prop', () => { + expect(findModal().props('title')).toBe(wrapper.vm.$options.i18n.modalTitle); + }); + + it('passes actionPrimary prop', () => { + expect(findModal().props('actionPrimary')).toStrictEqual({ + text: wrapper.vm.$options.i18n.modalAction, + attributes: { + variant: 'danger', + }, + }); + }); + + it('displays description', () => { + const descriptionEl = findModal().findComponent(GlSprintf); + + expect(descriptionEl.exists()).toBe(true); + expect(descriptionEl.attributes('message')).toBe(wrapper.vm.$options.i18n.modalDescription); + }); + + it('emits ok when modal is validate', () => { + expect(wrapper.emitted().ok).toBeUndefined(); + + findModal().vm.$emit('ok'); + + expect(wrapper.emitted().ok).toHaveLength(1); + }); + + it('emits cancel when modal close', () => { + expect(wrapper.emitted().cancel).toBeUndefined(); + + findModal().vm.$emit('change', false); + + expect(wrapper.emitted().cancel).toHaveLength(1); + }); + }); + + describe('when itemToBeDeleted prop is null', () => { + beforeEach(() => { + mountComponent({ itemToBeDeleted: null }); + }); + + it("doesn't display modal", () => { + expect(findModal().props('visible')).toBe(false); + }); + }); +}); |