import Vue from 'vue'; import tableRegistry from '~/registry/components/table_registry.vue'; import store from '~/registry/stores'; import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { repoPropsData } from '../mock_data'; const [firstImage, secondImage] = repoPropsData.list; describe('table registry', () => { let vm; const Component = Vue.extend(tableRegistry); const bulkDeletePath = 'path'; const findDeleteBtn = () => vm.$el.querySelector('.js-delete-registry'); const findDeleteBtnRow = () => vm.$el.querySelector('.js-delete-registry-row'); const findSelectAllCheckbox = () => vm.$el.querySelector('.js-select-all-checkbox > input'); const findAllRowCheckboxes = () => Array.from(vm.$el.querySelectorAll('.js-select-checkbox input')); const confirmationModal = (child = '') => document.querySelector(`#${vm.modalId} ${child}`); const createComponent = () => { vm = mountComponentWithStore(Component, { store, props: { repo: repoPropsData, }, }); }; const selectAllCheckboxes = () => vm.selectAll(); const deselectAllCheckboxes = () => vm.deselectAll(); beforeEach(() => { createComponent(); }); afterEach(() => { vm.$destroy(); }); describe('rendering', () => { it('should render a table with the registry list', () => { expect(vm.$el.querySelectorAll('table tbody tr').length).toEqual(repoPropsData.list.length); }); it('should render registry tag', () => { const textRendered = vm.$el .querySelector('.table tbody tr') .textContent.trim() // replace additional whitespace characters (e.g. new lines) with a single empty space .replace(/\s\s+/g, ' '); expect(textRendered).toContain(repoPropsData.list[0].tag); expect(textRendered).toContain(repoPropsData.list[0].shortRevision); expect(textRendered).toContain(repoPropsData.list[0].layers); expect(textRendered).toContain(repoPropsData.list[0].size); }); }); describe('multi select', () => { it('should support multiselect and selecting a row should enable delete button', done => { findSelectAllCheckbox().click(); selectAllCheckboxes(); expect(findSelectAllCheckbox().checked).toBe(true); Vue.nextTick(() => { expect(findDeleteBtn().disabled).toBe(false); done(); }); }); it('selecting all checkbox should select all rows and enable delete button', done => { selectAllCheckboxes(); Vue.nextTick(() => { const checkedValues = findAllRowCheckboxes().filter(x => x.checked); expect(checkedValues.length).toBe(repoPropsData.list.length); done(); }); }); it('deselecting select all checkbox should deselect all rows and disable delete button', done => { selectAllCheckboxes(); deselectAllCheckboxes(); Vue.nextTick(() => { const checkedValues = findAllRowCheckboxes().filter(x => x.checked); expect(checkedValues.length).toBe(0); done(); }); }); it('should delete multiple items when multiple items are selected', done => { selectAllCheckboxes(); Vue.nextTick(() => { expect(vm.itemsToBeDeleted).toEqual([0, 1]); expect(findDeleteBtn().disabled).toBe(false); findDeleteBtn().click(); spyOn(vm, 'multiDeleteItems').and.returnValue(Promise.resolve()); Vue.nextTick(() => { const modal = confirmationModal(); confirmationModal('.btn-danger').click(); expect(modal).toExist(); Vue.nextTick(() => { expect(vm.itemsToBeDeleted).toEqual([]); expect(vm.multiDeleteItems).toHaveBeenCalledWith({ path: bulkDeletePath, items: [firstImage.tag, secondImage.tag], }); done(); }); }); }); }); }); describe('delete registry', () => { beforeEach(() => { vm.itemsToBeDeleted = [0]; }); it('should be possible to delete a registry', done => { Vue.nextTick(() => { expect(vm.itemsToBeDeleted).toEqual([0]); expect(findDeleteBtn()).toBeDefined(); expect(findDeleteBtn().disabled).toBe(false); expect(findDeleteBtnRow()).toBeDefined(); done(); }); }); it('should call deleteItems and reset itemsToBeDeleted when confirming deletion', done => { Vue.nextTick(() => { expect(vm.itemsToBeDeleted).toEqual([0]); expect(findDeleteBtn().disabled).toBe(false); findDeleteBtn().click(); spyOn(vm, 'multiDeleteItems').and.returnValue(Promise.resolve()); Vue.nextTick(() => { confirmationModal('.btn-danger').click(); expect(vm.itemsToBeDeleted).toEqual([]); expect(vm.multiDeleteItems).toHaveBeenCalledWith({ path: bulkDeletePath, items: [firstImage.tag], }); done(); }); }); }); }); describe('pagination', () => { it('should be possible to change the page', () => { expect(vm.$el.querySelector('.gl-pagination')).toBeDefined(); }); }); describe('modal content', () => { it('should show the singular title and image name when deleting a single image', done => { findDeleteBtnRow().click(); Vue.nextTick(() => { expect(vm.modalTitle).toBe('Remove image'); expect(vm.modalDescription).toContain(firstImage.tag); done(); }); }); it('should show the plural title and image count when deleting more than one image', done => { selectAllCheckboxes(); vm.setModalDescription(); Vue.nextTick(() => { expect(vm.modalTitle).toBe('Remove images'); expect(vm.modalDescription).toContain('2 images'); done(); }); }); }); });