summaryrefslogtreecommitdiff
path: root/spec/frontend/import_entities
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 13:18:24 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-20 13:18:24 +0000
commit0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch)
tree4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /spec/frontend/import_entities
parent744144d28e3e7fddc117924fef88de5d9674fe4c (diff)
downloadgitlab-ce-0653e08efd039a5905f3fa4f6e9cef9f5d2f799c.tar.gz
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'spec/frontend/import_entities')
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js90
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js59
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_table_spec.js8
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js29
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js38
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/fixtures.js4
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js2
-rw-r--r--spec/frontend/import_entities/import_projects/store/actions_spec.js29
8 files changed, 199 insertions, 60 deletions
diff --git a/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js
new file mode 100644
index 00000000000..60f0780fdb3
--- /dev/null
+++ b/spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js
@@ -0,0 +1,90 @@
+import { GlButton, GlIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { STATUSES } from '~/import_entities/constants';
+import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
+import { generateFakeEntry } from '../graphql/fixtures';
+
+describe('import actions cell', () => {
+ let wrapper;
+
+ const createComponent = (props) => {
+ wrapper = shallowMount(ImportActionsCell, {
+ propsData: {
+ groupPathRegex: /^[a-zA-Z]+$/,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when import status is NONE', () => {
+ beforeEach(() => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+ });
+
+ it('renders import button', () => {
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Import');
+ });
+
+ it('does not render icon with a hint', () => {
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
+ });
+ });
+
+ describe('when import status is FINISHED', () => {
+ beforeEach(() => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
+ createComponent({ group });
+ });
+
+ it('renders re-import button', () => {
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Re-import');
+ });
+
+ it('renders icon with a hint', () => {
+ const icon = wrapper.findComponent(GlIcon);
+ expect(icon.exists()).toBe(true);
+ expect(icon.attributes().title).toBe(
+ 'Re-import creates a new group. It does not sync with the existing group.',
+ );
+ });
+ });
+
+ it('does not render import button when group import is in progress', () => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.STARTED });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(false);
+ });
+
+ it('renders import button as disabled when there are validation errors', () => {
+ const group = generateFakeEntry({
+ id: 1,
+ status: STATUSES.NONE,
+ validation_errors: [{ field: 'new_name', message: 'something ' }],
+ });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ expect(button.props().disabled).toBe(true);
+ });
+
+ it('emits import-group event when import button is clicked', () => {
+ const group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+
+ const button = wrapper.findComponent(GlButton);
+ button.vm.$emit('click');
+
+ expect(wrapper.emitted('import-group')).toHaveLength(1);
+ });
+});
diff --git a/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js
new file mode 100644
index 00000000000..2a56efd1cbb
--- /dev/null
+++ b/spec/frontend/import_entities/import_groups/components/import_source_cell_spec.js
@@ -0,0 +1,59 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { STATUSES } from '~/import_entities/constants';
+import ImportSourceCell from '~/import_entities/import_groups/components/import_source_cell.vue';
+import { generateFakeEntry } from '../graphql/fixtures';
+
+describe('import source cell', () => {
+ let wrapper;
+ let group;
+
+ const createComponent = (props) => {
+ wrapper = shallowMount(ImportSourceCell, {
+ propsData: {
+ ...props,
+ },
+ stubs: { GlSprintf },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when group status is NONE', () => {
+ beforeEach(() => {
+ group = generateFakeEntry({ id: 1, status: STATUSES.NONE });
+ createComponent({ group });
+ });
+
+ it('renders link to a group', () => {
+ const link = wrapper.findComponent(GlLink);
+ expect(link.attributes().href).toBe(group.web_url);
+ expect(link.text()).toContain(group.full_path);
+ });
+
+ it('does not render last imported line', () => {
+ expect(wrapper.text()).not.toContain('Last imported to');
+ });
+ });
+
+ describe('when group status is FINISHED', () => {
+ beforeEach(() => {
+ group = generateFakeEntry({ id: 1, status: STATUSES.FINISHED });
+ createComponent({ group });
+ });
+
+ it('renders link to a group', () => {
+ const link = wrapper.findComponent(GlLink);
+ expect(link.attributes().href).toBe(group.web_url);
+ expect(link.text()).toContain(group.full_path);
+ });
+
+ it('renders last imported line', () => {
+ expect(wrapper.text()).toMatchInterpolatedText(
+ 'fake_group_1 Last imported to root/last-group1',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/import_entities/import_groups/components/import_table_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
index bbd8463e685..f43e545e049 100644
--- a/spec/frontend/import_entities/import_groups/components/import_table_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
@@ -15,6 +15,7 @@ import stubChildren from 'helpers/stub_children';
import { stubComponent } from 'helpers/stub_component';
import waitForPromises from 'helpers/wait_for_promises';
import { STATUSES } from '~/import_entities/constants';
+import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
import ImportTable from '~/import_entities/import_groups/components/import_table.vue';
import ImportTargetCell from '~/import_entities/import_groups/components/import_target_cell.vue';
import importGroupsMutation from '~/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql';
@@ -163,11 +164,8 @@ describe('import table', () => {
it('invokes importGroups mutation when row button is clicked', async () => {
jest.spyOn(apolloProvider.defaultClient, 'mutate');
- const triggerImportButton = wrapper
- .findAllComponents(GlButton)
- .wrappers.find((w) => w.text() === 'Import');
- triggerImportButton.vm.$emit('click');
+ wrapper.findComponent(ImportActionsCell).vm.$emit('import-group');
await waitForPromises();
expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith({
mutation: importGroupsMutation,
@@ -329,7 +327,7 @@ describe('import table', () => {
});
it('does not allow selecting already started groups', async () => {
- const NEW_GROUPS = [generateFakeEntry({ id: 1, status: STATUSES.FINISHED })];
+ const NEW_GROUPS = [generateFakeEntry({ id: 1, status: STATUSES.STARTED })];
createComponent({
bulkImportSourceGroups: () => ({
diff --git a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
index 8231297e594..be83a61841f 100644
--- a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js
@@ -1,14 +1,10 @@
-import { GlButton, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui';
+import { GlDropdownItem, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue';
import { STATUSES } from '~/import_entities/constants';
import ImportTargetCell from '~/import_entities/import_groups/components/import_target_cell.vue';
import { availableNamespacesFixture } from '../graphql/fixtures';
-Vue.use(VueApollo);
-
const getFakeGroup = (status) => ({
web_url: 'https://fake.host/',
full_path: 'fake_group_1',
@@ -26,9 +22,6 @@ describe('import target cell', () => {
let wrapper;
let group;
- const findByText = (cmp, text) => {
- return wrapper.findAll(cmp).wrappers.find((node) => node.text().indexOf(text) === 0);
- };
const findNameInput = () => wrapper.find(GlFormInput);
const findNamespaceDropdown = () => wrapper.find(ImportGroupDropdown);
@@ -117,10 +110,6 @@ describe('import target cell', () => {
createComponent({ group });
});
- it('does not render Import button', () => {
- expect(findByText(GlButton, 'Import')).toBe(undefined);
- });
-
it('renders namespace dropdown as disabled', () => {
expect(findNamespaceDropdown().attributes('disabled')).toBe('true');
});
@@ -132,17 +121,8 @@ describe('import target cell', () => {
createComponent({ group });
});
- it('does not render Import button', () => {
- expect(findByText(GlButton, 'Import')).toBe(undefined);
- });
-
- it('does not render namespace dropdown', () => {
- expect(findNamespaceDropdown().exists()).toBe(false);
- });
-
- it('renders target as link', () => {
- const TARGET_LINK = `${group.import_target.target_namespace}/${group.import_target.new_name}`;
- expect(findByText(GlLink, TARGET_LINK).exists()).toBe(true);
+ it('renders namespace dropdown as enabled', () => {
+ expect(findNamespaceDropdown().attributes('disabled')).toBe(undefined);
});
});
@@ -179,9 +159,6 @@ describe('import target cell', () => {
},
});
- jest.runOnlyPendingTimers();
- await nextTick();
-
expect(wrapper.text()).toContain(FAKE_ERROR_MESSAGE);
});
});
diff --git a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
index ec50dfd037f..e1d65095888 100644
--- a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
+++ b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
@@ -259,6 +259,10 @@ describe('Bulk import resolvers', () => {
target_namespace: 'root',
new_name: 'group1',
},
+ last_import_target: {
+ target_namespace: 'root',
+ new_name: 'group1',
+ },
validation_errors: [],
},
],
@@ -414,19 +418,32 @@ describe('Bulk import resolvers', () => {
});
});
- it('setImportProgress updates group progress', async () => {
+ it('setImportProgress updates group progress and sets import target', async () => {
const NEW_STATUS = 'dummy';
const FAKE_JOB_ID = 5;
+ const IMPORT_TARGET = {
+ __typename: 'ClientBulkImportTarget',
+ new_name: 'fake_name',
+ target_namespace: 'fake_target',
+ };
const {
data: {
- setImportProgress: { progress },
+ setImportProgress: { progress, last_import_target: lastImportTarget },
},
} = await client.mutate({
mutation: setImportProgressMutation,
- variables: { sourceGroupId: GROUP_ID, status: NEW_STATUS, jobId: FAKE_JOB_ID },
+ variables: {
+ sourceGroupId: GROUP_ID,
+ status: NEW_STATUS,
+ jobId: FAKE_JOB_ID,
+ importTarget: IMPORT_TARGET,
+ },
});
- expect(progress).toMatchObject({
+ expect(lastImportTarget).toStrictEqual(IMPORT_TARGET);
+
+ expect(progress).toStrictEqual({
+ __typename: clientTypenames.BulkImportProgress,
id: FAKE_JOB_ID,
status: NEW_STATUS,
});
@@ -442,7 +459,8 @@ describe('Bulk import resolvers', () => {
variables: { id: FAKE_JOB_ID, status: NEW_STATUS },
});
- expect(statusInResponse).toMatchObject({
+ expect(statusInResponse).toStrictEqual({
+ __typename: clientTypenames.BulkImportProgress,
id: FAKE_JOB_ID,
status: NEW_STATUS,
});
@@ -460,7 +478,13 @@ describe('Bulk import resolvers', () => {
variables: { sourceGroupId: GROUP_ID, field: FAKE_FIELD, message: FAKE_MESSAGE },
});
- expect(validationErrors).toMatchObject([{ field: FAKE_FIELD, message: FAKE_MESSAGE }]);
+ expect(validationErrors).toStrictEqual([
+ {
+ __typename: clientTypenames.BulkImportValidationError,
+ field: FAKE_FIELD,
+ message: FAKE_MESSAGE,
+ },
+ ]);
});
it('removeValidationError removes error from group', async () => {
@@ -481,7 +505,7 @@ describe('Bulk import resolvers', () => {
variables: { sourceGroupId: GROUP_ID, field: FAKE_FIELD },
});
- expect(validationErrors).toMatchObject([]);
+ expect(validationErrors).toStrictEqual([]);
});
});
});
diff --git a/spec/frontend/import_entities/import_groups/graphql/fixtures.js b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
index 6f66066b312..d1bd52693b6 100644
--- a/spec/frontend/import_entities/import_groups/graphql/fixtures.js
+++ b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
@@ -9,6 +9,10 @@ export const generateFakeEntry = ({ id, status, ...rest }) => ({
target_namespace: 'root',
new_name: `group${id}`,
},
+ last_import_target: {
+ target_namespace: 'root',
+ new_name: `last-group${id}`,
+ },
id,
progress: {
id: `test-${id}`,
diff --git a/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js b/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
index bae715edac0..f06babcb149 100644
--- a/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
+++ b/spec/frontend/import_entities/import_groups/graphql/services/source_groups_manager_spec.js
@@ -20,7 +20,7 @@ describe('SourceGroupsManager', () => {
describe('storage management', () => {
const IMPORT_ID = 1;
- const IMPORT_TARGET = { destination_name: 'demo', destination_namespace: 'foo' };
+ const IMPORT_TARGET = { new_name: 'demo', target_namespace: 'foo' };
const STATUS = 'FAKE_STATUS';
const FAKE_GROUP = { id: 1, import_target: IMPORT_TARGET, status: STATUS };
diff --git a/spec/frontend/import_entities/import_projects/store/actions_spec.js b/spec/frontend/import_entities/import_projects/store/actions_spec.js
index f2bfc61381c..0ebe8525b5a 100644
--- a/spec/frontend/import_entities/import_projects/store/actions_spec.js
+++ b/spec/frontend/import_entities/import_projects/store/actions_spec.js
@@ -85,7 +85,7 @@ describe('import_projects store actions', () => {
afterEach(() => mock.restore());
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
+ it('commits REQUEST_REPOS, SET_PAGE, RECEIVE_REPOS_SUCCESS mutations on a successful request', () => {
mock.onGet(MOCK_ENDPOINT).reply(200, payload);
return testAction(
@@ -93,8 +93,8 @@ describe('import_projects store actions', () => {
null,
localState,
[
- { type: SET_PAGE, payload: 1 },
{ type: REQUEST_REPOS },
+ { type: SET_PAGE, payload: 1 },
{
type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),
@@ -104,19 +104,14 @@ describe('import_projects store actions', () => {
);
});
- it('commits SET_PAGE, REQUEST_REPOS, RECEIVE_REPOS_ERROR and SET_PAGE again mutations on an unsuccessful request', () => {
+ it('commits REQUEST_REPOS, RECEIVE_REPOS_ERROR 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 },
- ],
+ [{ type: REQUEST_REPOS }, { type: RECEIVE_REPOS_ERROR }],
[],
);
});
@@ -135,7 +130,7 @@ describe('import_projects store actions', () => {
expect(requestedUrl).toBe(`${MOCK_ENDPOINT}?page=${localStateWithPage.pageInfo.page + 1}`);
});
- it('correctly updates current page on an unsuccessful request', () => {
+ it('correctly keeps current page on an unsuccessful request', () => {
mock.onGet(MOCK_ENDPOINT).reply(500);
const CURRENT_PAGE = 5;
@@ -143,10 +138,7 @@ describe('import_projects store actions', () => {
fetchRepos,
null,
{ ...localState, pageInfo: { page: CURRENT_PAGE } },
- expect.arrayContaining([
- { type: SET_PAGE, payload: CURRENT_PAGE + 1 },
- { type: SET_PAGE, payload: CURRENT_PAGE },
- ]),
+ expect.arrayContaining([]),
[],
);
});
@@ -159,12 +151,7 @@ describe('import_projects store actions', () => {
fetchRepos,
null,
{ ...localState, filter: 'filter' },
- [
- { type: SET_PAGE, payload: 1 },
- { type: REQUEST_REPOS },
- { type: SET_PAGE, payload: 0 },
- { type: RECEIVE_REPOS_ERROR },
- ],
+ [{ type: REQUEST_REPOS }, { type: RECEIVE_REPOS_ERROR }],
[],
);
@@ -183,8 +170,8 @@ describe('import_projects store actions', () => {
null,
{ ...localState, filter: 'filter' },
[
- { type: SET_PAGE, payload: 1 },
{ type: REQUEST_REPOS },
+ { type: SET_PAGE, payload: 1 },
{
type: RECEIVE_REPOS_SUCCESS,
payload: convertObjectPropsToCamelCase(payload, { deep: true }),