Commit 6394f69c authored by Illya Klymov's avatar Illya Klymov

Correctly handle scenario when no top-level groups are available

* remove extra checks for canCreateGroup since user can't reach
  import process without this permission
parent 66e31810
...@@ -33,11 +33,6 @@ export default { ...@@ -33,11 +33,6 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
canCreateGroup: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
...@@ -176,7 +171,6 @@ export default { ...@@ -176,7 +171,6 @@ export default {
:key="group.id" :key="group.id"
:group="group" :group="group"
:available-namespaces="availableNamespaces" :available-namespaces="availableNamespaces"
:can-create-group="canCreateGroup"
@update-target-namespace="updateTargetNamespace(group.id, $event)" @update-target-namespace="updateTargetNamespace(group.id, $event)"
@update-new-name="updateNewName(group.id, $event)" @update-new-name="updateNewName(group.id, $event)"
@import-group="importGroup(group.id)" @import-group="importGroup(group.id)"
......
...@@ -24,11 +24,6 @@ export default { ...@@ -24,11 +24,6 @@ export default {
type: Array, type: Array,
required: true, required: true,
}, },
canCreateGroup: {
type: Boolean,
required: false,
default: false,
},
}, },
computed: { computed: {
isDisabled() { isDisabled() {
...@@ -45,19 +40,18 @@ export default { ...@@ -45,19 +40,18 @@ export default {
text: namespace.full_path, text: namespace.full_path,
})); }));
if (!this.canCreateGroup) { const select2Config = {
return { data: availableNamespacesData }; data: [{ id: '', text: s__('BulkImport|No parent') }],
};
if (availableNamespacesData.length) {
select2Config.data.push({
text: s__('BulkImport|Existing groups'),
children: availableNamespacesData,
});
} }
return { return select2Config;
data: [
{ id: '', text: s__('BulkImport|No parent') },
{
text: s__('BulkImport|Existing groups'),
children: availableNamespacesData,
},
],
};
}, },
}, },
methods: { methods: {
......
...@@ -52,7 +52,7 @@ export function createResolvers({ endpoints }) { ...@@ -52,7 +52,7 @@ export function createResolvers({ endpoints }) {
status: STATUSES.NONE, status: STATUSES.NONE,
import_target: { import_target: {
new_name: group.full_path, new_name: group.full_path,
target_namespace: availableNamespaces[0].full_path, target_namespace: availableNamespaces[0]?.full_path ?? '',
}, },
})), })),
pageInfo: { pageInfo: {
......
...@@ -9,5 +9,4 @@ ...@@ -9,5 +9,4 @@
available_namespaces_path: import_available_namespaces_path(format: :json), available_namespaces_path: import_available_namespaces_path(format: :json),
create_bulk_import_path: import_bulk_imports_path(format: :json), create_bulk_import_path: import_bulk_imports_path(format: :json),
jobs_path: realtime_changes_import_bulk_imports_path(format: :json), jobs_path: realtime_changes_import_bulk_imports_path(format: :json),
can_create_group: current_user.can_create_group?.to_s,
source_url: @source_url } } source_url: @source_url } }
...@@ -75,23 +75,24 @@ describe('import table row', () => { ...@@ -75,23 +75,24 @@ describe('import table row', () => {
}); });
}); });
it('renders only namespaces if user cannot create new group', () => { it('renders only no parent option if available namespaces list is empty', () => {
createComponent({ createComponent({
canCreateGroup: false,
group: getFakeGroup(STATUSES.NONE), group: getFakeGroup(STATUSES.NONE),
availableNamespaces: [],
}); });
const dropdownData = findNamespaceDropdown().props().options.data; const dropdownData = findNamespaceDropdown().props().options.data;
const noParentOption = dropdownData.find((o) => o.text === 'No parent'); const noParentOption = dropdownData.find((o) => o.text === 'No parent');
const existingGroupOption = dropdownData.find((o) => o.text === 'Existing groups');
expect(noParentOption).toBeUndefined(); expect(noParentOption.id).toBe('');
expect(dropdownData).toHaveLength(availableNamespacesFixture.length); expect(existingGroupOption).toBeUndefined();
}); });
it('renders no parent option in available namespaces if user can create new group', () => { it('renders both no parent option and available namespaces list when available namespaces list is not empty', () => {
createComponent({ createComponent({
canCreateGroup: true,
group: getFakeGroup(STATUSES.NONE), group: getFakeGroup(STATUSES.NONE),
availableNamespaces: availableNamespacesFixture,
}); });
const dropdownData = findNamespaceDropdown().props().options.data; const dropdownData = findNamespaceDropdown().props().options.data;
......
...@@ -27,7 +27,7 @@ describe('import table', () => { ...@@ -27,7 +27,7 @@ describe('import table', () => {
]; ];
const FAKE_PAGE_INFO = { page: 1, perPage: 20, total: 40, totalPages: 2 }; const FAKE_PAGE_INFO = { page: 1, perPage: 20, total: 40, totalPages: 2 };
const createComponent = ({ bulkImportSourceGroups, canCreateGroup }) => { const createComponent = ({ bulkImportSourceGroups }) => {
apolloProvider = createMockApollo([], { apolloProvider = createMockApollo([], {
Query: { Query: {
availableNamespaces: () => availableNamespacesFixture, availableNamespaces: () => availableNamespacesFixture,
...@@ -43,7 +43,6 @@ describe('import table', () => { ...@@ -43,7 +43,6 @@ describe('import table', () => {
wrapper = shallowMount(ImportTable, { wrapper = shallowMount(ImportTable, {
propsData: { propsData: {
sourceUrl: 'https://demo.host', sourceUrl: 'https://demo.host',
canCreateGroup,
}, },
stubs: { stubs: {
GlSprintf, GlSprintf,
...@@ -100,25 +99,6 @@ describe('import table', () => { ...@@ -100,25 +99,6 @@ describe('import table', () => {
expect(wrapper.findAll(ImportTableRow)).toHaveLength(FAKE_GROUPS.length); expect(wrapper.findAll(ImportTableRow)).toHaveLength(FAKE_GROUPS.length);
}); });
it.each`
canCreateGroup | userPermissions
${true} | ${'user can create new top-level group'}
${false} | ${'user cannot create new top-level group'}
`('correctly passes canCreateGroup to rows when $userPermissions', async ({ canCreateGroup }) => {
createComponent({
bulkImportSourceGroups: () => ({
nodes: FAKE_GROUPS,
pageInfo: FAKE_PAGE_INFO,
}),
canCreateGroup,
});
await waitForPromises();
wrapper.findAllComponents(ImportTableRow).wrappers.forEach((w) => {
expect(w.props().canCreateGroup).toBe(canCreateGroup);
});
});
it('does not render status string when result list is empty', async () => { it('does not render status string when result list is empty', async () => {
createComponent({ createComponent({
bulkImportSourceGroups: jest.fn().mockResolvedValue({ bulkImportSourceGroups: jest.fn().mockResolvedValue({
......
...@@ -82,6 +82,15 @@ describe('Bulk import resolvers', () => { ...@@ -82,6 +82,15 @@ describe('Bulk import resolvers', () => {
.reply(httpStatus.OK, availableNamespacesFixture); .reply(httpStatus.OK, availableNamespacesFixture);
}); });
it('populates each result instance with empty import_target when there are no available namespaces', async () => {
axiosMockAdapter.onGet(FAKE_ENDPOINTS.availableNamespaces).reply(httpStatus.OK, []);
const response = await client.query({ query: bulkImportSourceGroupsQuery });
results = response.data.bulkImportSourceGroups.nodes;
expect(results.every((r) => r.import_target.target_namespace === '')).toBe(true);
});
describe('when called', () => { describe('when called', () => {
beforeEach(async () => { beforeEach(async () => {
const response = await client.query({ query: bulkImportSourceGroupsQuery }); const response = await client.query({ query: bulkImportSourceGroupsQuery });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment