summaryrefslogtreecommitdiff
path: root/spec/frontend/invite_members/components/import_a_project_modal_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/invite_members/components/import_a_project_modal_spec.js')
-rw-r--r--spec/frontend/invite_members/components/import_a_project_modal_spec.js167
1 files changed, 167 insertions, 0 deletions
diff --git a/spec/frontend/invite_members/components/import_a_project_modal_spec.js b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
new file mode 100644
index 00000000000..fecbf84fb57
--- /dev/null
+++ b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
@@ -0,0 +1,167 @@
+import { GlFormGroup, GlSprintf, GlModal } from '@gitlab/ui';
+import MockAdapter from 'axios-mock-adapter';
+import { stubComponent } from 'helpers/stub_component';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import * as ProjectsApi from '~/api/projects_api';
+import ImportAProjectModal from '~/invite_members/components/import_a_project_modal.vue';
+import ProjectSelect from '~/invite_members/components/project_select.vue';
+import axios from '~/lib/utils/axios_utils';
+
+let wrapper;
+let mock;
+
+const projectId = '1';
+const projectName = 'test name';
+const projectToBeImported = { id: '2' };
+const $toast = {
+ show: jest.fn(),
+};
+
+const createComponent = () => {
+ wrapper = shallowMountExtended(ImportAProjectModal, {
+ propsData: {
+ projectId,
+ projectName,
+ },
+ stubs: {
+ GlModal: stubComponent(GlModal, {
+ template:
+ '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>',
+ }),
+ GlSprintf,
+ GlFormGroup: stubComponent(GlFormGroup, {
+ props: ['state', 'invalidFeedback'],
+ }),
+ },
+ mocks: {
+ $toast,
+ },
+ });
+};
+
+beforeEach(() => {
+ gon.api_version = 'v4';
+ mock = new MockAdapter(axios);
+});
+
+afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+});
+
+describe('ImportAProjectModal', () => {
+ const findIntroText = () => wrapper.find({ ref: 'modalIntro' }).text();
+ const findCancelButton = () => wrapper.findByTestId('cancel-button');
+ const findImportButton = () => wrapper.findByTestId('import-button');
+ const clickImportButton = () => findImportButton().vm.$emit('click');
+ const clickCancelButton = () => findCancelButton().vm.$emit('click');
+ const findFormGroup = () => wrapper.findByTestId('form-group');
+ const formGroupInvalidFeedback = () => findFormGroup().props('invalidFeedback');
+ const formGroupErrorState = () => findFormGroup().props('state');
+ const findProjectSelect = () => wrapper.findComponent(ProjectSelect);
+
+ describe('rendering the modal', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders the modal with the correct title', () => {
+ expect(wrapper.findComponent(GlModal).props('title')).toBe(
+ 'Import members from another project',
+ );
+ });
+
+ it('renders the Cancel button text correctly', () => {
+ expect(findCancelButton().text()).toBe('Cancel');
+ });
+
+ it('renders the Import button text correctly', () => {
+ expect(findImportButton().text()).toBe('Import project members');
+ });
+
+ it('renders the modal intro text correctly', () => {
+ expect(findIntroText()).toBe("You're importing members to the test name project.");
+ });
+
+ it('renders the Import button modal without isLoading', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+
+ it('sets isLoading to true when the Invite button is clicked', async () => {
+ clickImportButton();
+
+ await wrapper.vm.$nextTick();
+
+ expect(findImportButton().props('loading')).toBe(true);
+ });
+ });
+
+ describe('submitting the import form', () => {
+ describe('when the import is successful', () => {
+ beforeEach(() => {
+ createComponent();
+
+ findProjectSelect().vm.$emit('input', projectToBeImported);
+
+ jest.spyOn(ProjectsApi, 'importProjectMembers').mockResolvedValue();
+
+ clickImportButton();
+ });
+
+ it('calls Api importProjectMembers', () => {
+ expect(ProjectsApi.importProjectMembers).toHaveBeenCalledWith(
+ projectId,
+ projectToBeImported.id,
+ );
+ });
+
+ it('displays the successful toastMessage', () => {
+ expect($toast.show).toHaveBeenCalledWith(
+ 'Successfully imported',
+ wrapper.vm.$options.toastOptions,
+ );
+ });
+
+ it('sets isLoading to false after success', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+ });
+
+ describe('when the import fails', () => {
+ beforeEach(async () => {
+ createComponent();
+
+ findProjectSelect().vm.$emit('input', projectToBeImported);
+
+ jest
+ .spyOn(ProjectsApi, 'importProjectMembers')
+ .mockRejectedValue({ response: { data: { success: false } } });
+
+ clickImportButton();
+ await waitForPromises();
+ });
+
+ it('displays the generic error message', () => {
+ expect(formGroupInvalidFeedback()).toBe('Unable to import project members');
+ expect(formGroupErrorState()).toBe(false);
+ });
+
+ it('sets isLoading to false after error', () => {
+ expect(findImportButton().props('loading')).toBe(false);
+ });
+
+ it('clears the error when the modal is closed with an error', async () => {
+ expect(formGroupInvalidFeedback()).toBe('Unable to import project members');
+ expect(formGroupErrorState()).toBe(false);
+
+ clickCancelButton();
+
+ await wrapper.vm.$nextTick();
+
+ expect(formGroupInvalidFeedback()).toBe('');
+ expect(formGroupErrorState()).not.toBe(false);
+ });
+ });
+ });
+});