debian-mirror-gitlab/spec/frontend/groups/components/group_item_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

377 lines
12 KiB
JavaScript
Raw Normal View History

2022-08-13 15:12:31 +05:30
import { GlPopover } from '@gitlab/ui';
2021-10-27 15:23:28 +05:30
import waitForPromises from 'helpers/wait_for_promises';
2021-09-04 01:27:46 +05:30
import GroupFolder from '~/groups/components/group_folder.vue';
import GroupItem from '~/groups/components/group_item.vue';
import ItemActions from '~/groups/components/item_actions.vue';
2018-03-17 18:26:18 +05:30
import eventHub from '~/groups/event_hub';
2021-03-11 19:13:27 +05:30
import { getGroupItemMicrodata } from '~/groups/store/utils';
2020-05-24 23:13:21 +05:30
import * as urlUtilities from '~/lib/utils/url_utility';
2022-08-13 15:12:31 +05:30
import {
ITEM_TYPE,
VISIBILITY_INTERNAL,
VISIBILITY_PRIVATE,
VISIBILITY_PUBLIC,
} from '~/groups/constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
2018-03-17 18:26:18 +05:30
import { mockParentGroupItem, mockChildren } from '../mock_data';
2021-09-04 01:27:46 +05:30
const createComponent = (
propsData = { group: mockParentGroupItem, parentGroup: mockChildren[0] },
2022-08-13 15:12:31 +05:30
provide = {
currentGroupVisibility: VISIBILITY_PRIVATE,
},
2021-09-04 01:27:46 +05:30
) => {
2022-08-13 15:12:31 +05:30
return mountExtended(GroupItem, {
2021-09-04 01:27:46 +05:30
propsData,
components: { GroupFolder },
2022-08-13 15:12:31 +05:30
provide,
2018-03-17 18:26:18 +05:30
});
};
describe('GroupItemComponent', () => {
2021-09-04 01:27:46 +05:30
let wrapper;
2018-03-17 18:26:18 +05:30
2020-05-24 23:13:21 +05:30
beforeEach(() => {
2021-09-04 01:27:46 +05:30
wrapper = createComponent();
2021-10-27 15:23:28 +05:30
return waitForPromises();
2018-03-17 18:26:18 +05:30
});
afterEach(() => {
2021-09-04 01:27:46 +05:30
wrapper.destroy();
2018-03-17 18:26:18 +05:30
});
2021-03-08 18:12:59 +05:30
const withMicrodata = (group) => ({
2021-02-22 17:27:13 +05:30
...group,
microdata: getGroupItemMicrodata(group),
});
2018-03-17 18:26:18 +05:30
describe('computed', () => {
describe('groupDomId', () => {
it('should return ID string suffixed with group ID', () => {
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.groupDomId).toBe('group-55');
2018-03-17 18:26:18 +05:30
});
});
describe('rowClass', () => {
it('should return map of classes based on group details', () => {
const classes = ['is-open', 'has-children', 'has-description', 'being-removed'];
2021-09-04 01:27:46 +05:30
const { rowClass } = wrapper.vm;
2018-03-17 18:26:18 +05:30
expect(Object.keys(rowClass).length).toBe(classes.length);
2021-03-08 18:12:59 +05:30
Object.keys(rowClass).forEach((className) => {
2018-12-13 13:39:08 +05:30
expect(classes.indexOf(className)).toBeGreaterThan(-1);
2018-03-17 18:26:18 +05:30
});
});
});
describe('hasChildren', () => {
it('should return boolean value representing if group has any children present', () => {
2020-05-24 23:13:21 +05:30
const group = { ...mockParentGroupItem };
2018-03-17 18:26:18 +05:30
group.childrenCount = 5;
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.hasChildren).toBe(true);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
group.childrenCount = 0;
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.hasChildren).toBe(false);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
});
});
describe('hasAvatar', () => {
it('should return boolean value representing if group has any avatar present', () => {
2020-05-24 23:13:21 +05:30
const group = { ...mockParentGroupItem };
2018-03-17 18:26:18 +05:30
group.avatarUrl = null;
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.hasAvatar).toBe(false);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
group.avatarUrl = '/uploads/group_avatar.png';
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.hasAvatar).toBe(true);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
});
});
describe('isGroup', () => {
it('should return boolean value representing if group item is of type `group` or not', () => {
2020-05-24 23:13:21 +05:30
const group = { ...mockParentGroupItem };
2018-03-17 18:26:18 +05:30
group.type = 'group';
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.isGroup).toBe(true);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
group.type = 'project';
2022-03-02 08:16:31 +05:30
group.lastActivityAt = '2017-04-09T18:40:39.101Z';
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(wrapper.vm.isGroup).toBe(false);
wrapper.destroy();
2018-03-17 18:26:18 +05:30
});
});
});
describe('methods', () => {
describe('onClickRowGroup', () => {
let event;
beforeEach(() => {
const classList = {
contains() {
return false;
},
};
event = {
target: {
classList,
parentElement: {
classList,
},
},
};
});
it('should emit `toggleChildren` event when expand is clicked on a group and it has children present', () => {
2020-05-24 23:13:21 +05:30
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
2018-03-17 18:26:18 +05:30
2021-09-04 01:27:46 +05:30
wrapper.vm.onClickRowGroup(event);
2018-12-13 13:39:08 +05:30
2021-09-04 01:27:46 +05:30
expect(eventHub.$emit).toHaveBeenCalledWith('toggleChildren', wrapper.vm.group);
2018-03-17 18:26:18 +05:30
});
2020-05-24 23:13:21 +05:30
it('should navigate page to group homepage if group does not have any children present', () => {
jest.spyOn(urlUtilities, 'visitUrl').mockImplementation();
const group = { ...mockParentGroupItem };
2018-03-17 18:26:18 +05:30
group.childrenCount = 0;
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2020-05-24 23:13:21 +05:30
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
2018-03-17 18:26:18 +05:30
2021-09-04 01:27:46 +05:30
wrapper.vm.onClickRowGroup(event);
2020-05-24 23:13:21 +05:30
expect(eventHub.$emit).not.toHaveBeenCalled();
2021-09-04 01:27:46 +05:30
expect(urlUtilities.visitUrl).toHaveBeenCalledWith(wrapper.vm.group.relativePath);
2018-03-17 18:26:18 +05:30
});
});
});
describe('template', () => {
2020-03-13 15:44:24 +05:30
let group = null;
describe('for a group pending deletion', () => {
beforeEach(() => {
group = { ...mockParentGroupItem, pendingRemoval: true };
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2020-03-13 15:44:24 +05:30
});
2021-09-30 23:02:18 +05:30
it('renders the group pending deletion badge', () => {
2021-09-04 01:27:46 +05:30
const badgeEl = wrapper.vm.$el.querySelector('.badge-warning');
2020-03-13 15:44:24 +05:30
expect(badgeEl).toBeDefined();
2021-09-30 23:02:18 +05:30
expect(badgeEl.innerHTML).toContain('pending deletion');
2020-03-13 15:44:24 +05:30
});
});
describe('for a group not scheduled for deletion', () => {
beforeEach(() => {
group = { ...mockParentGroupItem, pendingRemoval: false };
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2020-03-13 15:44:24 +05:30
});
2021-09-30 23:02:18 +05:30
it('does not render the group pending deletion badge', () => {
2021-09-04 01:27:46 +05:30
const groupTextContainer = wrapper.vm.$el.querySelector('.group-text-container');
2020-03-13 15:44:24 +05:30
2021-09-30 23:02:18 +05:30
expect(groupTextContainer).not.toContain('pending deletion');
2020-03-13 15:44:24 +05:30
});
2021-09-04 01:27:46 +05:30
it('renders `item-actions` component and passes correct props to it', () => {
wrapper = createComponent({
group: mockParentGroupItem,
parentGroup: mockChildren[0],
action: 'subgroups_and_projects',
});
const itemActionsComponent = wrapper.findComponent(ItemActions);
expect(itemActionsComponent.exists()).toBe(true);
expect(itemActionsComponent.props()).toEqual({
group: mockParentGroupItem,
parentGroup: mockChildren[0],
action: 'subgroups_and_projects',
});
});
2020-03-13 15:44:24 +05:30
});
2018-03-17 18:26:18 +05:30
it('should render component template correctly', () => {
2021-09-04 01:27:46 +05:30
const visibilityIconEl = wrapper.vm.$el.querySelector(
'[data-testid="group-visibility-icon"]',
);
const { vm } = wrapper;
2019-09-30 21:07:59 +05:30
2018-03-17 18:26:18 +05:30
expect(vm.$el.getAttribute('id')).toBe('group-55');
2021-09-04 01:27:46 +05:30
expect(vm.$el.classList.contains('group-row')).toBe(true);
2018-03-17 18:26:18 +05:30
expect(vm.$el.querySelector('.group-row-contents')).toBeDefined();
expect(vm.$el.querySelector('.group-row-contents .controls')).toBeDefined();
expect(vm.$el.querySelector('.group-row-contents .stats')).toBeDefined();
expect(vm.$el.querySelector('.folder-toggle-wrap')).toBeDefined();
expect(vm.$el.querySelector('.folder-toggle-wrap .folder-caret')).toBeDefined();
expect(vm.$el.querySelector('.folder-toggle-wrap .item-type-icon')).toBeDefined();
expect(vm.$el.querySelector('.avatar-container')).toBeDefined();
expect(vm.$el.querySelector('.avatar-container a.no-expand')).toBeDefined();
expect(vm.$el.querySelector('.avatar-container .avatar')).toBeDefined();
expect(vm.$el.querySelector('.title')).toBeDefined();
expect(vm.$el.querySelector('.title a.no-expand')).toBeDefined();
2019-09-30 21:07:59 +05:30
expect(visibilityIconEl).not.toBe(null);
2021-04-17 20:07:23 +05:30
expect(visibilityIconEl.getAttribute('title')).toBe(vm.visibilityTooltip);
2019-09-30 21:07:59 +05:30
2018-03-17 18:26:18 +05:30
expect(vm.$el.querySelector('.access-type')).toBeDefined();
expect(vm.$el.querySelector('.description')).toBeDefined();
expect(vm.$el.querySelector('.group-list-tree')).toBeDefined();
});
});
2021-02-22 17:27:13 +05:30
describe('schema.org props', () => {
describe('when showSchemaMarkup is disabled on the group', () => {
2021-03-08 18:12:59 +05:30
it.each(['itemprop', 'itemtype', 'itemscope'], 'it does not set %s', (attr) => {
2021-09-30 23:02:18 +05:30
expect(wrapper.attributes(attr)).toBeUndefined();
2021-02-22 17:27:13 +05:30
});
it.each(
['.js-group-avatar', '.js-group-name', '.js-group-description'],
'it does not set `itemprop` on sub-nodes',
2021-03-08 18:12:59 +05:30
(selector) => {
2021-09-30 23:02:18 +05:30
expect(wrapper.find(selector).attributes('itemprop')).toBeUndefined();
2021-02-22 17:27:13 +05:30
},
);
});
describe('when group has microdata', () => {
beforeEach(() => {
const group = withMicrodata({
...mockParentGroupItem,
avatarUrl: 'http://foo.bar',
description: 'Foo Bar',
});
2021-09-04 01:27:46 +05:30
wrapper = createComponent({ group });
2021-02-22 17:27:13 +05:30
});
it.each`
attr | value
${'itemscope'} | ${'itemscope'}
${'itemtype'} | ${'https://schema.org/Organization'}
${'itemprop'} | ${'subOrganization'}
`('it does set correct $attr', ({ attr, value } = {}) => {
2021-09-30 23:02:18 +05:30
expect(wrapper.attributes(attr)).toBe(value);
2021-02-22 17:27:13 +05:30
});
it.each`
selector | propValue
2021-09-30 23:02:18 +05:30
${'img'} | ${'logo'}
2021-02-22 17:27:13 +05:30
${'[data-testid="group-name"]'} | ${'name'}
${'[data-testid="group-description"]'} | ${'description'}
`('it does set correct $selector', ({ selector, propValue } = {}) => {
2021-09-30 23:02:18 +05:30
expect(wrapper.find(selector).attributes('itemprop')).toBe(propValue);
2021-02-22 17:27:13 +05:30
});
});
});
2022-08-13 15:12:31 +05:30
describe('visibility warning popover', () => {
const findPopover = () => wrapper.findComponent(GlPopover);
const itDoesNotRenderVisibilityWarningPopover = () => {
it('does not render visibility warning popover', () => {
expect(findPopover().exists()).toBe(false);
});
};
describe('when showing groups', () => {
beforeEach(() => {
wrapper = createComponent();
});
itDoesNotRenderVisibilityWarningPopover();
});
describe('when `action` prop is not `shared`', () => {
beforeEach(() => {
wrapper = createComponent({
group: mockParentGroupItem,
parentGroup: mockChildren[0],
action: 'subgroups_and_projects',
});
});
itDoesNotRenderVisibilityWarningPopover();
});
describe('when showing projects', () => {
describe.each`
itemVisibility | currentGroupVisibility | isPopoverShown
${VISIBILITY_PRIVATE} | ${VISIBILITY_PUBLIC} | ${false}
${VISIBILITY_INTERNAL} | ${VISIBILITY_PUBLIC} | ${false}
${VISIBILITY_PUBLIC} | ${VISIBILITY_PUBLIC} | ${false}
${VISIBILITY_PRIVATE} | ${VISIBILITY_PRIVATE} | ${false}
${VISIBILITY_INTERNAL} | ${VISIBILITY_PRIVATE} | ${true}
${VISIBILITY_PUBLIC} | ${VISIBILITY_PRIVATE} | ${true}
`(
'when item visibility is $itemVisibility and parent group visibility is $currentGroupVisibility',
({ itemVisibility, currentGroupVisibility, isPopoverShown }) => {
beforeEach(() => {
wrapper = createComponent(
{
group: {
...mockParentGroupItem,
visibility: itemVisibility,
type: ITEM_TYPE.PROJECT,
},
parentGroup: mockChildren[0],
action: 'shared',
},
{
currentGroupVisibility,
},
);
});
if (isPopoverShown) {
it('renders visibility warning popover', () => {
expect(findPopover().exists()).toBe(true);
});
} else {
itDoesNotRenderVisibilityWarningPopover();
}
},
);
});
it('sets up popover `target` prop correctly', () => {
wrapper = createComponent({
group: {
...mockParentGroupItem,
visibility: VISIBILITY_PUBLIC,
type: ITEM_TYPE.PROJECT,
},
parentGroup: mockChildren[0],
action: 'shared',
});
expect(findPopover().props('target')()).toEqual(
wrapper.findByRole('button', { name: GroupItem.i18n.popoverTitle }).element,
);
});
});
2018-03-17 18:26:18 +05:30
});