diff options
Diffstat (limited to 'spec/frontend/registry/explorer/pages/details_spec.js')
-rw-r--r-- | spec/frontend/registry/explorer/pages/details_spec.js | 198 |
1 files changed, 153 insertions, 45 deletions
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js index 15aa5008413..93098403a28 100644 --- a/spec/frontend/registry/explorer/pages/details_spec.js +++ b/spec/frontend/registry/explorer/pages/details_spec.js @@ -1,15 +1,21 @@ import { mount } from '@vue/test-utils'; -import { GlTable, GlPagination, GlSkeletonLoader } from '@gitlab/ui'; +import { GlTable, GlPagination, GlSkeletonLoader, GlAlert, GlLink } from '@gitlab/ui'; import Tracking from '~/tracking'; import stubChildren from 'helpers/stub_children'; import component from '~/registry/explorer/pages/details.vue'; -import store from '~/registry/explorer/stores/'; -import { SET_MAIN_LOADING } from '~/registry/explorer/stores/mutation_types/'; +import { createStore } from '~/registry/explorer/stores/'; +import { + SET_MAIN_LOADING, + SET_INITIAL_STATE, + SET_TAGS_LIST_SUCCESS, + SET_TAGS_PAGINATION, +} from '~/registry/explorer/stores/mutation_types/'; import { DELETE_TAG_SUCCESS_MESSAGE, DELETE_TAG_ERROR_MESSAGE, DELETE_TAGS_SUCCESS_MESSAGE, DELETE_TAGS_ERROR_MESSAGE, + ADMIN_GARBAGE_COLLECTION_TIP, } from '~/registry/explorer/constants'; import { tagsListResponse } from '../mock_data'; import { GlModal } from '../stubs'; @@ -18,6 +24,7 @@ import { $toast } from '../../shared/mocks'; describe('Details Page', () => { let wrapper; let dispatchSpy; + let store; const findDeleteModal = () => wrapper.find(GlModal); const findPagination = () => wrapper.find(GlPagination); @@ -30,6 +37,8 @@ describe('Details Page', () => { const findAllCheckboxes = () => wrapper.findAll('.js-row-checkbox'); const findCheckedCheckboxes = () => findAllCheckboxes().filter(c => c.attributes('checked')); const findFirsTagColumn = () => wrapper.find('.js-tag-column'); + const findFirstTagNameText = () => wrapper.find('[data-testid="rowNameText"]'); + const findAlert = () => wrapper.find(GlAlert); const routeId = window.btoa(JSON.stringify({ name: 'foo', tags_path: 'bar' })); @@ -55,13 +64,17 @@ describe('Details Page', () => { }; beforeEach(() => { + store = createStore(); dispatchSpy = jest.spyOn(store, 'dispatch'); - store.dispatch('receiveTagsListSuccess', tagsListResponse); + dispatchSpy.mockResolvedValue(); + store.commit(SET_TAGS_LIST_SUCCESS, tagsListResponse.data); + store.commit(SET_TAGS_PAGINATION, tagsListResponse.headers); jest.spyOn(Tracking, 'event'); }); afterEach(() => { wrapper.destroy(); + wrapper = null; }); describe('when isLoading is true', () => { @@ -130,10 +143,6 @@ describe('Details Page', () => { }); describe('row checkbox', () => { - beforeEach(() => { - mountComponent(); - }); - it('if selected adds item to selectedItems', () => { findFirstRowItem('rowCheckbox').vm.$emit('change'); return wrapper.vm.$nextTick().then(() => { @@ -240,15 +249,24 @@ describe('Details Page', () => { }); }); - describe('tag cell', () => { + describe('name cell', () => { + it('tag column has a tooltip with the tag name', () => { + mountComponent(); + expect(findFirstTagNameText().attributes('title')).toBe(tagsListResponse.data[0].name); + }); + describe('on desktop viewport', () => { beforeEach(() => { mountComponent(); }); - it('has class w-25', () => { + it('table header has class w-25', () => { expect(findFirsTagColumn().classes()).toContain('w-25'); }); + + it('tag column has the mw-m class', () => { + expect(findFirstRowItem('rowName').classes()).toContain('mw-m'); + }); }); describe('on mobile viewport', () => { @@ -260,9 +278,28 @@ describe('Details Page', () => { }); }); - it('does not has class w-25', () => { + it('table header does not have class w-25', () => { expect(findFirsTagColumn().classes()).not.toContain('w-25'); }); + + it('tag column has the gl-justify-content-end class', () => { + expect(findFirstRowItem('rowName').classes()).toContain('gl-justify-content-end'); + }); + }); + }); + + describe('last updated cell', () => { + let timeCell; + + beforeEach(() => { + timeCell = findFirstRowItem('rowTime'); + }); + + it('displays the time in string format', () => { + expect(timeCell.text()).toBe('2 years ago'); + }); + it('has a tooltip timestamp', () => { + expect(timeCell.attributes('title')).toBe('Sep 19, 2017 1:45pm GMT+0000'); }); }); }); @@ -328,25 +365,9 @@ describe('Details Page', () => { }); // itemsToBeDeleted is not represented in the DOM, is used as parking variable between selected and deleted items expect(wrapper.vm.itemsToBeDeleted).toEqual([]); + expect(wrapper.vm.selectedItems).toEqual([]); expect(findCheckedCheckboxes()).toHaveLength(0); }); - - it('show success toast on successful delete', () => { - return wrapper.vm.handleSingleDelete(0).then(() => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAG_SUCCESS_MESSAGE, { - type: 'success', - }); - }); - }); - - it('show error toast on erred delete', () => { - dispatchSpy.mockRejectedValue(); - return wrapper.vm.handleSingleDelete(0).then(() => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAG_ERROR_MESSAGE, { - type: 'error', - }); - }); - }); }); describe('when multiple elements are selected', () => { @@ -365,23 +386,6 @@ describe('Details Page', () => { expect(wrapper.vm.itemsToBeDeleted).toEqual([]); expect(findCheckedCheckboxes()).toHaveLength(0); }); - - it('show success toast on successful delete', () => { - return wrapper.vm.handleMultipleDelete(0).then(() => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAGS_SUCCESS_MESSAGE, { - type: 'success', - }); - }); - }); - - it('show error toast on erred delete', () => { - dispatchSpy.mockRejectedValue(); - return wrapper.vm.handleMultipleDelete(0).then(() => { - expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAGS_ERROR_MESSAGE, { - type: 'error', - }); - }); - }); }); }); @@ -395,4 +399,108 @@ describe('Details Page', () => { }); }); }); + + describe('Delete alert', () => { + const config = { + garbageCollectionHelpPagePath: 'foo', + }; + + describe('when the user is an admin', () => { + beforeEach(() => { + store.commit(SET_INITIAL_STATE, { ...config, isAdmin: true }); + }); + + afterEach(() => { + store.commit(SET_INITIAL_STATE, config); + }); + + describe.each` + deleteType | successTitle | errorTitle + ${'handleSingleDelete'} | ${DELETE_TAG_SUCCESS_MESSAGE} | ${DELETE_TAG_ERROR_MESSAGE} + ${'handleMultipleDelete'} | ${DELETE_TAGS_SUCCESS_MESSAGE} | ${DELETE_TAGS_ERROR_MESSAGE} + `('behaves correctly on $deleteType', ({ deleteType, successTitle, errorTitle }) => { + describe('when delete is successful', () => { + beforeEach(() => { + dispatchSpy.mockResolvedValue(); + mountComponent(); + return wrapper.vm[deleteType]('foo'); + }); + + it('alert exists', () => { + expect(findAlert().exists()).toBe(true); + }); + + it('alert body contains admin tip', () => { + expect( + findAlert() + .text() + .replace(/\s\s+/gm, ' '), + ).toBe(ADMIN_GARBAGE_COLLECTION_TIP.replace(/%{\w+}/gm, '')); + }); + + it('alert body contains link', () => { + const alertLink = findAlert().find(GlLink); + expect(alertLink.exists()).toBe(true); + expect(alertLink.attributes('href')).toBe(config.garbageCollectionHelpPagePath); + }); + + it('alert title is appropriate', () => { + expect(findAlert().attributes('title')).toBe(successTitle); + }); + }); + + describe('when delete is not successful', () => { + beforeEach(() => { + mountComponent(); + dispatchSpy.mockRejectedValue(); + return wrapper.vm[deleteType]('foo'); + }); + + it('alert exist and text is appropriate', () => { + expect(findAlert().exists()).toBe(true); + expect(findAlert().text()).toBe(errorTitle); + }); + }); + }); + }); + + describe.each` + deleteType | successTitle | errorTitle + ${'handleSingleDelete'} | ${DELETE_TAG_SUCCESS_MESSAGE} | ${DELETE_TAG_ERROR_MESSAGE} + ${'handleMultipleDelete'} | ${DELETE_TAGS_SUCCESS_MESSAGE} | ${DELETE_TAGS_ERROR_MESSAGE} + `( + 'when the user is not an admin alert behaves correctly on $deleteType', + ({ deleteType, successTitle, errorTitle }) => { + beforeEach(() => { + store.commit('SET_INITIAL_STATE', { ...config }); + }); + + describe('when delete is successful', () => { + beforeEach(() => { + dispatchSpy.mockResolvedValue(); + mountComponent(); + return wrapper.vm[deleteType]('foo'); + }); + + it('alert exist and text is appropriate', () => { + expect(findAlert().exists()).toBe(true); + expect(findAlert().text()).toBe(successTitle); + }); + }); + + describe('when delete is not successful', () => { + beforeEach(() => { + mountComponent(); + dispatchSpy.mockRejectedValue(); + return wrapper.vm[deleteType]('foo'); + }); + + it('alert exist and text is appropriate', () => { + expect(findAlert().exists()).toBe(true); + expect(findAlert().text()).toBe(errorTitle); + }); + }); + }, + ); + }); }); |