diff options
Diffstat (limited to 'spec/frontend/members/components/action_dropdowns/user_action_dropdown_spec.js')
-rw-r--r-- | spec/frontend/members/components/action_dropdowns/user_action_dropdown_spec.js | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/spec/frontend/members/components/action_dropdowns/user_action_dropdown_spec.js b/spec/frontend/members/components/action_dropdowns/user_action_dropdown_spec.js new file mode 100644 index 00000000000..5a2de1cac80 --- /dev/null +++ b/spec/frontend/members/components/action_dropdowns/user_action_dropdown_spec.js @@ -0,0 +1,220 @@ +import { shallowMount } from '@vue/test-utils'; +import { sprintf } from '~/locale'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import LeaveGroupDropdownItem from '~/members/components/action_dropdowns/leave_group_dropdown_item.vue'; +import RemoveMemberDropdownItem from '~/members/components/action_dropdowns/remove_member_dropdown_item.vue'; +import UserActionDropdown from '~/members/components/action_dropdowns/user_action_dropdown.vue'; +import { I18N } from '~/members/components/action_dropdowns/constants'; +import { + MEMBER_MODEL_TYPE_GROUP_MEMBER, + MEMBER_MODEL_TYPE_PROJECT_MEMBER, +} from '~/members/constants'; +import { parseUserDeletionObstacles } from '~/vue_shared/components/user_deletion_obstacles/utils'; +import { member, orphanedMember } from '../../mock_data'; + +describe('UserActionDropdown', () => { + let wrapper; + + const createComponent = (propsData = {}) => { + wrapper = shallowMount(UserActionDropdown, { + propsData: { + member, + isCurrentUser: false, + isInvitedUser: false, + ...propsData, + }, + directives: { + GlTooltip: createMockDirective(), + }, + }); + }; + + const findRemoveMemberDropdownItem = () => wrapper.findComponent(RemoveMemberDropdownItem); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('when user has `canRemove` permissions', () => { + beforeEach(() => { + createComponent({ + permissions: { + canRemove: true, + }, + }); + }); + + it('renders remove member dropdown with correct text', () => { + const removeMemberDropdownItem = findRemoveMemberDropdownItem(); + expect(removeMemberDropdownItem.exists()).toBe(true); + expect(removeMemberDropdownItem.html()).toContain(I18N.removeMember); + }); + + it('displays a tooltip', () => { + const tooltip = getBinding(wrapper.element, 'gl-tooltip'); + expect(tooltip).not.toBeUndefined(); + expect(tooltip.value).toBe(I18N.actions); + }); + + it('sets props correctly', () => { + expect(findRemoveMemberDropdownItem().props()).toEqual({ + memberId: member.id, + memberModelType: MEMBER_MODEL_TYPE_GROUP_MEMBER, + modalMessage: sprintf( + I18N.confirmNormalUserRemoval, + { + userName: member.user.name, + group: member.source.fullName, + }, + false, + ), + isAccessRequest: false, + isInvite: false, + userDeletionObstacles: { + name: member.user.name, + obstacles: parseUserDeletionObstacles(member.user), + }, + preventRemoval: false, + }); + }); + + describe('when member is orphaned', () => { + it('sets `message` prop correctly', () => { + createComponent({ + member: orphanedMember, + permissions: { + canRemove: true, + }, + }); + + expect(findRemoveMemberDropdownItem().props('modalMessage')).toBe( + sprintf(I18N.confirmOrphanedUserRemoval, { group: orphanedMember.source.fullName }), + ); + }); + }); + + describe('when member is the current user', () => { + it('renders leave dropdown with correct text', () => { + createComponent({ + isCurrentUser: true, + permissions: { + canRemove: true, + }, + }); + + const leaveGroupDropdownItem = wrapper.findComponent(LeaveGroupDropdownItem); + expect(leaveGroupDropdownItem.exists()).toBe(true); + expect(leaveGroupDropdownItem.html()).toContain(I18N.leaveGroup); + }); + }); + }); + + describe('when user does not have `canRemove` permissions', () => { + it('does not render remove member dropdown', () => { + createComponent({ + permissions: { + canRemove: false, + }, + }); + + expect(findRemoveMemberDropdownItem().exists()).toBe(false); + }); + }); + + describe('when user can remove but it is blocked by last owner', () => { + const permissions = { + canRemove: false, + canRemoveBlockedByLastOwner: true, + }; + + it('renders remove member dropdown', () => { + createComponent({ + permissions, + }); + + expect(findRemoveMemberDropdownItem().exists()).toBe(true); + }); + + describe('when member model type is `GroupMember`', () => { + it('passes correct message to the modal', () => { + createComponent({ + permissions, + }); + + expect(findRemoveMemberDropdownItem().props('modalMessage')).toBe( + I18N.lastGroupOwnerCannotBeRemoved, + ); + }); + }); + + describe('when member model type is `ProjectMember`', () => { + it('passes correct message to the modal', () => { + createComponent({ + member: { + ...member, + type: MEMBER_MODEL_TYPE_PROJECT_MEMBER, + }, + permissions, + }); + + expect(findRemoveMemberDropdownItem().props('modalMessage')).toBe( + I18N.personalProjectOwnerCannotBeRemoved, + ); + }); + }); + + describe('when member is the current user', () => { + it('renders leave dropdown with correct props', () => { + createComponent({ + isCurrentUser: true, + permissions, + }); + + expect(wrapper.findComponent(LeaveGroupDropdownItem).props()).toEqual({ + member, + permissions, + }); + }); + }); + }); + + describe('when group member', () => { + beforeEach(() => { + createComponent({ + member: { + ...member, + type: MEMBER_MODEL_TYPE_GROUP_MEMBER, + }, + permissions: { + canRemove: true, + }, + }); + }); + + it('sets member type correctly', () => { + expect(findRemoveMemberDropdownItem().props().memberModelType).toBe( + MEMBER_MODEL_TYPE_GROUP_MEMBER, + ); + }); + }); + + describe('when project member', () => { + beforeEach(() => { + createComponent({ + member: { + ...member, + type: MEMBER_MODEL_TYPE_PROJECT_MEMBER, + }, + permissions: { + canRemove: true, + }, + }); + }); + + it('sets member type correctly', () => { + expect(findRemoveMemberDropdownItem().props().memberModelType).toBe( + MEMBER_MODEL_TYPE_PROJECT_MEMBER, + ); + }); + }); +}); |