import { GlTable, GlPagination, GlModal } from '@gitlab/ui'; import { mount, createLocalVue } from '@vue/test-utils'; import { last } from 'lodash'; import Vuex from 'vuex'; import stubChildren from 'helpers/stub_children'; import { packageList } from 'jest/packages/mock_data'; import PackagesListRow from '~/packages/shared/components/package_list_row.vue'; import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue'; import { TrackingActions } from '~/packages/shared/constants'; import * as SharedUtils from '~/packages/shared/utils'; import PackagesList from '~/packages_and_registries/package_registry/components/list/packages_list.vue'; import Tracking from '~/tracking'; const localVue = createLocalVue(); localVue.use(Vuex); describe('packages_list', () => { let wrapper; let store; const EmptySlotStub = { name: 'empty-slot-stub', template: '
bar
' }; const findPackagesListLoader = () => wrapper.find(PackagesListLoader); const findPackageListPagination = () => wrapper.find(GlPagination); const findPackageListDeleteModal = () => wrapper.find(GlModal); const findEmptySlot = () => wrapper.find(EmptySlotStub); const findPackagesListRow = () => wrapper.find(PackagesListRow); const createStore = (isGroupPage, packages, isLoading) => { const state = { isLoading, packages, pagination: { perPage: 1, total: 1, page: 1, }, config: { isGroupPage, }, sorting: { orderBy: 'version', sort: 'desc', }, }; store = new Vuex.Store({ state, getters: { getList: () => packages, }, }); store.dispatch = jest.fn(); }; const mountComponent = ({ isGroupPage = false, packages = packageList, isLoading = false, ...options } = {}) => { createStore(isGroupPage, packages, isLoading); wrapper = mount(PackagesList, { localVue, store, stubs: { ...stubChildren(PackagesList), GlTable, GlModal, }, ...options, }); }; afterEach(() => { wrapper.destroy(); wrapper = null; }); describe('when is loading', () => { beforeEach(() => { mountComponent({ packages: [], isLoading: true, }); }); it('shows skeleton loader when loading', () => { expect(findPackagesListLoader().exists()).toBe(true); }); }); describe('when is not loading', () => { beforeEach(() => { mountComponent(); }); it('does not show skeleton loader when not loading', () => { expect(findPackagesListLoader().exists()).toBe(false); }); }); describe('layout', () => { beforeEach(() => { mountComponent(); }); it('contains a pagination component', () => { const sorting = findPackageListPagination(); expect(sorting.exists()).toBe(true); }); it('contains a modal component', () => { const sorting = findPackageListDeleteModal(); expect(sorting.exists()).toBe(true); }); }); describe('when the user can destroy the package', () => { beforeEach(() => { mountComponent(); }); it('setItemToBeDeleted sets itemToBeDeleted and open the modal', () => { const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show'); const item = last(wrapper.vm.list); findPackagesListRow().vm.$emit('packageToDelete', item); return wrapper.vm.$nextTick().then(() => { expect(wrapper.vm.itemToBeDeleted).toEqual(item); expect(mockModalShow).toHaveBeenCalled(); }); }); it('deleteItemConfirmation resets itemToBeDeleted', () => { wrapper.setData({ itemToBeDeleted: 1 }); wrapper.vm.deleteItemConfirmation(); expect(wrapper.vm.itemToBeDeleted).toEqual(null); }); it('deleteItemConfirmation emit package:delete', () => { const itemToBeDeleted = { id: 2 }; wrapper.setData({ itemToBeDeleted }); wrapper.vm.deleteItemConfirmation(); return wrapper.vm.$nextTick(() => { expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]); }); }); it('deleteItemCanceled resets itemToBeDeleted', () => { wrapper.setData({ itemToBeDeleted: 1 }); wrapper.vm.deleteItemCanceled(); expect(wrapper.vm.itemToBeDeleted).toEqual(null); }); }); describe('when the list is empty', () => { beforeEach(() => { mountComponent({ packages: [], slots: { 'empty-state': EmptySlotStub, }, }); }); it('show the empty slot', () => { const emptySlot = findEmptySlot(); expect(emptySlot.exists()).toBe(true); }); }); describe('pagination component', () => { let pagination; let modelEvent; beforeEach(() => { mountComponent(); pagination = findPackageListPagination(); // retrieve the event used by v-model, a more sturdy approach than hardcoding it modelEvent = pagination.vm.$options.model.event; }); it('emits page:changed events when the page changes', () => { pagination.vm.$emit(modelEvent, 2); expect(wrapper.emitted('page:changed')).toEqual([[2]]); }); }); describe('tracking', () => { let eventSpy; let utilSpy; const category = 'foo'; beforeEach(() => { mountComponent(); eventSpy = jest.spyOn(Tracking, 'event'); utilSpy = jest.spyOn(SharedUtils, 'packageTypeToTrackCategory').mockReturnValue(category); wrapper.setData({ itemToBeDeleted: { package_type: 'conan' } }); }); it('tracking category calls packageTypeToTrackCategory', () => { expect(wrapper.vm.tracking.category).toBe(category); expect(utilSpy).toHaveBeenCalledWith('conan'); }); it('deleteItemConfirmation calls event', () => { wrapper.vm.deleteItemConfirmation(); expect(eventSpy).toHaveBeenCalledWith( category, TrackingActions.DELETE_PACKAGE, expect.any(Object), ); }); }); });