diff options
Diffstat (limited to 'spec/frontend/import_entities/import_groups/components/import_table_row_spec.js')
-rw-r--r-- | spec/frontend/import_entities/import_groups/components/import_table_row_spec.js | 109 |
1 files changed, 102 insertions, 7 deletions
diff --git a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js index cdef4b1ee62..7a83136e785 100644 --- a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js +++ b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js @@ -1,10 +1,15 @@ -import { GlButton, GlLink, GlFormInput } from '@gitlab/ui'; +import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'helpers/mock_apollo_helper'; import { STATUSES } from '~/import_entities/constants'; import ImportTableRow from '~/import_entities/import_groups/components/import_table_row.vue'; -import Select2Select from '~/vue_shared/components/select2_select.vue'; +import groupQuery from '~/import_entities/import_groups/graphql/queries/group.query.graphql'; import { availableNamespacesFixture } from '../graphql/fixtures'; +Vue.use(VueApollo); + const getFakeGroup = (status) => ({ web_url: 'https://fake.host/', full_path: 'fake_group_1', @@ -17,8 +22,12 @@ const getFakeGroup = (status) => ({ status, }); +const EXISTING_GROUP_TARGET_NAMESPACE = 'existing-group'; +const EXISTING_GROUP_PATH = 'existing-path'; + describe('import table row', () => { let wrapper; + let apolloProvider; let group; const findByText = (cmp, text) => { @@ -26,12 +35,27 @@ describe('import table row', () => { }; const findImportButton = () => findByText(GlButton, 'Import'); const findNameInput = () => wrapper.find(GlFormInput); - const findNamespaceDropdown = () => wrapper.find(Select2Select); + const findNamespaceDropdown = () => wrapper.find(GlDropdown); const createComponent = (props) => { + apolloProvider = createMockApollo([ + [ + groupQuery, + ({ fullPath }) => { + const existingGroup = + fullPath === `${EXISTING_GROUP_TARGET_NAMESPACE}/${EXISTING_GROUP_PATH}` + ? { id: 1 } + : null; + return Promise.resolve({ data: { existingGroup } }); + }, + ], + ]); + wrapper = shallowMount(ImportTableRow, { + apolloProvider, propsData: { availableNamespaces: availableNamespacesFixture, + groupPathRegex: /.*/, ...props, }, }); @@ -49,15 +73,24 @@ describe('import table row', () => { }); it.each` - selector | sourceEvent | payload | event - ${findNamespaceDropdown} | ${'input'} | ${'demo'} | ${'update-target-namespace'} - ${findNameInput} | ${'input'} | ${'demo'} | ${'update-new-name'} - ${findImportButton} | ${'click'} | ${undefined} | ${'import-group'} + selector | sourceEvent | payload | event + ${findNameInput} | ${'input'} | ${'demo'} | ${'update-new-name'} + ${findImportButton} | ${'click'} | ${undefined} | ${'import-group'} `('invokes $event', ({ selector, sourceEvent, payload, event }) => { selector().vm.$emit(sourceEvent, payload); expect(wrapper.emitted(event)).toBeDefined(); expect(wrapper.emitted(event)[0][0]).toBe(payload); }); + + it('emits update-target-namespace when dropdown option is clicked', () => { + const dropdownItem = findNamespaceDropdown().findAllComponents(GlDropdownItem).at(2); + const dropdownItemText = dropdownItem.text(); + + dropdownItem.vm.$emit('click'); + + expect(wrapper.emitted('update-target-namespace')).toBeDefined(); + expect(wrapper.emitted('update-target-namespace')[0][0]).toBe(dropdownItemText); + }); }); describe('when entity status is NONE', () => { @@ -75,6 +108,34 @@ describe('import table row', () => { }); }); + it('renders only no parent option if available namespaces list is empty', () => { + createComponent({ + group: getFakeGroup(STATUSES.NONE), + availableNamespaces: [], + }); + + const items = findNamespaceDropdown() + .findAllComponents(GlDropdownItem) + .wrappers.map((w) => w.text()); + + expect(items[0]).toBe('No parent'); + expect(items).toHaveLength(1); + }); + + it('renders both no parent option and available namespaces list when available namespaces list is not empty', () => { + createComponent({ + group: getFakeGroup(STATUSES.NONE), + availableNamespaces: availableNamespacesFixture, + }); + + const [firstItem, ...rest] = findNamespaceDropdown() + .findAllComponents(GlDropdownItem) + .wrappers.map((w) => w.text()); + + expect(firstItem).toBe('No parent'); + expect(rest).toHaveLength(availableNamespacesFixture.length); + }); + describe('when entity status is SCHEDULING', () => { beforeEach(() => { group = getFakeGroup(STATUSES.SCHEDULING); @@ -109,4 +170,38 @@ describe('import table row', () => { expect(findByText(GlLink, TARGET_LINK).exists()).toBe(true); }); }); + + describe('validations', () => { + it('Reports invalid group name when name is not matching regex', () => { + createComponent({ + group: { + ...getFakeGroup(STATUSES.NONE), + import_target: { + target_namespace: 'root', + new_name: 'very`bad`name', + }, + }, + groupPathRegex: /^[a-zA-Z]+$/, + }); + + expect(wrapper.text()).toContain('Please choose a group URL with no special characters.'); + }); + + it('Reports invalid group name if group already exists', async () => { + createComponent({ + group: { + ...getFakeGroup(STATUSES.NONE), + import_target: { + target_namespace: EXISTING_GROUP_TARGET_NAMESPACE, + new_name: EXISTING_GROUP_PATH, + }, + }, + }); + + jest.runOnlyPendingTimers(); + await nextTick(); + + expect(wrapper.text()).toContain('Name already exists.'); + }); + }); }); |