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')
-rw-r--r--spec/frontend/import_projects/components/bitbucket_status_table_spec.js59
-rw-r--r--spec/frontend/import_projects/components/import_projects_table_spec.js249
-rw-r--r--spec/frontend/import_projects/components/provider_repo_table_row_spec.js169
-rw-r--r--spec/frontend/import_projects/store/actions_spec.js398
-rw-r--r--spec/frontend/import_projects/store/getters_spec.js135
-rw-r--r--spec/frontend/import_projects/store/mutations_spec.js319
-rw-r--r--spec/frontend/import_projects/utils_spec.js65
7 files changed, 0 insertions, 1394 deletions
diff --git a/spec/frontend/import_projects/components/bitbucket_status_table_spec.js b/spec/frontend/import_projects/components/bitbucket_status_table_spec.js
deleted file mode 100644
index b65b388fd5f..00000000000
--- a/spec/frontend/import_projects/components/bitbucket_status_table_spec.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { nextTick } from 'vue';
-import { shallowMount } from '@vue/test-utils';
-
-import { GlAlert } from '@gitlab/ui';
-import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
-import ImportProjectsTable from '~/import_projects/components/import_projects_table.vue';
-
-const ImportProjectsTableStub = {
- name: 'ImportProjectsTable',
- template:
- '<div><slot name="incompatible-repos-warning"></slot><slot name="actions"></slot></div>',
-};
-
-describe('BitbucketStatusTable', () => {
- let wrapper;
-
- afterEach(() => {
- if (wrapper) {
- wrapper.destroy();
- wrapper = null;
- }
- });
-
- function createComponent(propsData, importProjectsTableStub = true, slots) {
- wrapper = shallowMount(BitbucketStatusTable, {
- propsData,
- stubs: {
- ImportProjectsTable: importProjectsTableStub,
- },
- slots,
- });
- }
-
- it('renders import table component', () => {
- createComponent({ providerTitle: 'Test' });
- expect(wrapper.find(ImportProjectsTable).exists()).toBe(true);
- });
-
- it('passes alert in incompatible-repos-warning slot', () => {
- createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub);
- expect(wrapper.find(GlAlert).exists()).toBe(true);
- });
-
- it('passes actions slot to import project table component', () => {
- const actionsSlotContent = 'DEMO';
- createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub, {
- actions: actionsSlotContent,
- });
- expect(wrapper.find(ImportProjectsTable).text()).toBe(actionsSlotContent);
- });
-
- it('dismisses alert when requested', async () => {
- createComponent({ providerTitle: 'Test' }, ImportProjectsTableStub);
- wrapper.find(GlAlert).vm.$emit('dismiss');
- await nextTick();
-
- expect(wrapper.find(GlAlert).exists()).toBe(false);
- });
-});
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);
- },
- );
-});
diff --git a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_projects/components/provider_repo_table_row_spec.js
deleted file mode 100644
index 03e30ef610e..00000000000
--- a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js
+++ /dev/null
@@ -1,169 +0,0 @@
-import { nextTick } from 'vue';
-import Vuex from 'vuex';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import { GlBadge } from '@gitlab/ui';
-import ProviderRepoTableRow from '~/import_projects/components/provider_repo_table_row.vue';
-import ImportStatus from '~/import_projects/components/import_status.vue';
-import { STATUSES } from '~/import_projects/constants';
-import Select2Select from '~/vue_shared/components/select2_select.vue';
-
-describe('ProviderRepoTableRow', () => {
- let wrapper;
- const fetchImport = jest.fn();
- const setImportTarget = jest.fn();
- const fakeImportTarget = {
- targetNamespace: 'target',
- newName: 'newName',
- };
-
- const availableNamespaces = [
- { text: 'Groups', children: [{ id: 'test', text: 'test' }] },
- { text: 'Users', children: [{ id: 'root', text: 'root' }] },
- ];
-
- function initStore(initialState) {
- const store = new Vuex.Store({
- state: initialState,
- getters: {
- getImportTarget: () => () => fakeImportTarget,
- },
- actions: { fetchImport, setImportTarget },
- });
-
- return store;
- }
-
- const findImportButton = () => {
- const buttons = wrapper.findAll('button').filter(node => node.text() === 'Import');
-
- return buttons.length ? buttons.at(0) : buttons;
- };
-
- function mountComponent(props) {
- const localVue = createLocalVue();
- localVue.use(Vuex);
-
- const store = initStore();
-
- wrapper = shallowMount(ProviderRepoTableRow, {
- localVue,
- store,
- propsData: { availableNamespaces, ...props },
- });
- }
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('when rendering importable project', () => {
- const repo = {
- importSource: {
- id: 'remote-1',
- fullName: 'fullName',
- providerLink: 'providerLink',
- },
- };
-
- beforeEach(() => {
- mountComponent({ repo });
- });
-
- it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
-
- expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
- expect(providerLink.text()).toMatch(repo.importSource.fullName);
- });
-
- it('renders empty import status', () => {
- expect(wrapper.find(ImportStatus).props().status).toBe(STATUSES.NONE);
- });
-
- it('renders a select2 namespace select', () => {
- expect(wrapper.find(Select2Select).exists()).toBe(true);
- expect(wrapper.find(Select2Select).props().options.data).toBe(availableNamespaces);
- });
-
- it('renders import button', () => {
- expect(findImportButton().exists()).toBe(true);
- });
-
- it('imports repo when clicking import button', async () => {
- findImportButton().trigger('click');
-
- await nextTick();
-
- const { calls } = fetchImport.mock;
-
- expect(calls).toHaveLength(1);
- expect(calls[0][1]).toBe(repo.importSource.id);
- });
- });
-
- describe('when rendering imported project', () => {
- const repo = {
- importSource: {
- id: 'remote-1',
- fullName: 'fullName',
- providerLink: 'providerLink',
- },
- importedProject: {
- id: 1,
- fullPath: 'fullPath',
- importSource: 'importSource',
- importStatus: STATUSES.FINISHED,
- },
- };
-
- beforeEach(() => {
- mountComponent({ repo });
- });
-
- it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
-
- expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
- expect(providerLink.text()).toMatch(repo.importSource.fullName);
- });
-
- it('renders proper import status', () => {
- expect(wrapper.find(ImportStatus).props().status).toBe(repo.importedProject.importStatus);
- });
-
- it('does not renders a namespace select', () => {
- expect(wrapper.find(Select2Select).exists()).toBe(false);
- });
-
- it('does not render import button', () => {
- expect(findImportButton().exists()).toBe(false);
- });
- });
-
- describe('when rendering incompatible project', () => {
- const repo = {
- importSource: {
- id: 'remote-1',
- fullName: 'fullName',
- providerLink: 'providerLink',
- incompatible: true,
- },
- };
-
- beforeEach(() => {
- mountComponent({ repo });
- });
-
- it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
-
- expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
- expect(providerLink.text()).toMatch(repo.importSource.fullName);
- });
-
- it('renders badge with error', () => {
- expect(wrapper.find(GlBadge).text()).toBe('Incompatible project');
- });
- });
-});
diff --git a/spec/frontend/import_projects/store/actions_spec.js b/spec/frontend/import_projects/store/actions_spec.js
deleted file mode 100644
index 06afb20c6a2..00000000000
--- a/spec/frontend/import_projects/store/actions_spec.js
+++ /dev/null
@@ -1,398 +0,0 @@
-import MockAdapter from 'axios-mock-adapter';
-import testAction from 'helpers/vuex_action_helper';
-import { TEST_HOST } from 'helpers/test_constants';
-import { deprecatedCreateFlash as createFlash } from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import {
- REQUEST_REPOS,
- RECEIVE_REPOS_SUCCESS,
- RECEIVE_REPOS_ERROR,
- REQUEST_IMPORT,
- RECEIVE_IMPORT_SUCCESS,
- RECEIVE_IMPORT_ERROR,
- RECEIVE_JOBS_SUCCESS,
- REQUEST_NAMESPACES,
- RECEIVE_NAMESPACES_SUCCESS,
- RECEIVE_NAMESPACES_ERROR,
- SET_PAGE,
- SET_FILTER,
-} from '~/import_projects/store/mutation_types';
-import actionsFactory from '~/import_projects/store/actions';
-import { getImportTarget } from '~/import_projects/store/getters';
-import state from '~/import_projects/store/state';
-import { STATUSES } from '~/import_projects/constants';
-
-jest.mock('~/flash');
-
-const MOCK_ENDPOINT = `${TEST_HOST}/endpoint.json`;
-const endpoints = {
- reposPath: MOCK_ENDPOINT,
- importPath: MOCK_ENDPOINT,
- jobsPath: MOCK_ENDPOINT,
- namespacesPath: MOCK_ENDPOINT,
-};
-
-const {
- clearJobsEtagPoll,
- stopJobsPolling,
- importAll,
- fetchRepos,
- fetchImport,
- fetchJobs,
- fetchNamespaces,
- setFilter,
-} = actionsFactory({
- endpoints,
-});
-
-describe('import_projects store actions', () => {
- let localState;
- const importRepoId = 1;
- const otherImportRepoId = 2;
- const defaultTargetNamespace = 'default';
- const sanitizedName = 'sanitizedName';
- const defaultImportTarget = { newName: sanitizedName, targetNamespace: defaultTargetNamespace };
-
- beforeEach(() => {
- localState = {
- ...state(),
- defaultTargetNamespace,
- repositories: [
- { importSource: { id: importRepoId, sanitizedName }, importStatus: STATUSES.NONE },
- {
- importSource: { id: otherImportRepoId, sanitizedName: 's2' },
- importStatus: STATUSES.NONE,
- },
- {
- importSource: { id: 3, sanitizedName: 's3', incompatible: true },
- importStatus: STATUSES.NONE,
- },
- ],
- provider: 'provider',
- };
-
- localState.getImportTarget = getImportTarget(localState);
- });
-
- describe('fetchRepos', () => {
- let mock;
- const payload = { imported_projects: [{}], provider_repos: [{}] };
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => mock.restore());
-
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
- mock.onGet(MOCK_ENDPOINT).reply(200, payload);
-
- return testAction(
- fetchRepos,
- null,
- localState,
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- {
- type: RECEIVE_REPOS_SUCCESS,
- payload: convertObjectPropsToCamelCase(payload, { deep: true }),
- },
- ],
- [],
- );
- });
-
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_ERROR and SET_PAGE again mutations on an unsuccessful request', () => {
- mock.onGet(MOCK_ENDPOINT).reply(500);
-
- return testAction(
- fetchRepos,
- null,
- localState,
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- { type: SET_PAGE, payload: 0 },
- { type: RECEIVE_REPOS_ERROR },
- ],
- [],
- );
- });
-
- it('includes page in url query params', async () => {
- let requestedUrl;
- mock.onGet().reply(config => {
- requestedUrl = config.url;
- return [200, payload];
- });
-
- const localStateWithPage = { ...localState, pageInfo: { page: 2 } };
-
- await testAction(fetchRepos, null, localStateWithPage, expect.any(Array), expect.any(Array));
-
- expect(requestedUrl).toBe(`${MOCK_ENDPOINT}?page=${localStateWithPage.pageInfo.page + 1}`);
- });
-
- it('correctly updates current page on an unsuccessful request', () => {
- mock.onGet(MOCK_ENDPOINT).reply(500);
- const CURRENT_PAGE = 5;
-
- return testAction(
- fetchRepos,
- null,
- { ...localState, pageInfo: { page: CURRENT_PAGE } },
- expect.arrayContaining([
- { type: SET_PAGE, payload: CURRENT_PAGE + 1 },
- { type: SET_PAGE, payload: CURRENT_PAGE },
- ]),
- [],
- );
- });
-
- describe('when rate limited', () => {
- it('commits RECEIVE_REPOS_ERROR and shows rate limited error message', async () => {
- mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(429);
-
- await testAction(
- fetchRepos,
- null,
- { ...localState, filter: 'filter' },
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- { type: SET_PAGE, payload: 0 },
- { type: RECEIVE_REPOS_ERROR },
- ],
- [],
- );
-
- expect(createFlash).toHaveBeenCalledWith('Provider rate limit exceeded. Try again later');
- });
- });
-
- describe('when filtered', () => {
- it('fetches repos with filter applied', () => {
- mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, payload);
-
- return testAction(
- fetchRepos,
- null,
- { ...localState, filter: 'filter' },
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- {
- type: RECEIVE_REPOS_SUCCESS,
- payload: convertObjectPropsToCamelCase(payload, { deep: true }),
- },
- ],
- [],
- );
- });
- });
- });
-
- describe('fetchImport', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => mock.restore());
-
- it('commits REQUEST_IMPORT and REQUEST_IMPORT_SUCCESS mutations on a successful request', () => {
- const importedProject = { name: 'imported/project' };
- mock.onPost(MOCK_ENDPOINT).reply(200, importedProject);
-
- return testAction(
- fetchImport,
- importRepoId,
- localState,
- [
- {
- type: REQUEST_IMPORT,
- payload: { repoId: importRepoId, importTarget: defaultImportTarget },
- },
- {
- type: RECEIVE_IMPORT_SUCCESS,
- payload: {
- importedProject: convertObjectPropsToCamelCase(importedProject, { deep: true }),
- repoId: importRepoId,
- },
- },
- ],
- [],
- );
- });
-
- it('commits REQUEST_IMPORT and RECEIVE_IMPORT_ERROR and shows generic error message on an unsuccessful request', async () => {
- mock.onPost(MOCK_ENDPOINT).reply(500);
-
- await testAction(
- fetchImport,
- importRepoId,
- localState,
- [
- {
- type: REQUEST_IMPORT,
- payload: { repoId: importRepoId, importTarget: defaultImportTarget },
- },
- { type: RECEIVE_IMPORT_ERROR, payload: importRepoId },
- ],
- [],
- );
-
- expect(createFlash).toHaveBeenCalledWith('Importing the project failed');
- });
-
- it('commits REQUEST_IMPORT and RECEIVE_IMPORT_ERROR and shows detailed error message on an unsuccessful request with errors fields in response', async () => {
- const ERROR_MESSAGE = 'dummy';
- mock.onPost(MOCK_ENDPOINT).reply(500, { errors: ERROR_MESSAGE });
-
- await testAction(
- fetchImport,
- importRepoId,
- localState,
- [
- {
- type: REQUEST_IMPORT,
- payload: { repoId: importRepoId, importTarget: defaultImportTarget },
- },
- { type: RECEIVE_IMPORT_ERROR, payload: importRepoId },
- ],
- [],
- );
-
- expect(createFlash).toHaveBeenCalledWith(`Importing the project failed: ${ERROR_MESSAGE}`);
- });
- });
-
- describe('fetchJobs', () => {
- let mock;
- const updatedProjects = [{ name: 'imported/project' }, { name: 'provider/repo' }];
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- stopJobsPolling();
- clearJobsEtagPoll();
- });
-
- afterEach(() => mock.restore());
-
- it('commits RECEIVE_JOBS_SUCCESS mutation on a successful request', async () => {
- mock.onGet(MOCK_ENDPOINT).reply(200, updatedProjects);
-
- await testAction(
- fetchJobs,
- null,
- localState,
- [
- {
- type: RECEIVE_JOBS_SUCCESS,
- payload: convertObjectPropsToCamelCase(updatedProjects, { deep: true }),
- },
- ],
- [],
- );
- });
-
- describe('when filtered', () => {
- beforeEach(() => {
- localState.filter = 'filter';
- });
-
- it('fetches realtime changes with filter applied', () => {
- mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, updatedProjects);
-
- return testAction(
- fetchJobs,
- null,
- localState,
- [
- {
- type: RECEIVE_JOBS_SUCCESS,
- payload: convertObjectPropsToCamelCase(updatedProjects, { deep: true }),
- },
- ],
- [],
- );
- });
- });
- });
-
- describe('fetchNamespaces', () => {
- let mock;
- const namespaces = [{ full_name: 'test/ns1' }, { full_name: 'test_ns2' }];
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => mock.restore());
-
- it('commits REQUEST_NAMESPACES and RECEIVE_NAMESPACES_SUCCESS on success', async () => {
- mock.onGet(MOCK_ENDPOINT).reply(200, namespaces);
-
- await testAction(
- fetchNamespaces,
- null,
- localState,
- [
- { type: REQUEST_NAMESPACES },
- {
- type: RECEIVE_NAMESPACES_SUCCESS,
- payload: convertObjectPropsToCamelCase(namespaces, { deep: true }),
- },
- ],
- [],
- );
- });
-
- it('commits REQUEST_NAMESPACES and RECEIVE_NAMESPACES_ERROR and shows generic error message on an unsuccessful request', async () => {
- mock.onGet(MOCK_ENDPOINT).reply(500);
-
- await testAction(
- fetchNamespaces,
- null,
- localState,
- [{ type: REQUEST_NAMESPACES }, { type: RECEIVE_NAMESPACES_ERROR }],
- [],
- );
-
- expect(createFlash).toHaveBeenCalledWith('Requesting namespaces failed');
- });
- });
-
- describe('importAll', () => {
- it('dispatches multiple fetchImport actions', async () => {
- await testAction(
- importAll,
- null,
- localState,
- [],
- [
- { type: 'fetchImport', payload: importRepoId },
- { type: 'fetchImport', payload: otherImportRepoId },
- ],
- );
- });
- });
-
- describe('setFilter', () => {
- it('dispatches sets the filter value and dispatches fetchRepos', async () => {
- await testAction(
- setFilter,
- 'filteredRepo',
- localState,
- [{ type: SET_FILTER, payload: 'filteredRepo' }],
- [{ type: 'fetchRepos' }],
- );
- });
- });
-});
diff --git a/spec/frontend/import_projects/store/getters_spec.js b/spec/frontend/import_projects/store/getters_spec.js
deleted file mode 100644
index 1ce42e534ea..00000000000
--- a/spec/frontend/import_projects/store/getters_spec.js
+++ /dev/null
@@ -1,135 +0,0 @@
-import {
- isLoading,
- isImportingAnyRepo,
- hasIncompatibleRepos,
- hasImportableRepos,
- importAllCount,
- getImportTarget,
-} from '~/import_projects/store/getters';
-import { STATUSES } from '~/import_projects/constants';
-import state from '~/import_projects/store/state';
-
-const IMPORTED_REPO = {
- importSource: {},
- importedProject: { fullPath: 'some/path', importStatus: STATUSES.FINISHED },
-};
-
-const IMPORTABLE_REPO = {
- importSource: { id: 'some-id', sanitizedName: 'sanitized' },
- importedProject: null,
-};
-
-const INCOMPATIBLE_REPO = {
- importSource: { incompatible: true },
-};
-
-describe('import_projects store getters', () => {
- let localState;
-
- beforeEach(() => {
- localState = state();
- });
-
- it.each`
- isLoadingRepos | isLoadingNamespaces | isLoadingValue
- ${false} | ${false} | ${false}
- ${true} | ${false} | ${true}
- ${false} | ${true} | ${true}
- ${true} | ${true} | ${true}
- `(
- 'isLoading returns $isLoadingValue when isLoadingRepos is $isLoadingRepos and isLoadingNamespaces is $isLoadingNamespaces',
- ({ isLoadingRepos, isLoadingNamespaces, isLoadingValue }) => {
- Object.assign(localState, {
- isLoadingRepos,
- isLoadingNamespaces,
- });
-
- expect(isLoading(localState)).toBe(isLoadingValue);
- },
- );
-
- it.each`
- importStatus | value
- ${STATUSES.NONE} | ${false}
- ${STATUSES.SCHEDULING} | ${true}
- ${STATUSES.SCHEDULED} | ${true}
- ${STATUSES.STARTED} | ${true}
- ${STATUSES.FINISHED} | ${false}
- `(
- 'isImportingAnyRepo returns $value when project with $importStatus status is available',
- ({ importStatus, value }) => {
- localState.repositories = [{ importedProject: { importStatus } }];
-
- expect(isImportingAnyRepo(localState)).toBe(value);
- },
- );
-
- it('isImportingAnyRepo returns false when project with no defined importStatus status is available', () => {
- localState.repositories = [{ importSource: {} }];
-
- expect(isImportingAnyRepo(localState)).toBe(false);
- });
-
- describe('hasIncompatibleRepos', () => {
- it('returns true if there are any incompatible projects', () => {
- localState.repositories = [IMPORTABLE_REPO, IMPORTED_REPO, INCOMPATIBLE_REPO];
-
- expect(hasIncompatibleRepos(localState)).toBe(true);
- });
-
- it('returns false if there are no incompatible projects', () => {
- localState.repositories = [IMPORTABLE_REPO, IMPORTED_REPO];
-
- expect(hasIncompatibleRepos(localState)).toBe(false);
- });
- });
-
- describe('hasImportableRepos', () => {
- it('returns true if there are any importable projects ', () => {
- localState.repositories = [IMPORTABLE_REPO, IMPORTED_REPO, INCOMPATIBLE_REPO];
-
- expect(hasImportableRepos(localState)).toBe(true);
- });
-
- it('returns false if there are no importable projects', () => {
- localState.repositories = [IMPORTED_REPO, INCOMPATIBLE_REPO];
-
- expect(hasImportableRepos(localState)).toBe(false);
- });
- });
-
- describe('importAllCount', () => {
- it('returns count of available importable projects ', () => {
- localState.repositories = [
- IMPORTABLE_REPO,
- IMPORTABLE_REPO,
- IMPORTED_REPO,
- INCOMPATIBLE_REPO,
- ];
-
- expect(importAllCount(localState)).toBe(2);
- });
- });
-
- describe('getImportTarget', () => {
- it('returns default value if no custom target available', () => {
- localState.defaultTargetNamespace = 'default';
- localState.repositories = [IMPORTABLE_REPO];
-
- expect(getImportTarget(localState)(IMPORTABLE_REPO.importSource.id)).toStrictEqual({
- newName: IMPORTABLE_REPO.importSource.sanitizedName,
- targetNamespace: localState.defaultTargetNamespace,
- });
- });
-
- it('returns custom import target if available', () => {
- const fakeTarget = { newName: 'something', targetNamespace: 'ns' };
- localState.repositories = [IMPORTABLE_REPO];
- localState.customImportTargets[IMPORTABLE_REPO.importSource.id] = fakeTarget;
-
- expect(getImportTarget(localState)(IMPORTABLE_REPO.importSource.id)).toStrictEqual(
- fakeTarget,
- );
- });
- });
-});
diff --git a/spec/frontend/import_projects/store/mutations_spec.js b/spec/frontend/import_projects/store/mutations_spec.js
deleted file mode 100644
index 5d78a7fa9e7..00000000000
--- a/spec/frontend/import_projects/store/mutations_spec.js
+++ /dev/null
@@ -1,319 +0,0 @@
-import * as types from '~/import_projects/store/mutation_types';
-import mutations from '~/import_projects/store/mutations';
-import getInitialState from '~/import_projects/store/state';
-import { STATUSES } from '~/import_projects/constants';
-
-describe('import_projects store mutations', () => {
- let state;
-
- const SOURCE_PROJECT = {
- id: 1,
- full_name: 'full/name',
- sanitized_name: 'name',
- provider_link: 'https://demo.link/full/name',
- };
- const IMPORTED_PROJECT = {
- name: 'demo',
- importSource: 'something',
- providerLink: 'custom-link',
- importStatus: 'status',
- fullName: 'fullName',
- };
-
- describe(`${types.SET_FILTER}`, () => {
- const NEW_VALUE = 'new-value';
-
- beforeEach(() => {
- state = {
- filter: 'some-value',
- repositories: ['some', ' repositories'],
- pageInfo: { page: 1 },
- };
- mutations[types.SET_FILTER](state, NEW_VALUE);
- });
-
- it('removes current repositories list', () => {
- expect(state.repositories.length).toBe(0);
- });
-
- it('resets current page to 0', () => {
- expect(state.pageInfo.page).toBe(0);
- });
- });
-
- describe(`${types.REQUEST_REPOS}`, () => {
- it('sets repos loading flag to true', () => {
- state = {};
-
- mutations[types.REQUEST_REPOS](state);
-
- expect(state.isLoadingRepos).toBe(true);
- });
- });
-
- describe(`${types.RECEIVE_REPOS_SUCCESS}`, () => {
- describe('with legacy response format', () => {
- describe('for imported projects', () => {
- const response = {
- importedProjects: [IMPORTED_PROJECT],
- providerRepos: [],
- };
-
- it('recreates importSource from response', () => {
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
-
- expect(state.repositories[0].importSource).toStrictEqual(
- expect.objectContaining({
- fullName: IMPORTED_PROJECT.importSource,
- sanitizedName: IMPORTED_PROJECT.name,
- providerLink: IMPORTED_PROJECT.providerLink,
- }),
- );
- });
-
- it('passes project to importProject', () => {
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
-
- expect(IMPORTED_PROJECT).toStrictEqual(
- expect.objectContaining(state.repositories[0].importedProject),
- );
- });
- });
-
- describe('for importable projects', () => {
- beforeEach(() => {
- state = getInitialState();
-
- const response = {
- importedProjects: [],
- providerRepos: [SOURCE_PROJECT],
- };
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
- });
-
- it('sets importSource to project', () => {
- expect(state.repositories[0].importSource).toBe(SOURCE_PROJECT);
- });
- });
-
- describe('for incompatible projects', () => {
- const response = {
- importedProjects: [],
- providerRepos: [],
- incompatibleRepos: [SOURCE_PROJECT],
- };
-
- beforeEach(() => {
- state = getInitialState();
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
- });
-
- it('sets incompatible flag', () => {
- expect(state.repositories[0].importSource.incompatible).toBe(true);
- });
-
- it('sets importSource to project', () => {
- expect(state.repositories[0].importSource).toStrictEqual(
- expect.objectContaining(SOURCE_PROJECT),
- );
- });
- });
-
- it('sets repos loading flag to false', () => {
- const response = {
- importedProjects: [],
- providerRepos: [],
- };
-
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
-
- expect(state.isLoadingRepos).toBe(false);
- });
- });
-
- it('passes response as it is', () => {
- const response = [];
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
-
- expect(state.repositories).toStrictEqual(response);
- });
-
- it('sets repos loading flag to false', () => {
- const response = [];
-
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_SUCCESS](state, response);
-
- expect(state.isLoadingRepos).toBe(false);
- });
- });
-
- describe(`${types.RECEIVE_REPOS_ERROR}`, () => {
- it('sets repos loading flag to false', () => {
- state = getInitialState();
-
- mutations[types.RECEIVE_REPOS_ERROR](state);
-
- expect(state.isLoadingRepos).toBe(false);
- });
- });
-
- describe(`${types.REQUEST_IMPORT}`, () => {
- beforeEach(() => {
- const REPO_ID = 1;
- const importTarget = { targetNamespace: 'ns', newName: 'name ' };
- state = { repositories: [{ importSource: { id: REPO_ID } }] };
-
- mutations[types.REQUEST_IMPORT](state, { repoId: REPO_ID, importTarget });
- });
-
- it(`sets status to ${STATUSES.SCHEDULING}`, () => {
- expect(state.repositories[0].importedProject.importStatus).toBe(STATUSES.SCHEDULING);
- });
- });
-
- describe(`${types.RECEIVE_IMPORT_SUCCESS}`, () => {
- beforeEach(() => {
- const REPO_ID = 1;
- state = { repositories: [{ importSource: { id: REPO_ID } }] };
-
- mutations[types.RECEIVE_IMPORT_SUCCESS](state, {
- repoId: REPO_ID,
- importedProject: IMPORTED_PROJECT,
- });
- });
-
- it('sets import status', () => {
- expect(state.repositories[0].importedProject.importStatus).toBe(
- IMPORTED_PROJECT.importStatus,
- );
- });
-
- it('sets imported project', () => {
- expect(IMPORTED_PROJECT).toStrictEqual(
- expect.objectContaining(state.repositories[0].importedProject),
- );
- });
- });
-
- describe(`${types.RECEIVE_IMPORT_ERROR}`, () => {
- beforeEach(() => {
- const REPO_ID = 1;
- state = { repositories: [{ importSource: { id: REPO_ID } }] };
-
- mutations[types.RECEIVE_IMPORT_ERROR](state, REPO_ID);
- });
-
- it(`removes importedProject entry`, () => {
- expect(state.repositories[0].importedProject).toBeNull();
- });
- });
-
- describe(`${types.RECEIVE_JOBS_SUCCESS}`, () => {
- it('updates import status of existing project', () => {
- const repoId = 1;
- state = {
- repositories: [{ importedProject: { id: repoId }, importStatus: STATUSES.STARTED }],
- };
- const updatedProjects = [{ id: repoId, importStatus: STATUSES.FINISHED }];
-
- mutations[types.RECEIVE_JOBS_SUCCESS](state, updatedProjects);
-
- expect(state.repositories[0].importedProject.importStatus).toBe(
- updatedProjects[0].importStatus,
- );
- });
- });
-
- describe(`${types.REQUEST_NAMESPACES}`, () => {
- it('sets namespaces loading flag to true', () => {
- state = {};
-
- mutations[types.REQUEST_NAMESPACES](state);
-
- expect(state.isLoadingNamespaces).toBe(true);
- });
- });
-
- describe(`${types.RECEIVE_NAMESPACES_SUCCESS}`, () => {
- const response = [{ fullPath: 'some/path' }];
-
- beforeEach(() => {
- state = {};
- mutations[types.RECEIVE_NAMESPACES_SUCCESS](state, response);
- });
-
- it('stores namespaces to state', () => {
- expect(state.namespaces).toStrictEqual(response);
- });
-
- it('sets namespaces loading flag to false', () => {
- expect(state.isLoadingNamespaces).toBe(false);
- });
- });
-
- describe(`${types.RECEIVE_NAMESPACES_ERROR}`, () => {
- it('sets namespaces loading flag to false', () => {
- state = {};
-
- mutations[types.RECEIVE_NAMESPACES_ERROR](state);
-
- expect(state.isLoadingNamespaces).toBe(false);
- });
- });
-
- describe(`${types.SET_IMPORT_TARGET}`, () => {
- const PROJECT = {
- id: 2,
- sanitizedName: 'sanitizedName',
- };
-
- it('stores custom target if it differs from defaults', () => {
- state = { customImportTargets: {}, repositories: [{ importSource: PROJECT }] };
- const importTarget = { targetNamespace: 'ns', newName: 'name ' };
-
- mutations[types.SET_IMPORT_TARGET](state, { repoId: PROJECT.id, importTarget });
- expect(state.customImportTargets[PROJECT.id]).toBe(importTarget);
- });
-
- it('removes custom target if it is equal to defaults', () => {
- const importTarget = { targetNamespace: 'ns', newName: 'name ' };
- state = {
- defaultTargetNamespace: 'default',
- customImportTargets: {
- [PROJECT.id]: importTarget,
- },
- repositories: [{ importSource: PROJECT }],
- };
-
- mutations[types.SET_IMPORT_TARGET](state, {
- repoId: PROJECT.id,
- importTarget: {
- targetNamespace: state.defaultTargetNamespace,
- newName: PROJECT.sanitizedName,
- },
- });
-
- expect(state.customImportTargets[SOURCE_PROJECT.id]).toBeUndefined();
- });
- });
-
- describe(`${types.SET_PAGE}`, () => {
- it('sets page number', () => {
- const NEW_PAGE = 4;
- state = { pageInfo: { page: 5 } };
-
- mutations[types.SET_PAGE](state, NEW_PAGE);
- expect(state.pageInfo.page).toBe(NEW_PAGE);
- });
- });
-});
diff --git a/spec/frontend/import_projects/utils_spec.js b/spec/frontend/import_projects/utils_spec.js
deleted file mode 100644
index 4e1e16a3184..00000000000
--- a/spec/frontend/import_projects/utils_spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import { isProjectImportable, isIncompatible, getImportStatus } from '~/import_projects/utils';
-import { STATUSES } from '~/import_projects/constants';
-
-describe('import_projects utils', () => {
- const COMPATIBLE_PROJECT = {
- importSource: { incompatible: false },
- };
-
- const INCOMPATIBLE_PROJECT = {
- importSource: { incompatible: true },
- importedProject: null,
- };
-
- describe('isProjectImportable', () => {
- it.each`
- status | result
- ${STATUSES.FINISHED} | ${false}
- ${STATUSES.FAILED} | ${false}
- ${STATUSES.SCHEDULED} | ${false}
- ${STATUSES.STARTED} | ${false}
- ${STATUSES.NONE} | ${true}
- ${STATUSES.SCHEDULING} | ${false}
- `('returns $result when project is compatible and status is $status', ({ status, result }) => {
- expect(
- isProjectImportable({
- ...COMPATIBLE_PROJECT,
- importedProject: { importStatus: status },
- }),
- ).toBe(result);
- });
-
- it('returns true if import status is not defined', () => {
- expect(isProjectImportable({ importSource: {} })).toBe(true);
- });
-
- it('returns false if project is not compatible', () => {
- expect(isProjectImportable(INCOMPATIBLE_PROJECT)).toBe(false);
- });
- });
-
- describe('isIncompatible', () => {
- it('returns true for incompatible project', () => {
- expect(isIncompatible(INCOMPATIBLE_PROJECT)).toBe(true);
- });
-
- it('returns false for compatible project', () => {
- expect(isIncompatible(COMPATIBLE_PROJECT)).toBe(false);
- });
- });
-
- describe('getImportStatus', () => {
- it('returns actual status when project status is provided', () => {
- expect(
- getImportStatus({
- ...COMPATIBLE_PROJECT,
- importedProject: { importStatus: STATUSES.FINISHED },
- }),
- ).toBe(STATUSES.FINISHED);
- });
-
- it('returns NONE as status if import status is not provided', () => {
- expect(getImportStatus(COMPATIBLE_PROJECT)).toBe(STATUSES.NONE);
- });
- });
-});