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:
Diffstat (limited to 'spec/frontend/members/components/modals/leave_modal_spec.js')
-rw-r--r--spec/frontend/members/components/modals/leave_modal_spec.js122
1 files changed, 95 insertions, 27 deletions
diff --git a/spec/frontend/members/components/modals/leave_modal_spec.js b/spec/frontend/members/components/modals/leave_modal_spec.js
index cdbabb2f646..ba587c6f0b3 100644
--- a/spec/frontend/members/components/modals/leave_modal_spec.js
+++ b/spec/frontend/members/components/modals/leave_modal_spec.js
@@ -1,11 +1,14 @@
import { GlModal, GlForm } from '@gitlab/ui';
-import { within } from '@testing-library/dom';
-import { mount, createWrapper } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
+import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import LeaveModal from '~/members/components/modals/leave_modal.vue';
-import { LEAVE_MODAL_ID, MEMBER_TYPES } from '~/members/constants';
+import {
+ LEAVE_MODAL_ID,
+ MEMBER_TYPES,
+ MEMBER_MODEL_TYPE_PROJECT_MEMBER,
+} from '~/members/constants';
import UserDeletionObstaclesList from '~/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue';
import { parseUserDeletionObstacles } from '~/vue_shared/components/user_deletion_obstacles/utils';
import { member } from '../../mock_data';
@@ -31,14 +34,17 @@ describe('LeaveModal', () => {
});
};
- const createComponent = (propsData = {}, state) => {
- wrapper = mount(LeaveModal, {
+ const createComponent = async (propsData = {}, state) => {
+ wrapper = mountExtended(LeaveModal, {
store: createStore(state),
provide: {
namespace: MEMBER_TYPES.user,
},
propsData: {
member,
+ permissions: {
+ canRemove: true,
+ },
...propsData,
},
attrs: {
@@ -46,39 +52,98 @@ describe('LeaveModal', () => {
visible: true,
},
});
+
+ await nextTick();
};
- const findModal = () => wrapper.findComponent(GlModal);
+ const findModal = () => extendedWrapper(wrapper.findComponent(GlModal));
const findForm = () => findModal().findComponent(GlForm);
const findUserDeletionObstaclesList = () => findModal().findComponent(UserDeletionObstaclesList);
- const getByText = (text, options) =>
- createWrapper(within(findModal().element).getByText(text, options));
-
- beforeEach(async () => {
- createComponent();
- await nextTick();
- });
-
afterEach(() => {
wrapper.destroy();
});
- it('sets modal ID', () => {
+ it('sets modal ID', async () => {
+ await createComponent();
+
expect(findModal().props('modalId')).toBe(LEAVE_MODAL_ID);
});
- it('displays modal title', () => {
- expect(getByText(`Leave "${member.source.fullName}"`).exists()).toBe(true);
+ describe('when leave is allowed', () => {
+ it('displays modal title', async () => {
+ await createComponent();
+
+ expect(findModal().findByText(`Leave "${member.source.fullName}"`).exists()).toBe(true);
+ });
+
+ it('displays modal body', async () => {
+ await createComponent();
+
+ expect(
+ findModal()
+ .findByText(`Are you sure you want to leave "${member.source.fullName}"?`)
+ .exists(),
+ ).toBe(true);
+ });
});
- it('displays modal body', () => {
- expect(getByText(`Are you sure you want to leave "${member.source.fullName}"?`).exists()).toBe(
- true,
- );
+ describe('when leave is blocked by last owner', () => {
+ const permissions = {
+ canRemove: false,
+ canRemoveBlockedByLastOwner: true,
+ };
+
+ it('does not show primary action button', async () => {
+ await createComponent({
+ permissions,
+ });
+
+ expect(findModal().props('actionPrimary')).toBe(null);
+ });
+
+ it('displays modal title', async () => {
+ await createComponent({
+ permissions,
+ });
+
+ expect(findModal().findByText(`Cannot leave "${member.source.fullName}"`).exists()).toBe(
+ true,
+ );
+ });
+
+ describe('when member model type is `GroupMember`', () => {
+ it('displays modal body', async () => {
+ await createComponent({
+ permissions,
+ });
+
+ expect(
+ findModal().findByText(LeaveModal.i18n.preventedBodyGroupMemberModelType).exists(),
+ ).toBe(true);
+ });
+ });
+
+ describe('when member model type is `ProjectMember`', () => {
+ it('displays modal body', async () => {
+ await createComponent({
+ member: {
+ ...member,
+ type: MEMBER_MODEL_TYPE_PROJECT_MEMBER,
+ },
+ permissions,
+ });
+
+ expect(
+ findModal().findByText(LeaveModal.i18n.preventedBodyProjectMemberModelType).exists(),
+ ).toBe(true);
+ });
+ });
});
- it('displays form with correct action and inputs', () => {
+ it('displays form with correct action and inputs', async () => {
+ await createComponent();
+
const form = findForm();
expect(form.attributes('action')).toBe('/groups/foo-bar/-/group_members/leave');
@@ -89,7 +154,9 @@ describe('LeaveModal', () => {
});
describe('User deletion obstacles list', () => {
- it("displays obstacles list when member's user is part of on-call management", () => {
+ it("displays obstacles list when member's user is part of on-call management", async () => {
+ await createComponent();
+
const obstaclesList = findUserDeletionObstaclesList();
expect(obstaclesList.exists()).toBe(true);
expect(obstaclesList.props()).toMatchObject({
@@ -105,17 +172,18 @@ describe('LeaveModal', () => {
delete memberWithoutOncall.user.oncallSchedules;
delete memberWithoutOncall.user.escalationPolicies;
- createComponent({ member: memberWithoutOncall });
- await nextTick();
+ await createComponent({ member: memberWithoutOncall });
expect(findUserDeletionObstaclesList().exists()).toBe(false);
});
});
- it('submits the form when "Leave" button is clicked', () => {
+ it('submits the form when "Leave" button is clicked', async () => {
+ await createComponent();
+
const submitSpy = jest.spyOn(findForm().element, 'submit');
- getByText('Leave').trigger('click');
+ findModal().findByText('Leave').trigger('click');
expect(submitSpy).toHaveBeenCalled();