diff options
Diffstat (limited to 'spec/frontend/import_entities/import_groups/components')
-rw-r--r-- | spec/frontend/import_entities/import_groups/components/import_table_row_spec.js | 112 | ||||
-rw-r--r-- | spec/frontend/import_entities/import_groups/components/import_table_spec.js | 103 |
2 files changed, 215 insertions, 0 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 new file mode 100644 index 00000000000..d88a31a0e47 --- /dev/null +++ b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js @@ -0,0 +1,112 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlButton, GlLink, GlFormInput } from '@gitlab/ui'; +import Select2Select from '~/vue_shared/components/select2_select.vue'; +import ImportTableRow from '~/import_entities/import_groups/components/import_table_row.vue'; +import { STATUSES } from '~/import_entities/constants'; +import { availableNamespacesFixture } from '../graphql/fixtures'; + +const getFakeGroup = status => ({ + web_url: 'https://fake.host/', + full_path: 'fake_group_1', + full_name: 'fake_name_1', + import_target: { + target_namespace: 'root', + new_name: 'group1', + }, + id: 1, + status, +}); + +describe('import table row', () => { + let wrapper; + let group; + + const findByText = (cmp, text) => { + return wrapper.findAll(cmp).wrappers.find(node => node.text().indexOf(text) === 0); + }; + const findImportButton = () => findByText(GlButton, 'Import'); + const findNameInput = () => wrapper.find(GlFormInput); + const findNamespaceDropdown = () => wrapper.find(Select2Select); + + const createComponent = props => { + wrapper = shallowMount(ImportTableRow, { + propsData: { + availableNamespaces: availableNamespacesFixture, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('events', () => { + beforeEach(() => { + group = getFakeGroup(STATUSES.NONE); + createComponent({ group }); + }); + + it.each` + selector | sourceEvent | payload | event + ${findNamespaceDropdown} | ${'input'} | ${'demo'} | ${'update-target-namespace'} + ${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); + }); + }); + + describe('when entity status is NONE', () => { + beforeEach(() => { + group = getFakeGroup(STATUSES.NONE); + createComponent({ group }); + }); + + it('renders Import button', () => { + expect(findByText(GlButton, 'Import').exists()).toBe(true); + }); + + it('renders namespace dropdown as not disabled', () => { + expect(findNamespaceDropdown().attributes('disabled')).toBe(undefined); + }); + }); + + describe('when entity status is SCHEDULING', () => { + beforeEach(() => { + group = getFakeGroup(STATUSES.SCHEDULING); + 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'); + }); + }); + + describe('when entity status is FINISHED', () => { + beforeEach(() => { + group = getFakeGroup(STATUSES.FINISHED); + 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); + }); + }); +}); 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 new file mode 100644 index 00000000000..0ca721cd951 --- /dev/null +++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js @@ -0,0 +1,103 @@ +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import { GlLoadingIcon } from '@gitlab/ui'; +import waitForPromises from 'helpers/wait_for_promises'; +import createMockApollo from 'jest/helpers/mock_apollo_helper'; +import ImportTableRow from '~/import_entities/import_groups/components/import_table_row.vue'; +import ImportTable from '~/import_entities/import_groups/components/import_table.vue'; +import setTargetNamespaceMutation from '~/import_entities/import_groups/graphql/mutations/set_target_namespace.mutation.graphql'; +import setNewNameMutation from '~/import_entities/import_groups/graphql/mutations/set_new_name.mutation.graphql'; +import importGroupMutation from '~/import_entities/import_groups/graphql/mutations/import_group.mutation.graphql'; + +import { STATUSES } from '~/import_entities/constants'; + +import { availableNamespacesFixture, generateFakeEntry } from '../graphql/fixtures'; + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +describe('import table', () => { + let wrapper; + let apolloProvider; + + const createComponent = ({ bulkImportSourceGroups }) => { + apolloProvider = createMockApollo([], { + Query: { + availableNamespaces: () => availableNamespacesFixture, + bulkImportSourceGroups, + }, + Mutation: { + setTargetNamespace: jest.fn(), + setNewName: jest.fn(), + importGroup: jest.fn(), + }, + }); + + wrapper = shallowMount(ImportTable, { + localVue, + apolloProvider, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('renders loading icon while performing request', async () => { + createComponent({ + bulkImportSourceGroups: () => new Promise(() => {}), + }); + await waitForPromises(); + + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + + it('does not renders loading icon when request is completed', async () => { + createComponent({ + bulkImportSourceGroups: () => [], + }); + await waitForPromises(); + + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + }); + + it('renders import row for each group in response', async () => { + const FAKE_GROUPS = [ + generateFakeEntry({ id: 1, status: STATUSES.NONE }), + generateFakeEntry({ id: 2, status: STATUSES.FINISHED }), + ]; + createComponent({ + bulkImportSourceGroups: () => FAKE_GROUPS, + }); + await waitForPromises(); + + expect(wrapper.findAll(ImportTableRow)).toHaveLength(FAKE_GROUPS.length); + }); + + describe('converts row events to mutation invocations', () => { + const FAKE_GROUP = generateFakeEntry({ id: 1, status: STATUSES.NONE }); + + beforeEach(() => { + createComponent({ + bulkImportSourceGroups: () => [FAKE_GROUP], + }); + return waitForPromises(); + }); + + it.each` + event | payload | mutation | variables + ${'update-target-namespace'} | ${'new-namespace'} | ${setTargetNamespaceMutation} | ${{ sourceGroupId: FAKE_GROUP.id, targetNamespace: 'new-namespace' }} + ${'update-new-name'} | ${'new-name'} | ${setNewNameMutation} | ${{ sourceGroupId: FAKE_GROUP.id, newName: 'new-name' }} + ${'import-group'} | ${undefined} | ${importGroupMutation} | ${{ sourceGroupId: FAKE_GROUP.id }} + `('correctly maps $event to mutation', async ({ event, payload, mutation, variables }) => { + jest.spyOn(apolloProvider.defaultClient, 'mutate'); + wrapper.find(ImportTableRow).vm.$emit(event, payload); + await waitForPromises(); + expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith({ + mutation, + variables, + }); + }); + }); +}); |