diff options
Diffstat (limited to 'spec/frontend/import_projects/components/import_projects_table_spec.js')
-rw-r--r-- | spec/frontend/import_projects/components/import_projects_table_spec.js | 249 |
1 files changed, 0 insertions, 249 deletions
diff --git a/spec/frontend/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_projects/components/import_projects_table_spec.js deleted file mode 100644 index 7322c7c1ae1..00000000000 --- a/spec/frontend/import_projects/components/import_projects_table_spec.js +++ /dev/null @@ -1,249 +0,0 @@ -import { nextTick } from 'vue'; -import Vuex from 'vuex'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; -import { GlLoadingIcon, GlButton, GlIntersectionObserver } from '@gitlab/ui'; -import state from '~/import_projects/store/state'; -import * as getters from '~/import_projects/store/getters'; -import { STATUSES } from '~/import_projects/constants'; -import ImportProjectsTable from '~/import_projects/components/import_projects_table.vue'; -import ProviderRepoTableRow from '~/import_projects/components/provider_repo_table_row.vue'; - -describe('ImportProjectsTable', () => { - let wrapper; - - const findFilterField = () => - wrapper.find('input[data-qa-selector="githubish_import_filter_field"]'); - - const providerTitle = 'THE PROVIDER'; - const providerRepo = { - importSource: { - id: 10, - sanitizedName: 'sanitizedName', - fullName: 'fullName', - }, - importedProject: null, - }; - - const findImportAllButton = () => - wrapper - .findAll(GlButton) - .filter(w => w.props().variant === 'success') - .at(0); - const findImportAllModal = () => wrapper.find({ ref: 'importAllModal' }); - - const importAllFn = jest.fn(); - const importAllModalShowFn = jest.fn(); - const fetchReposFn = jest.fn(); - - function createComponent({ - state: initialState, - getters: customGetters, - slots, - filterable, - paginatable, - } = {}) { - const localVue = createLocalVue(); - localVue.use(Vuex); - - const store = new Vuex.Store({ - state: { ...state(), ...initialState }, - getters: { - ...getters, - ...customGetters, - }, - actions: { - fetchRepos: fetchReposFn, - fetchJobs: jest.fn(), - fetchNamespaces: jest.fn(), - importAll: importAllFn, - stopJobsPolling: jest.fn(), - clearJobsEtagPoll: jest.fn(), - setFilter: jest.fn(), - }, - }); - - wrapper = shallowMount(ImportProjectsTable, { - localVue, - store, - propsData: { - providerTitle, - filterable, - paginatable, - }, - slots, - stubs: { - GlModal: { template: '<div>Modal!</div>', methods: { show: importAllModalShowFn } }, - }, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - wrapper = null; - } - }); - - it('renders a loading icon while repos are loading', () => { - createComponent({ state: { isLoadingRepos: true } }); - - expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); - }); - - it('renders a loading icon while namespaces are loading', () => { - createComponent({ state: { isLoadingNamespaces: true } }); - - expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); - }); - - it('renders a table with provider repos', () => { - const repositories = [ - { importSource: { id: 1 }, importedProject: null }, - { importSource: { id: 2 }, importedProject: { importStatus: STATUSES.FINISHED } }, - { importSource: { id: 3, incompatible: true }, importedProject: {} }, - ]; - - createComponent({ - state: { namespaces: [{ fullPath: 'path' }], repositories }, - }); - - expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); - expect(wrapper.find('table').exists()).toBe(true); - expect( - wrapper - .findAll('th') - .filter(w => w.text() === `From ${providerTitle}`) - .exists(), - ).toBe(true); - - expect(wrapper.findAll(ProviderRepoTableRow)).toHaveLength(repositories.length); - }); - - it.each` - hasIncompatibleRepos | count | buttonText - ${false} | ${1} | ${'Import 1 repository'} - ${true} | ${1} | ${'Import 1 compatible repository'} - ${false} | ${5} | ${'Import 5 repositories'} - ${true} | ${5} | ${'Import 5 compatible repositories'} - `( - 'import all button has "$buttonText" text when hasIncompatibleRepos is $hasIncompatibleRepos and repos count is $count', - ({ hasIncompatibleRepos, buttonText, count }) => { - createComponent({ - state: { - providerRepos: [providerRepo], - }, - getters: { - hasIncompatibleRepos: () => hasIncompatibleRepos, - importAllCount: () => count, - }, - }); - - expect(findImportAllButton().text()).toBe(buttonText); - }, - ); - - it('renders an empty state if there are no repositories available', () => { - createComponent({ state: { repositories: [] } }); - - expect(wrapper.find(ProviderRepoTableRow).exists()).toBe(false); - expect(wrapper.text()).toContain(`No ${providerTitle} repositories found`); - }); - - it('opens confirmation modal when import all button is clicked', async () => { - createComponent({ state: { repositories: [providerRepo] } }); - - findImportAllButton().vm.$emit('click'); - await nextTick(); - - expect(importAllModalShowFn).toHaveBeenCalled(); - }); - - it('triggers importAll action when modal is confirmed', async () => { - createComponent({ state: { providerRepos: [providerRepo] } }); - - findImportAllModal().vm.$emit('ok'); - await nextTick(); - - expect(importAllFn).toHaveBeenCalled(); - }); - - it('shows loading spinner when import is in progress', () => { - createComponent({ getters: { isImportingAnyRepo: () => true } }); - - expect(findImportAllButton().props().loading).toBe(true); - }); - - it('renders filtering input field by default', () => { - createComponent(); - - expect(findFilterField().exists()).toBe(true); - }); - - it('does not render filtering input field when filterable is false', () => { - createComponent({ filterable: false }); - - expect(findFilterField().exists()).toBe(false); - }); - - describe('when paginatable is set to true', () => { - const pageInfo = { page: 1 }; - - beforeEach(() => { - createComponent({ - state: { - namespaces: [{ fullPath: 'path' }], - pageInfo, - repositories: [ - { importSource: { id: 1 }, importedProject: null, importStatus: STATUSES.NONE }, - ], - }, - paginatable: true, - }); - }); - - it('does not call fetchRepos on mount', () => { - expect(fetchReposFn).not.toHaveBeenCalled(); - }); - - it('renders intersection observer component', () => { - expect(wrapper.find(GlIntersectionObserver).exists()).toBe(true); - }); - - it('calls fetchRepos when intersection observer appears', async () => { - wrapper.find(GlIntersectionObserver).vm.$emit('appear'); - - await nextTick(); - - expect(fetchReposFn).toHaveBeenCalled(); - }); - }); - - it('calls fetchRepos on mount', () => { - createComponent(); - - expect(fetchReposFn).toHaveBeenCalled(); - }); - - it.each` - hasIncompatibleRepos | shouldRenderSlot | action - ${false} | ${false} | ${'does not render'} - ${true} | ${true} | ${'render'} - `( - '$action incompatible-repos-warning slot if hasIncompatibleRepos is $hasIncompatibleRepos', - ({ hasIncompatibleRepos, shouldRenderSlot }) => { - const INCOMPATIBLE_TEXT = 'INCOMPATIBLE!'; - - createComponent({ - getters: { - hasIncompatibleRepos: () => hasIncompatibleRepos, - }, - - slots: { - 'incompatible-repos-warning': INCOMPATIBLE_TEXT, - }, - }); - - expect(wrapper.text().includes(INCOMPATIBLE_TEXT)).toBe(shouldRenderSlot); - }, - ); -}); |