diff options
Diffstat (limited to 'spec/frontend/packages_and_registries')
11 files changed, 174 insertions, 364 deletions
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js index 96c670eaad2..fa0d76762df 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js @@ -335,10 +335,10 @@ describe('tags list row', () => { }); describe.each` - name | finderFunction | text | icon | clipboard - ${'published date detail'} | ${findPublishedDateDetail} | ${'Published to the gitlab-org/gitlab-test/rails-12009 image repository at 01:29 UTC on 2020-11-03'} | ${'clock'} | ${false} - ${'manifest detail'} | ${findManifestDetail} | ${'Manifest digest: sha256:2cf3d2fdac1b04a14301d47d51cb88dcd26714c74f91440eeee99ce399089062'} | ${'log'} | ${true} - ${'configuration detail'} | ${findConfigurationDetail} | ${'Configuration digest: sha256:c2613843ab33aabf847965442b13a8b55a56ae28837ce182627c0716eb08c02b'} | ${'cloud-gear'} | ${true} + name | finderFunction | text | icon | clipboard + ${'published date detail'} | ${findPublishedDateDetail} | ${'Published to the gitlab-org/gitlab-test/rails-12009 image repository at 13:29:38 UTC on 2020-11-03'} | ${'clock'} | ${false} + ${'manifest detail'} | ${findManifestDetail} | ${'Manifest digest: sha256:2cf3d2fdac1b04a14301d47d51cb88dcd26714c74f91440eeee99ce399089062'} | ${'log'} | ${true} + ${'configuration detail'} | ${findConfigurationDetail} | ${'Configuration digest: sha256:c2613843ab33aabf847965442b13a8b55a56ae28837ce182627c0716eb08c02b'} | ${'cloud-gear'} | ${true} `('$name details row', ({ finderFunction, text, icon, clipboard }) => { it(`has ${text} as text`, async () => { mountComponent(); diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js index 7da91c4af96..75068591007 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js @@ -1,6 +1,6 @@ import { GlIcon, GlSprintf, GlSkeletonLoader, GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; -import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { createMockDirective } from 'helpers/vue_mock_directive'; import { mockTracking } from 'helpers/tracking_helper'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import DeleteButton from '~/packages_and_registries/container_registry/explorer/components/delete_button.vue'; @@ -59,31 +59,6 @@ describe('Image List Row', () => { wrapper = null; }); - describe('list item component', () => { - describe('tooltip', () => { - it(`the title is ${ROW_SCHEDULED_FOR_DELETION}`, () => { - mountComponent(); - - const tooltip = getBinding(wrapper.element, 'gl-tooltip'); - expect(tooltip).toBeDefined(); - expect(tooltip.value.title).toBe(ROW_SCHEDULED_FOR_DELETION); - }); - - it('is disabled when item is being deleted', () => { - mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } }); - - const tooltip = getBinding(wrapper.element, 'gl-tooltip'); - expect(tooltip.value.disabled).toBe(false); - }); - }); - - it('is disabled when the item is in deleting status', () => { - mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } }); - - expect(findListItemComponent().props('disabled')).toBe(true); - }); - }); - describe('image title and path', () => { it('renders shortened name of image and contains a link to the details page', () => { mountComponent(); @@ -158,10 +133,22 @@ describe('Image List Row', () => { mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } }); }); - it('the router link is disabled', () => { - // we check the event prop as is the only workaround to disable a router link - expect(findDetailsLink().props('event')).toBe(''); + it('the router link does not exist', () => { + expect(findDetailsLink().exists()).toBe(false); + }); + + it('image name exists', () => { + expect(findListItemComponent().text()).toContain('gitlab-test/rails-12009'); + }); + + it(`contains secondary text ${ROW_SCHEDULED_FOR_DELETION}`, () => { + expect(findListItemComponent().text()).toContain(ROW_SCHEDULED_FOR_DELETION); }); + + it('the tags count does not exist', () => { + expect(findTagsCount().exists()).toBe(false); + }); + it('the clipboard button is disabled', () => { expect(findClipboardButton().attributes('disabled')).toBe('true'); }); diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js index c6b5138639e..0cbe2755f7e 100644 --- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js +++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js @@ -61,14 +61,14 @@ describe('Package History', () => { ); }); describe.each` - name | amount | icon | text | timeAgoTooltip | link - ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'Test package version 1.0.0 was first created'} | ${mavenPackage.created_at} | ${null} - ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit #sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url} - ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url} - ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null} - ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit #sha-baz on branch branch-name, built by pipeline #3, and published to the registry'} | ${mavenPackage.created_at} | ${mockPipelineInfo.project.commit_url} + name | amount | icon | text | timeAgoTooltip | link + ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'Test package version 1.0.0 was first created'} | ${mavenPackage.created_at} | ${null} + ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url} + ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url} + ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null} + ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null} + ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null} + ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit sha-baz on branch branch-name, built by pipeline #3, and published to the registry'} | ${mavenPackage.created_at} | ${mockPipelineInfo.project.commit_url} `( 'with $amount pipelines history element $name', ({ name, icon, text, timeAgoTooltip, link, amount }) => { diff --git a/spec/frontend/packages_and_registries/package_registry/components/delete_modal_spec.js b/spec/frontend/packages_and_registries/package_registry/components/delete_modal_spec.js index e0e26434680..9c1ebf5a2eb 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/delete_modal_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/delete_modal_spec.js @@ -63,6 +63,14 @@ describe('DeleteModal', () => { expect(wrapper.emitted('confirm')).toHaveLength(1); }); + it('emits cancel when cancel event is emitted', () => { + expect(wrapper.emitted('cancel')).toBeUndefined(); + + findModal().vm.$emit('cancel'); + + expect(wrapper.emitted('cancel')).toHaveLength(1); + }); + it('show calls gl-modal show', () => { findModal().vm.show(); diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap index c4020eeb75f..b2375da7b11 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap +++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap @@ -114,7 +114,7 @@ exports[`PypiInstallation renders all the messages 1`] = ` aria-live="polite" class="btn input-group-text btn-default btn-md gl-button btn-default-secondary btn-icon" data-clipboard-handle-tooltip="false" - data-clipboard-text="pip install @gitlab-org/package-15 --extra-index-url http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple" + data-clipboard-text="pip install @gitlab-org/package-15 --index-url http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple" id="clipboard-button-6" title="Copy Pip command" type="button" diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js index ec2e833552a..bb2fa9eb6f5 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js @@ -131,14 +131,14 @@ describe('Package History', () => { }); describe.each` - name | amount | icon | text | timeAgoTooltip | link - ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'@gitlab-org/package-15 version 1.0.0 was first created'} | ${packageData().createdAt} | ${null} - ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit #b83d6e39 on branch master'} | ${null} | ${onePipeline.commitPath} - ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by Administrator'} | ${onePipeline.createdAt} | ${onePipeline.path} - ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${packageData().createdAt} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null} - ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit #b83d6e39 on branch master, built by pipeline #3, and published to the registry'} | ${packageData().createdAt} | ${onePipeline.commitPath} + name | amount | icon | text | timeAgoTooltip | link + ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'@gitlab-org/package-15 version 1.0.0 was first created'} | ${packageData().createdAt} | ${null} + ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit b83d6e39 on branch master'} | ${null} | ${onePipeline.commitPath} + ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by Administrator'} | ${onePipeline.createdAt} | ${onePipeline.path} + ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${packageData().createdAt} | ${null} + ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null} + ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null} + ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit b83d6e39 on branch master, built by pipeline #3, and published to the registry'} | ${packageData().createdAt} | ${onePipeline.commitPath} `( 'with $amount pipelines history element $name', ({ name, icon, text, timeAgoTooltip, link, amount }) => { diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_versions_list_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_versions_list_spec.js index f0fa9592419..20a459e2c1a 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/package_versions_list_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_versions_list_spec.js @@ -1,7 +1,7 @@ -import { GlKeysetPagination } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import PackageVersionsList from '~/packages_and_registries/package_registry/components/details/package_versions_list.vue'; import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue'; +import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; import VersionRow from '~/packages_and_registries/package_registry/components/details/version_row.vue'; import { packageData } from '../../mock_data'; @@ -21,7 +21,7 @@ describe('PackageVersionsList', () => { const uiElements = { findLoader: () => wrapper.findComponent(PackagesListLoader), - findListPagination: () => wrapper.findComponent(GlKeysetPagination), + findRegistryList: () => wrapper.findComponent(RegistryList), findEmptySlot: () => wrapper.findComponent(EmptySlotStub), findListRow: () => wrapper.findAllComponents(VersionRow), }; @@ -33,6 +33,9 @@ describe('PackageVersionsList', () => { isLoading: false, ...props, }, + stubs: { + RegistryList, + }, slots: { 'empty-state': EmptySlotStub, }, @@ -55,8 +58,8 @@ describe('PackageVersionsList', () => { expect(uiElements.findEmptySlot().exists()).toBe(false); }); - it('does not display pagination', () => { - expect(uiElements.findListPagination().exists()).toBe(false); + it('does not display registry list', () => { + expect(uiElements.findRegistryList().exists()).toBe(false); }); }); @@ -77,8 +80,8 @@ describe('PackageVersionsList', () => { expect(uiElements.findListRow().exists()).toBe(false); }); - it('does not display pagination', () => { - expect(uiElements.findListPagination().exists()).toBe(false); + it('does not display registry list', () => { + expect(uiElements.findRegistryList().exists()).toBe(false); }); }); @@ -87,6 +90,19 @@ describe('PackageVersionsList', () => { mountComponent(); }); + it('displays package registry list', () => { + expect(uiElements.findRegistryList().exists()).toEqual(true); + }); + + it('binds the right props', () => { + expect(uiElements.findRegistryList().props()).toMatchObject({ + items: packageList, + pagination: {}, + isLoading: false, + hiddenDelete: true, + }); + }); + it('displays package version rows', () => { expect(uiElements.findListRow().exists()).toEqual(true); expect(uiElements.findListRow()).toHaveLength(packageList.length); @@ -102,27 +118,6 @@ describe('PackageVersionsList', () => { }); }); - describe('pagination display', () => { - it('does not display pagination if there is no previous or next page', () => { - expect(uiElements.findListPagination().exists()).toBe(false); - }); - - it('displays pagination if pageInfo.hasNextPage is true', async () => { - await wrapper.setProps({ pageInfo: { hasNextPage: true } }); - expect(uiElements.findListPagination().exists()).toBe(true); - }); - - it('displays pagination if pageInfo.hasPreviousPage is true', async () => { - await wrapper.setProps({ pageInfo: { hasPreviousPage: true } }); - expect(uiElements.findListPagination().exists()).toBe(true); - }); - - it('displays pagination if both pageInfo.hasNextPage and pageInfo.hasPreviousPage are true', async () => { - await wrapper.setProps({ pageInfo: { hasNextPage: true, hasPreviousPage: true } }); - expect(uiElements.findListPagination().exists()).toBe(true); - }); - }); - it('does not display loader', () => { expect(uiElements.findLoader().exists()).toBe(false); }); @@ -137,14 +132,14 @@ describe('PackageVersionsList', () => { mountComponent({ pageInfo: { hasNextPage: true } }); }); - it('emits prev-page event when paginator emits prev event', () => { - uiElements.findListPagination().vm.$emit('prev'); + it('emits prev-page event when registry list emits prev event', () => { + uiElements.findRegistryList().vm.$emit('prev-page'); expect(wrapper.emitted('prev-page')).toHaveLength(1); }); - it('emits next-page when paginator emits next event', () => { - uiElements.findListPagination().vm.$emit('next'); + it('emits next-page when registry list emits next event', () => { + uiElements.findRegistryList().vm.$emit('next-page'); expect(wrapper.emitted('next-page')).toHaveLength(1); }); diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js index 20acb0872e5..4a27f8011df 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js @@ -16,7 +16,7 @@ const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_PYPI }; describe('PypiInstallation', () => { let wrapper; - const pipCommandStr = `pip install @gitlab-org/package-15 --extra-index-url ${packageEntity.pypiUrl}`; + const pipCommandStr = `pip install @gitlab-org/package-15 --index-url ${packageEntity.pypiUrl}`; const pypiSetupStr = `[gitlab] repository = ${packageEntity.pypiSetupUrl} username = __token__ 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 7cc5bea0f7a..5e9cb8fbb0b 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,14 +1,19 @@ import { GlAlert, GlSprintf } from '@gitlab/ui'; import { nextTick } from 'vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { stubComponent } from 'helpers/stub_component'; 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 DeleteModal from '~/packages_and_registries/package_registry/components/delete_modal.vue'; import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; import { DELETE_PACKAGE_TRACKING_ACTION, + DELETE_PACKAGES_TRACKING_ACTION, REQUEST_DELETE_PACKAGE_TRACKING_ACTION, + REQUEST_DELETE_PACKAGES_TRACKING_ACTION, CANCEL_DELETE_PACKAGE_TRACKING_ACTION, + CANCEL_DELETE_PACKAGES_TRACKING_ACTION, } from '~/packages_and_registries/package_registry/constants'; import PackagesList from '~/packages_and_registries/package_registry/components/list/packages_list.vue'; import Tracking from '~/tracking'; @@ -44,6 +49,7 @@ describe('packages_list', () => { const findRegistryList = () => wrapper.findComponent(RegistryList); const findPackagesListRow = () => wrapper.findComponent(PackagesListRow); const findErrorPackageAlert = () => wrapper.findComponent(GlAlert); + const findDeletePackagesModal = () => wrapper.findComponent(DeleteModal); const mountComponent = (props) => { wrapper = shallowMountExtended(PackagesList, { @@ -53,6 +59,11 @@ describe('packages_list', () => { }, stubs: { DeletePackageModal, + DeleteModal: stubComponent(DeleteModal, { + methods: { + show: jest.fn(), + }, + }), GlSprintf, RegistryList, }, @@ -125,20 +136,48 @@ describe('packages_list', () => { }); }); - describe('when the user can destroy the package', () => { - beforeEach(async () => { + describe.each` + description | finderFunction | deletePayload + ${'when the user can destroy the package'} | ${findPackagesListRow} | ${firstPackage} + ${'when the user can bulk destroy packages and deletes only one package'} | ${findRegistryList} | ${[firstPackage]} + `('$description', ({ finderFunction, deletePayload }) => { + let eventSpy; + const category = 'UI::NpmPackages'; + + beforeEach(() => { + eventSpy = jest.spyOn(Tracking, 'event'); mountComponent(); - await findPackagesListRow().vm.$emit('delete', firstPackage); + finderFunction().vm.$emit('delete', deletePayload); }); it('passes itemToBeDeleted to the modal', () => { expect(findPackageListDeleteModal().props('itemToBeDeleted')).toStrictEqual(firstPackage); }); - it('emits package:delete when modal confirms', async () => { - await findPackageListDeleteModal().vm.$emit('ok'); + it('requesting delete tracks the right action', () => { + expect(eventSpy).toHaveBeenCalledWith( + category, + REQUEST_DELETE_PACKAGE_TRACKING_ACTION, + expect.any(Object), + ); + }); + + describe('when modal confirms', () => { + beforeEach(() => { + findPackageListDeleteModal().vm.$emit('ok'); + }); + + it('emits package:delete when modal confirms', () => { + expect(wrapper.emitted('package:delete')[0]).toEqual([firstPackage]); + }); - expect(wrapper.emitted('package:delete')[0]).toEqual([firstPackage]); + it('tracks the right action', () => { + expect(eventSpy).toHaveBeenCalledWith( + category, + DELETE_PACKAGE_TRACKING_ACTION, + expect.any(Object), + ); + }); }); it.each(['ok', 'cancel'])('resets itemToBeDeleted when modal emits %s', async (event) => { @@ -146,26 +185,73 @@ describe('packages_list', () => { expect(findPackageListDeleteModal().props('itemToBeDeleted')).toBeNull(); }); + + it('canceling delete tracks the right action', () => { + findPackageListDeleteModal().vm.$emit('cancel'); + + expect(eventSpy).toHaveBeenCalledWith( + category, + CANCEL_DELETE_PACKAGE_TRACKING_ACTION, + expect.any(Object), + ); + }); }); describe('when the user can bulk destroy packages', () => { + let eventSpy; + const items = [firstPackage, secondPackage]; + beforeEach(() => { + eventSpy = jest.spyOn(Tracking, 'event'); mountComponent(); + findRegistryList().vm.$emit('delete', items); }); - it('passes itemToBeDeleted to the modal when there is only one package', async () => { - await findRegistryList().vm.$emit('delete', [firstPackage]); - - expect(findPackageListDeleteModal().props('itemToBeDeleted')).toStrictEqual(firstPackage); + it('passes itemsToBeDeleted to the modal', () => { + expect(findDeletePackagesModal().props('itemsToBeDeleted')).toStrictEqual(items); expect(wrapper.emitted('delete')).toBeUndefined(); }); - it('emits delete when there is more than one package', () => { - const items = [firstPackage, secondPackage]; - findRegistryList().vm.$emit('delete', items); + it('requesting delete tracks the right action', () => { + expect(eventSpy).toHaveBeenCalledWith( + undefined, + REQUEST_DELETE_PACKAGES_TRACKING_ACTION, + expect.any(Object), + ); + }); + + describe('when modal confirms', () => { + beforeEach(() => { + findDeletePackagesModal().vm.$emit('confirm'); + }); + + it('emits delete event', () => { + expect(wrapper.emitted('delete')[0]).toEqual([items]); + }); + + it('tracks the right action', () => { + expect(eventSpy).toHaveBeenCalledWith( + undefined, + DELETE_PACKAGES_TRACKING_ACTION, + expect.any(Object), + ); + }); + }); + + it.each(['confirm', 'cancel'])('resets itemsToBeDeleted when modal emits %s', async (event) => { + await findDeletePackagesModal().vm.$emit(event); - expect(wrapper.emitted('delete')).toHaveLength(1); - expect(wrapper.emitted('delete')[0]).toEqual([items]); + expect(findDeletePackagesModal().props('itemsToBeDeleted')).toHaveLength(0); + }); + + it('canceling delete tracks the right action', () => { + findDeletePackagesModal().vm.$emit('cancel'); + + expect(eventSpy).toHaveBeenCalledWith( + undefined, + CANCEL_DELETE_PACKAGES_TRACKING_ACTION, + expect.any(Object), + ); }); }); @@ -223,44 +309,4 @@ describe('packages_list', () => { expect(wrapper.emitted('next-page')).toHaveLength(1); }); }); - - describe('tracking', () => { - let eventSpy; - const category = 'UI::NpmPackages'; - - beforeEach(() => { - eventSpy = jest.spyOn(Tracking, 'event'); - mountComponent(); - findPackagesListRow().vm.$emit('delete', firstPackage); - return nextTick(); - }); - - it('requesting the delete tracks the right action', () => { - expect(eventSpy).toHaveBeenCalledWith( - category, - REQUEST_DELETE_PACKAGE_TRACKING_ACTION, - expect.any(Object), - ); - }); - - it('confirming delete tracks the right action', () => { - findPackageListDeleteModal().vm.$emit('ok'); - - expect(eventSpy).toHaveBeenCalledWith( - category, - DELETE_PACKAGE_TRACKING_ACTION, - expect.any(Object), - ); - }); - - it('canceling delete tracks the right action', () => { - findPackageListDeleteModal().vm.$emit('cancel'); - - expect(eventSpy).toHaveBeenCalledWith( - category, - CANCEL_DELETE_PACKAGE_TRACKING_ACTION, - expect.any(Object), - ); - }); - }); }); diff --git a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap deleted file mode 100644 index c2fecf87428..00000000000 --- a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap +++ /dev/null @@ -1,125 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PackagesListApp renders 1`] = ` -<div> - <!----> - - <gl-card-stub - bodyclass="gl-display-flex gl-p-0!" - class="gl-px-8 gl-py-6 gl-line-height-20 gl-mt-3" - footerclass="" - headerclass="" - > - <!----> - - <div - class="gl-banner-content" - > - <h2 - class="gl-banner-title" - > - Help us learn about your registry migration needs - </h2> - - <p> - If you are interested in migrating packages from your private registry to the GitLab Package Registry, take our survey and tell us more about your needs. - </p> - - <gl-button-stub - buttontextclasses="" - category="primary" - data-testid="gl-banner-primary-button" - href="https://gitlab.fra1.qualtrics.com/jfe/form/SV_cHomH9FPzOaiDTU" - icon="" - size="medium" - variant="confirm" - > - Take survey - </gl-button-stub> - - </div> - - <gl-button-stub - aria-label="Close banner" - buttontextclasses="" - category="tertiary" - class="gl-banner-close" - icon="close" - size="small" - variant="default" - /> - </gl-card-stub> - - <package-title-stub - count="2" - helpurl="/help/user/packages/index" - /> - - <package-search-stub - class="gl-mb-5" - /> - - <div> - <section - class="gl-display-flex empty-state gl-text-center gl-flex-direction-column" - > - <div - class="gl-max-w-full" - > - <div - class="svg-250 svg-content" - > - <img - alt="" - class="gl-max-w-full gl-dark-invert-keep-hue" - role="img" - src="emptyListIllustration" - /> - </div> - </div> - - <div - class="gl-max-w-full gl-m-auto" - > - <div - class="gl-mx-auto gl-my-0 gl-p-5" - > - <h1 - class="gl-font-size-h-display gl-line-height-36 h4" - > - - There are no packages yet - - </h1> - - <p - class="gl-mt-3" - > - Learn how to - <b-link-stub - class="gl-link" - event="click" - href="/help/user/packages/package_registry/index" - routertag="a" - target="_blank" - > - publish and share your packages - </b-link-stub> - with GitLab. - </p> - - <div - class="gl-display-flex gl-flex-wrap gl-justify-content-center" - > - <!----> - - <!----> - </div> - </div> - </div> - </section> - </div> - - <div /> -</div> -`; diff --git a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js index abdb875e839..b3cbd9f5dcf 100644 --- a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js @@ -1,23 +1,18 @@ -import { GlAlert, GlBanner, GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui'; +import { GlAlert, GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui'; import Vue, { nextTick } from 'vue'; - import VueApollo from 'vue-apollo'; -import * as utils from '~/lib/utils/common_utils'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; -import { stubComponent } from 'helpers/stub_component'; import ListPage from '~/packages_and_registries/package_registry/pages/list.vue'; import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue'; import PackageSearch from '~/packages_and_registries/package_registry/components/list/package_search.vue'; import OriginalPackageList from '~/packages_and_registries/package_registry/components/list/packages_list.vue'; import DeletePackage from '~/packages_and_registries/package_registry/components/functional/delete_package.vue'; -import DeleteModal from '~/packages_and_registries/package_registry/components/delete_modal.vue'; import { PROJECT_RESOURCE_TYPE, GROUP_RESOURCE_TYPE, GRAPHQL_PAGE_SIZE, - HIDE_PACKAGE_MIGRATION_SURVEY_COOKIE, EMPTY_LIST_HELP_URL, PACKAGE_HELP_URL, DELETE_PACKAGES_ERROR_MESSAGE, @@ -59,13 +54,11 @@ describe('PackagesListApp', () => { }; const findAlert = () => wrapper.findComponent(GlAlert); - const findBanner = () => wrapper.findComponent(GlBanner); const findPackageTitle = () => wrapper.findComponent(PackageTitle); const findSearch = () => wrapper.findComponent(PackageSearch); const findListComponent = () => wrapper.findComponent(PackageList); const findEmptyState = () => wrapper.findComponent(GlEmptyState); const findDeletePackage = () => wrapper.findComponent(DeletePackage); - const findDeletePackagesModal = () => wrapper.findComponent(DeleteModal); const mountComponent = ({ resolver = jest.fn().mockResolvedValue(packagesListQuery()), @@ -84,18 +77,12 @@ describe('PackagesListApp', () => { apolloProvider, provide, stubs: { - GlBanner, GlEmptyState, GlLoadingIcon, GlSprintf, GlLink, PackageList, DeletePackage, - DeleteModal: stubComponent(DeleteModal, { - methods: { - show: jest.fn(), - }, - }), }, }); }; @@ -118,14 +105,6 @@ describe('PackagesListApp', () => { expect(resolver).not.toHaveBeenCalled(); }); - it('renders', async () => { - mountComponent(); - - await waitForFirstRequest(); - - expect(wrapper.element).toMatchSnapshot(); - }); - it('has a package title', async () => { mountComponent(); @@ -138,70 +117,6 @@ describe('PackagesListApp', () => { }); }); - describe('package migration survey banner', () => { - describe('with no cookie set', () => { - beforeEach(() => { - utils.setCookie = jest.fn(); - - mountComponent(); - }); - - it('displays the banner', () => { - expect(findBanner().exists()).toBe(true); - }); - - it('does not call setCookie', () => { - expect(utils.setCookie).not.toHaveBeenCalled(); - }); - - describe('when the close button is clicked', () => { - beforeEach(() => { - findBanner().vm.$emit('close'); - }); - - it('sets the dismissed cookie', () => { - expect(utils.setCookie).toHaveBeenCalledWith( - HIDE_PACKAGE_MIGRATION_SURVEY_COOKIE, - 'true', - ); - }); - - it('does not display the banner', () => { - expect(findBanner().exists()).toBe(false); - }); - }); - - describe('when the primary button is clicked', () => { - beforeEach(() => { - findBanner().vm.$emit('primary'); - }); - - it('sets the dismissed cookie', () => { - expect(utils.setCookie).toHaveBeenCalledWith( - HIDE_PACKAGE_MIGRATION_SURVEY_COOKIE, - 'true', - ); - }); - - it('does not display the banner', () => { - expect(findBanner().exists()).toBe(false); - }); - }); - }); - - describe('with the dismissed cookie set', () => { - beforeEach(() => { - jest.spyOn(utils, 'getCookie').mockReturnValue('true'); - - mountComponent(); - }); - - it('does not display the banner', () => { - expect(findBanner().exists()).toBe(false); - }); - }); - }); - describe('search component', () => { it('exists', () => { mountComponent(); @@ -372,18 +287,6 @@ describe('PackagesListApp', () => { describe('bulk delete package', () => { const items = [{ id: '1' }, { id: '2' }]; - it('deletePackage is bound to package-list package:delete event', async () => { - mountComponent(); - - await waitForFirstRequest(); - - findListComponent().vm.$emit('delete', [{ id: '1' }, { id: '2' }]); - - await waitForPromises(); - - expect(findDeletePackagesModal().props('itemsToBeDeleted')).toEqual(items); - }); - it('calls mutation with the right values and shows success alert', async () => { const mutationResolver = jest.fn().mockResolvedValue(packagesDestroyMutation()); mountComponent({ @@ -394,8 +297,6 @@ describe('PackagesListApp', () => { findListComponent().vm.$emit('delete', items); - findDeletePackagesModal().vm.$emit('confirm'); - expect(mutationResolver).toHaveBeenCalledWith({ ids: items.map((item) => item.id), }); @@ -417,8 +318,6 @@ describe('PackagesListApp', () => { findListComponent().vm.$emit('delete', items); - findDeletePackagesModal().vm.$emit('confirm'); - await waitForPromises(); expect(findAlert().exists()).toBe(true); |