Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.js286
1 files changed, 149 insertions, 137 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
index 9491b52c888..419d67e239f 100644
--- a/spec/frontend/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_projects/components/import_projects_table_spec.js
@@ -1,11 +1,24 @@
+import { nextTick } from 'vue';
import Vuex from 'vuex';
-import { createLocalVue, mount } from '@vue/test-utils';
-import { state, actions, getters, mutations } from '~/import_projects/store';
-import importProjectsTable from '~/import_projects/components/import_projects_table.vue';
-import STATUS_MAP from '~/import_projects/constants';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon, GlButton } from '@gitlab/ui';
+import { state, getters } from '~/import_projects/store';
+import eventHub from '~/import_projects/event_hub';
+import ImportProjectsTable from '~/import_projects/components/import_projects_table.vue';
+import ImportedProjectTableRow from '~/import_projects/components/imported_project_table_row.vue';
+import ProviderRepoTableRow from '~/import_projects/components/provider_repo_table_row.vue';
+import IncompatibleRepoTableRow from '~/import_projects/components/incompatible_repo_table_row.vue';
+
+jest.mock('~/import_projects/event_hub', () => ({
+ $emit: jest.fn(),
+}));
describe('ImportProjectsTable', () => {
- let vm;
+ let wrapper;
+
+ const findFilterField = () =>
+ wrapper.find('input[data-qa-selector="githubish_import_filter_field"]');
+
const providerTitle = 'THE PROVIDER';
const providerRepo = { id: 10, sanitizedName: 'sanitizedName', fullName: 'fullName' };
const importedProject = {
@@ -16,176 +29,175 @@ describe('ImportProjectsTable', () => {
importSource: 'importSource',
};
- function initStore() {
- const stubbedActions = {
- ...actions,
- fetchJobs: jest.fn(),
- fetchRepos: jest.fn(actions.requestRepos),
- fetchImport: jest.fn(actions.requestImport),
- };
-
- const store = new Vuex.Store({
- state: state(),
- actions: stubbedActions,
- mutations,
- getters,
- });
-
- return store;
- }
-
- function mountComponent() {
+ const findImportAllButton = () =>
+ wrapper
+ .findAll(GlButton)
+ .filter(w => w.props().variant === 'success')
+ .at(0);
+
+ function createComponent({
+ state: initialState,
+ getters: customGetters,
+ slots,
+ filterable,
+ } = {}) {
const localVue = createLocalVue();
localVue.use(Vuex);
- const store = initStore();
+ const store = new Vuex.Store({
+ state: { ...state(), ...initialState },
+ getters: {
+ ...getters,
+ ...customGetters,
+ },
+ actions: {
+ fetchRepos: jest.fn(),
+ fetchReposFiltered: jest.fn(),
+ fetchJobs: jest.fn(),
+ stopJobsPolling: jest.fn(),
+ clearJobsEtagPoll: jest.fn(),
+ setFilter: jest.fn(),
+ },
+ });
- const component = mount(importProjectsTable, {
+ wrapper = shallowMount(ImportProjectsTable, {
localVue,
store,
propsData: {
providerTitle,
+ filterable,
},
+ slots,
});
-
- return component.vm;
}
- beforeEach(() => {
- vm = mountComponent();
- });
-
afterEach(() => {
- vm.$destroy();
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
});
- it('renders a loading icon while repos are loading', () =>
- vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).not.toBeNull();
- }));
-
- it('renders a table with imported projects and provider repos', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [importedProject],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
+ it('renders a loading icon while repos are loading', () => {
+ createComponent({
+ state: {
+ isLoadingRepos: true,
+ },
});
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).toBeNull();
- expect(vm.$el.querySelector('.table')).not.toBeNull();
- expect(vm.$el.querySelector('.import-jobs-from-col').innerText).toMatch(
- `From ${providerTitle}`,
- );
-
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
- });
+ expect(wrapper.contains(GlLoadingIcon)).toBe(true);
});
- it('renders an empty state if there are no imported projects or provider repos', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [],
- namespaces: [],
+ it('renders a table with imported projects and provider repos', () => {
+ createComponent({
+ state: {
+ importedProjects: [importedProject],
+ providerRepos: [providerRepo],
+ incompatibleRepos: [{ ...providerRepo, id: 11 }],
+ namespaces: [{ path: 'path' }],
+ },
});
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.js-loading-button-icon')).toBeNull();
- expect(vm.$el.querySelector('.table')).toBeNull();
- expect(vm.$el.innerText).toMatch(`No ${providerTitle} repositories found`);
- });
+ expect(wrapper.contains(GlLoadingIcon)).toBe(false);
+ expect(wrapper.contains('table')).toBe(true);
+ expect(
+ wrapper
+ .findAll('th')
+ .filter(w => w.text() === `From ${providerTitle}`)
+ .isEmpty(),
+ ).toBe(false);
+
+ expect(wrapper.contains(ProviderRepoTableRow)).toBe(true);
+ expect(wrapper.contains(ImportedProjectTableRow)).toBe(true);
+ expect(wrapper.contains(IncompatibleRepoTableRow)).toBe(true);
});
- it('shows loading spinner when bulk import button is clicked', () => {
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
- });
-
- return vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
-
- vm.$el.querySelector('.js-import-all').click();
- })
- .then(() => vm.$nextTick())
- .then(() => {
- expect(vm.$el.querySelector('.js-import-all .js-loading-button-icon')).not.toBeNull();
+ it.each`
+ hasIncompatibleRepos | buttonText
+ ${false} | ${'Import all repositories'}
+ ${true} | ${'Import all compatible repositories'}
+ `(
+ 'import all button has "$buttonText" text when hasIncompatibleRepos is $hasIncompatibleRepos',
+ ({ hasIncompatibleRepos, buttonText }) => {
+ createComponent({
+ state: {
+ providerRepos: [providerRepo],
+ },
+ getters: {
+ hasIncompatibleRepos: () => hasIncompatibleRepos,
+ },
});
- });
- it('imports provider repos if bulk import button is clicked', () => {
- mountComponent();
+ expect(findImportAllButton().text()).toBe(buttonText);
+ },
+ );
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [],
- providerRepos: [providerRepo],
- namespaces: [{ path: 'path' }],
+ it('renders an empty state if there are no projects available', () => {
+ createComponent({
+ state: {
+ importedProjects: [],
+ providerRepos: [],
+ incompatibleProjects: [],
+ },
});
- return vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).not.toBeNull();
-
- vm.$store.dispatch('receiveImportSuccess', { importedProject, repoId: providerRepo.id });
- })
- .then(() => vm.$nextTick())
- .then(() => {
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector('.js-provider-repo')).toBeNull();
- });
+ expect(wrapper.contains(ProviderRepoTableRow)).toBe(false);
+ expect(wrapper.contains(ImportedProjectTableRow)).toBe(false);
+ expect(wrapper.text()).toContain(`No ${providerTitle} repositories found`);
});
- it('polls to update the status of imported projects', () => {
- const updatedProjects = [
- {
- id: importedProject.id,
- importStatus: 'finished',
+ it('sends importAll event when import button is clicked', async () => {
+ createComponent({
+ state: {
+ providerRepos: [providerRepo],
},
- ];
-
- vm.$store.dispatch('receiveReposSuccess', {
- importedProjects: [importedProject],
- providerRepos: [],
- namespaces: [{ path: 'path' }],
});
- return vm
- .$nextTick()
- .then(() => {
- const statusObject = STATUS_MAP[importedProject.importStatus];
+ findImportAllButton().vm.$emit('click');
+ await nextTick();
+ expect(eventHub.$emit).toHaveBeenCalledWith('importAll');
+ });
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector(`.${statusObject.textClass}`).textContent).toMatch(
- statusObject.text,
- );
+ it('shows loading spinner when import is in progress', () => {
+ createComponent({
+ getters: {
+ isImportingAnyRepo: () => true,
+ },
+ });
- expect(vm.$el.querySelector(`.ic-status_${statusObject.icon}`)).not.toBeNull();
+ expect(findImportAllButton().props().loading).toBe(true);
+ });
- vm.$store.dispatch('receiveJobsSuccess', updatedProjects);
- })
- .then(() => vm.$nextTick())
- .then(() => {
- const statusObject = STATUS_MAP[updatedProjects[0].importStatus];
+ it('renders filtering input field by default', () => {
+ createComponent();
+ expect(findFilterField().exists()).toBe(true);
+ });
- expect(vm.$el.querySelector('.js-imported-project')).not.toBeNull();
- expect(vm.$el.querySelector(`.${statusObject.textClass}`).textContent).toMatch(
- statusObject.text,
- );
+ it('does not render filtering input field when filterable is false', () => {
+ createComponent({ filterable: false });
+ expect(findFilterField().exists()).toBe(false);
+ });
- expect(vm.$el.querySelector(`.ic-status_${statusObject.icon}`)).not.toBeNull();
+ 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,
+ },
});
- });
- it('renders filtering input field', () => {
- expect(
- vm.$el.querySelector('input[data-qa-selector="githubish_import_filter_field"]'),
- ).not.toBeNull();
- });
+ expect(wrapper.text().includes(INCOMPATIBLE_TEXT)).toBe(shouldRenderSlot);
+ },
+ );
});