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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
commitdb384e6b19af03b4c3c82a5760d83a3fd79f7982 (patch)
tree34beaef37df5f47ccbcf5729d7583aae093cffa0 /spec/frontend/import_entities
parent54fd7b1bad233e3944434da91d257fa7f63c3996 (diff)
Add latest changes from gitlab-org/gitlab@16-3-stable-eev16.3.0-rc42
Diffstat (limited to 'spec/frontend/import_entities')
-rw-r--r--spec/frontend/import_entities/components/import_status_spec.js19
-rw-r--r--spec/frontend/import_entities/components/import_target_dropdown_spec.js99
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_actions_cell_spec.js48
-rw-r--r--spec/frontend/import_entities/import_projects/components/github_status_table_spec.js1
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js1
-rw-r--r--spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js31
-rw-r--r--spec/frontend/import_entities/mock_data.js34
7 files changed, 191 insertions, 42 deletions
diff --git a/spec/frontend/import_entities/components/import_status_spec.js b/spec/frontend/import_entities/components/import_status_spec.js
index 103a3e4ddd1..37c58b9cdf8 100644
--- a/spec/frontend/import_entities/components/import_status_spec.js
+++ b/spec/frontend/import_entities/components/import_status_spec.js
@@ -168,18 +168,14 @@ describe('Import entities status component', () => {
};
describe.each`
- detailsPath | importDetailsPage | partialImport | expectLink
- ${undefined} | ${false} | ${false} | ${false}
- ${undefined} | ${false} | ${true} | ${false}
- ${undefined} | ${true} | ${false} | ${false}
- ${undefined} | ${true} | ${true} | ${false}
- ${mockDetailsPath} | ${false} | ${false} | ${false}
- ${mockDetailsPath} | ${false} | ${true} | ${false}
- ${mockDetailsPath} | ${true} | ${false} | ${false}
- ${mockDetailsPath} | ${true} | ${true} | ${true}
+ detailsPath | partialImport | expectLink
+ ${undefined} | ${false} | ${false}
+ ${undefined} | ${true} | ${false}
+ ${mockDetailsPath} | ${false} | ${false}
+ ${mockDetailsPath} | ${true} | ${true}
`(
- 'when detailsPath is $detailsPath, feature flag importDetailsPage is $importDetailsPage, partial import is $partialImport',
- ({ detailsPath, importDetailsPage, partialImport, expectLink }) => {
+ 'when detailsPath is $detailsPath, partial import is $partialImport',
+ ({ detailsPath, partialImport, expectLink }) => {
beforeEach(() => {
createComponent(
{
@@ -190,7 +186,6 @@ describe('Import entities status component', () => {
{
provide: {
detailsPath,
- glFeatures: { importDetailsPage },
},
},
);
diff --git a/spec/frontend/import_entities/components/import_target_dropdown_spec.js b/spec/frontend/import_entities/components/import_target_dropdown_spec.js
new file mode 100644
index 00000000000..c12baed2374
--- /dev/null
+++ b/spec/frontend/import_entities/components/import_target_dropdown_spec.js
@@ -0,0 +1,99 @@
+import { GlCollapsibleListbox } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { shallowMount } from '@vue/test-utils';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+
+import ImportTargetDropdown from '~/import_entities/components/import_target_dropdown.vue';
+import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
+import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql';
+
+import { mockAvailableNamespaces, mockNamespacesResponse, mockUserNamespace } from '../mock_data';
+
+Vue.use(VueApollo);
+
+describe('ImportTargetDropdown', () => {
+ let wrapper;
+
+ const defaultProps = {
+ selected: mockUserNamespace,
+ userNamespace: mockUserNamespace,
+ };
+
+ const createComponent = ({ props = {} } = {}) => {
+ const apolloProvider = createMockApollo([
+ [
+ searchNamespacesWhereUserCanImportProjectsQuery,
+ jest.fn().mockResolvedValue(mockNamespacesResponse),
+ ],
+ ]);
+
+ wrapper = shallowMount(ImportTargetDropdown, {
+ apolloProvider,
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ });
+ };
+
+ const findListbox = () => wrapper.findComponent(GlCollapsibleListbox);
+ const findListboxUsersItems = () => findListbox().props('items')[0].options;
+ const findListboxGroupsItems = () => findListbox().props('items')[1].options;
+
+ const waitForQuery = async () => {
+ jest.advanceTimersByTime(DEBOUNCE_DELAY);
+ await waitForPromises();
+ };
+
+ it('renders listbox', () => {
+ createComponent();
+
+ expect(findListbox().exists()).toBe(true);
+ });
+
+ it('truncates "toggle-text" when "selected" is too long', () => {
+ const mockSelected = 'a-group-path-that-is-longer-than-24-characters';
+
+ createComponent({
+ props: { selected: mockSelected },
+ });
+
+ expect(findListbox().props('toggleText')).toBe('a-group-path-that-is-lo…');
+ });
+
+ it('passes userNamespace as "Users" group item', () => {
+ createComponent();
+
+ expect(findListboxUsersItems()).toEqual([
+ { text: mockUserNamespace, value: mockUserNamespace },
+ ]);
+ });
+
+ it('passes namespaces from GraphQL as "Groups" group item', async () => {
+ createComponent();
+
+ await waitForQuery();
+
+ expect(findListboxGroupsItems()).toEqual(
+ mockAvailableNamespaces.map((namespace) => ({
+ text: namespace.fullPath,
+ value: namespace.fullPath,
+ })),
+ );
+ });
+
+ it('filters namespaces based on user input', async () => {
+ createComponent();
+
+ findListbox().vm.$emit('search', 'match');
+
+ await waitForQuery();
+
+ expect(findListboxGroupsItems()).toEqual([
+ { text: 'match1', value: 'match1' },
+ { text: 'match2', value: 'match2' },
+ ]);
+ });
+});
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
index 4c13ec555c2..87bee6afd62 100644
--- 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
@@ -1,4 +1,10 @@
-import { GlDropdown, GlIcon, GlDropdownItem } from '@gitlab/ui';
+import {
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
+ GlButtonGroup,
+ GlButton,
+ GlIcon,
+} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ImportActionsCell from '~/import_entities/import_groups/components/import_actions_cell.vue';
@@ -13,6 +19,11 @@ describe('import actions cell', () => {
isInvalid: false,
...props,
},
+ stubs: {
+ GlButtonGroup,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
+ },
});
};
@@ -22,9 +33,9 @@ describe('import actions cell', () => {
});
it('renders import dropdown', () => {
- const dropdown = wrapper.findComponent(GlDropdown);
- expect(dropdown.exists()).toBe(true);
- expect(dropdown.props('text')).toBe('Import with projects');
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Import with projects');
});
it('does not render icon with a hint', () => {
@@ -38,9 +49,9 @@ describe('import actions cell', () => {
});
it('renders re-import dropdown', () => {
- const dropdown = wrapper.findComponent(GlDropdown);
- expect(dropdown.exists()).toBe(true);
- expect(dropdown.props('text')).toBe('Re-import with projects');
+ const button = wrapper.findComponent(GlButton);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Re-import with projects');
});
it('renders icon with a hint', () => {
@@ -55,22 +66,22 @@ describe('import actions cell', () => {
it('does not render import dropdown when group is not available for import', () => {
createComponent({ isAvailableForImport: false });
- const dropdown = wrapper.findComponent(GlDropdown);
+ const dropdown = wrapper.findComponent(GlDisclosureDropdown);
expect(dropdown.exists()).toBe(false);
});
it('renders import dropdown as disabled when group is invalid', () => {
createComponent({ isInvalid: true, isAvailableForImport: true });
- const dropdown = wrapper.findComponent(GlDropdown);
+ const dropdown = wrapper.findComponent(GlDisclosureDropdown);
expect(dropdown.props().disabled).toBe(true);
});
it('emits import-group event when import button is clicked', () => {
createComponent({ isAvailableForImport: true });
- const dropdown = wrapper.findComponent(GlDropdown);
- dropdown.vm.$emit('click');
+ const button = wrapper.findComponent(GlButton);
+ button.vm.$emit('click');
expect(wrapper.emitted('import-group')).toHaveLength(1);
});
@@ -87,23 +98,24 @@ describe('import actions cell', () => {
});
it('render import dropdown', () => {
- const dropdown = wrapper.findComponent(GlDropdown);
- expect(dropdown.props('text')).toBe(`${expectedAction} with projects`);
- expect(dropdown.findComponent(GlDropdownItem).text()).toBe(
+ const button = wrapper.findComponent(GlButton);
+ const dropdown = wrapper.findComponent(GlDisclosureDropdown);
+ expect(button.element).toHaveText(`${expectedAction} with projects`);
+ expect(dropdown.findComponent(GlDisclosureDropdownItem).text()).toBe(
`${expectedAction} without projects`,
);
});
it('request migrate projects by default', () => {
- const dropdown = wrapper.findComponent(GlDropdown);
- dropdown.vm.$emit('click');
+ const button = wrapper.findComponent(GlButton);
+ button.vm.$emit('click');
expect(wrapper.emitted('import-group')[0]).toStrictEqual([{ migrateProjects: true }]);
});
it('request not to migrate projects via dropdown option', () => {
- const dropdown = wrapper.findComponent(GlDropdown);
- dropdown.findComponent(GlDropdownItem).vm.$emit('click');
+ const dropdown = wrapper.findComponent(GlDisclosureDropdown);
+ dropdown.findComponent(GlDisclosureDropdownItem).vm.$emit('action');
expect(wrapper.emitted('import-group')[0]).toStrictEqual([{ migrateProjects: false }]);
});
diff --git a/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js b/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
index 7eebff7364c..0b9e7a8cb73 100644
--- a/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
@@ -1,6 +1,7 @@
import { GlTabs, GlSearchBoxByClick } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { stubComponent } from 'helpers/stub_component';
diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
index 351bbe5ea28..92d064846bd 100644
--- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlButton, GlIntersectionObserver, GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { STATUSES } from '~/import_entities/constants';
import ImportProjectsTable from '~/import_entities/import_projects/components/import_projects_table.vue';
diff --git a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
index 57e232a4c46..b4890c09fe2 100644
--- a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
@@ -1,9 +1,11 @@
import { GlBadge, GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
-import { STATUSES } from '~/import_entities//constants';
-import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+
+import { STATUSES } from '~/import_entities/constants';
+import ImportTargetDropdown from '~/import_entities/components/import_target_dropdown.vue';
import ImportStatus from '~/import_entities/components/import_status.vue';
import ProviderRepoTableRow from '~/import_entities/import_projects/components/provider_repo_table_row.vue';
@@ -39,8 +41,9 @@ describe('ProviderRepoTableRow', () => {
const findImportButton = () => findButton('Import');
const findReimportButton = () => findButton('Re-import');
- const findGroupDropdown = () => wrapper.findComponent(ImportGroupDropdown);
+ const findImportTargetDropdown = () => wrapper.findComponent(ImportTargetDropdown);
const findImportStatus = () => wrapper.findComponent(ImportStatus);
+ const findProviderLink = () => wrapper.findByTestId('providerLink');
const findCancelButton = () => {
const buttons = wrapper
@@ -55,7 +58,7 @@ describe('ProviderRepoTableRow', () => {
const store = initStore();
- wrapper = shallowMount(ProviderRepoTableRow, {
+ wrapper = shallowMountExtended(ProviderRepoTableRow, {
store,
propsData: { userNamespace, optionalStages: {}, ...props },
});
@@ -75,7 +78,7 @@ describe('ProviderRepoTableRow', () => {
});
it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
+ const providerLink = findProviderLink();
expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
expect(providerLink.text()).toMatch(repo.importSource.fullName);
@@ -86,7 +89,7 @@ describe('ProviderRepoTableRow', () => {
});
it('renders a group namespace select', () => {
- expect(wrapper.findComponent(ImportGroupDropdown).exists()).toBe(true);
+ expect(findImportTargetDropdown().exists()).toBe(true);
});
it('renders import button', () => {
@@ -106,7 +109,11 @@ describe('ProviderRepoTableRow', () => {
it('includes optionalStages to import', async () => {
const OPTIONAL_STAGES = { stage1: true, stage2: false };
- await wrapper.setProps({ optionalStages: OPTIONAL_STAGES });
+
+ mountComponent({
+ repo,
+ optionalStages: OPTIONAL_STAGES,
+ });
findImportButton().vm.$emit('click');
@@ -192,7 +199,7 @@ describe('ProviderRepoTableRow', () => {
});
it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
+ const providerLink = findProviderLink();
expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
expect(providerLink.text()).toMatch(repo.importSource.fullName);
@@ -203,7 +210,7 @@ describe('ProviderRepoTableRow', () => {
});
it('does not render a namespace select', () => {
- expect(findGroupDropdown().exists()).toBe(false);
+ expect(findImportTargetDropdown().exists()).toBe(false);
});
it('does not render import button', () => {
@@ -219,7 +226,7 @@ describe('ProviderRepoTableRow', () => {
await nextTick();
- expect(findGroupDropdown().exists()).toBe(true);
+ expect(findImportTargetDropdown().exists()).toBe(true);
});
it('imports repo when clicking re-import button', async () => {
@@ -282,7 +289,7 @@ describe('ProviderRepoTableRow', () => {
});
it('renders project information', () => {
- const providerLink = wrapper.find('[data-testid=providerLink]');
+ const providerLink = findProviderLink();
expect(providerLink.attributes().href).toMatch(repo.importSource.providerLink);
expect(providerLink.text()).toMatch(repo.importSource.fullName);
diff --git a/spec/frontend/import_entities/mock_data.js b/spec/frontend/import_entities/mock_data.js
new file mode 100644
index 00000000000..9208f99651f
--- /dev/null
+++ b/spec/frontend/import_entities/mock_data.js
@@ -0,0 +1,34 @@
+const mockGroupFactory = (fullPath) => ({
+ id: `gid://gitlab/Group/${fullPath}`,
+ fullPath,
+ name: fullPath,
+ visibility: 'public',
+ webUrl: `http://gdk.test:3000/groups/${fullPath}`,
+ __typename: 'Group',
+});
+
+export const mockAvailableNamespaces = [
+ mockGroupFactory('match1'),
+ mockGroupFactory('unrelated'),
+ mockGroupFactory('match2'),
+];
+
+export const mockNamespacesResponse = {
+ data: {
+ currentUser: {
+ id: 'gid://gitlab/User/1',
+ groups: {
+ nodes: mockAvailableNamespaces,
+ __typename: 'GroupConnection',
+ },
+ namespace: {
+ id: 'gid://gitlab/Namespaces::UserNamespace/1',
+ fullPath: 'root',
+ __typename: 'Namespace',
+ },
+ __typename: 'UserCore',
+ },
+ },
+};
+
+export const mockUserNamespace = 'user1';