diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/frontend/groups | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/frontend/groups')
-rw-r--r-- | spec/frontend/groups/components/group_item_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/groups/components/item_actions_spec.js | 125 | ||||
-rw-r--r-- | spec/frontend/groups/components/item_caret_spec.js | 58 | ||||
-rw-r--r-- | spec/frontend/groups/components/item_stats_spec.js | 131 | ||||
-rw-r--r-- | spec/frontend/groups/components/item_stats_value_spec.js | 111 | ||||
-rw-r--r-- | spec/frontend/groups/components/item_type_icon_spec.js | 80 | ||||
-rw-r--r-- | spec/frontend/groups/members/components/app_spec.js | 89 | ||||
-rw-r--r-- | spec/frontend/groups/members/index_spec.js | 26 | ||||
-rw-r--r-- | spec/frontend/groups/members/utils_spec.js | 51 |
9 files changed, 379 insertions, 294 deletions
diff --git a/spec/frontend/groups/components/group_item_spec.js b/spec/frontend/groups/components/group_item_spec.js index 7eb1c54ddb2..83acbb152b5 100644 --- a/spec/frontend/groups/components/group_item_spec.js +++ b/spec/frontend/groups/components/group_item_spec.js @@ -203,7 +203,7 @@ describe('GroupItemComponent', () => { expect(vm.$el.querySelector('.title a.no-expand')).toBeDefined(); expect(visibilityIconEl).not.toBe(null); - expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip); + expect(visibilityIconEl.title).toBe(vm.visibilityTooltip); expect(visibilityIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); expect(vm.$el.querySelector('.access-type')).toBeDefined(); diff --git a/spec/frontend/groups/components/item_actions_spec.js b/spec/frontend/groups/components/item_actions_spec.js index f5df8c180d5..d4aa29eaadd 100644 --- a/spec/frontend/groups/components/item_actions_spec.js +++ b/spec/frontend/groups/components/item_actions_spec.js @@ -1,84 +1,87 @@ -import Vue from 'vue'; - -import mountComponent from 'helpers/vue_mount_component_helper'; -import itemActionsComponent from '~/groups/components/item_actions.vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlIcon } from '@gitlab/ui'; +import ItemActions from '~/groups/components/item_actions.vue'; import eventHub from '~/groups/event_hub'; import { mockParentGroupItem, mockChildren } from '../mock_data'; -const createComponent = (group = mockParentGroupItem, parentGroup = mockChildren[0]) => { - const Component = Vue.extend(itemActionsComponent); +describe('ItemActions', () => { + let wrapper; + const parentGroup = mockChildren[0]; - return mountComponent(Component, { - group, + const defaultProps = { + group: mockParentGroupItem, parentGroup, - }); -}; - -describe('ItemActionsComponent', () => { - let vm; + }; - beforeEach(() => { - vm = createComponent(); - }); + const createComponent = (props = {}) => { + wrapper = shallowMount(ItemActions, { + propsData: { ...defaultProps, ...props }, + }); + }; afterEach(() => { - vm.$destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); - describe('methods', () => { - describe('onLeaveGroup', () => { - it('emits `showLeaveGroupModal` event with `group` and `parentGroup` props', () => { - jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - vm.onLeaveGroup(); - - expect(eventHub.$emit).toHaveBeenCalledWith( - 'showLeaveGroupModal', - vm.group, - vm.parentGroup, - ); - }); - }); - }); + const findEditGroupBtn = () => wrapper.find('[data-testid="edit-group-btn"]'); + const findEditGroupIcon = () => findEditGroupBtn().find(GlIcon); + const findLeaveGroupBtn = () => wrapper.find('[data-testid="leave-group-btn"]'); + const findLeaveGroupIcon = () => findLeaveGroupBtn().find(GlIcon); describe('template', () => { - it('should render component template correctly', () => { - expect(vm.$el.classList.contains('controls')).toBeTruthy(); - }); + it('renders component template correctly', () => { + createComponent(); - it('should render Edit Group button with correct attribute values', () => { - const group = { ...mockParentGroupItem }; - group.canEdit = true; - const newVm = createComponent(group); + expect(wrapper.classes()).toContain('controls'); + }); - const editBtn = newVm.$el.querySelector('a.edit-group'); + it('renders "Edit group" button with correct attribute values', () => { + const group = { + ...mockParentGroupItem, + canEdit: true, + }; + + createComponent({ group }); + + expect(findEditGroupBtn().exists()).toBe(true); + expect(findEditGroupBtn().classes()).toContain('no-expand'); + expect(findEditGroupBtn().attributes('href')).toBe(group.editPath); + expect(findEditGroupBtn().attributes('aria-label')).toBe('Edit group'); + expect(findEditGroupBtn().attributes('data-original-title')).toBe('Edit group'); + expect(findEditGroupIcon().exists()).toBe(true); + expect(findEditGroupIcon().props('name')).toBe('settings'); + }); - expect(editBtn).toBeDefined(); - expect(editBtn.classList.contains('no-expand')).toBeTruthy(); - expect(editBtn.getAttribute('href')).toBe(group.editPath); - expect(editBtn.getAttribute('aria-label')).toBe('Edit group'); - expect(editBtn.dataset.originalTitle).toBe('Edit group'); - expect(editBtn.querySelectorAll('svg').length).not.toBe(0); - expect(editBtn.querySelector('svg').getAttribute('data-testid')).toBe('settings-icon'); + describe('`canLeave` is true', () => { + const group = { + ...mockParentGroupItem, + canLeave: true, + }; - newVm.$destroy(); - }); + beforeEach(() => { + createComponent({ group }); + }); - it('should render Leave Group button with correct attribute values', () => { - const group = { ...mockParentGroupItem }; - group.canLeave = true; - const newVm = createComponent(group); + it('renders "Leave this group" button with correct attribute values', () => { + expect(findLeaveGroupBtn().exists()).toBe(true); + expect(findLeaveGroupBtn().classes()).toContain('no-expand'); + expect(findLeaveGroupBtn().attributes('href')).toBe(group.leavePath); + expect(findLeaveGroupBtn().attributes('aria-label')).toBe('Leave this group'); + expect(findLeaveGroupBtn().attributes('data-original-title')).toBe('Leave this group'); + expect(findLeaveGroupIcon().exists()).toBe(true); + expect(findLeaveGroupIcon().props('name')).toBe('leave'); + }); - const leaveBtn = newVm.$el.querySelector('a.leave-group'); + it('emits event on "Leave this group" button click', () => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - expect(leaveBtn).toBeDefined(); - expect(leaveBtn.classList.contains('no-expand')).toBeTruthy(); - expect(leaveBtn.getAttribute('href')).toBe(group.leavePath); - expect(leaveBtn.getAttribute('aria-label')).toBe('Leave this group'); - expect(leaveBtn.dataset.originalTitle).toBe('Leave this group'); - expect(leaveBtn.querySelectorAll('svg').length).not.toBe(0); - expect(leaveBtn.querySelector('svg').getAttribute('data-testid')).toBe('leave-icon'); + findLeaveGroupBtn().trigger('click'); - newVm.$destroy(); + expect(eventHub.$emit).toHaveBeenCalledWith('showLeaveGroupModal', group, parentGroup); + }); }); }); }); diff --git a/spec/frontend/groups/components/item_caret_spec.js b/spec/frontend/groups/components/item_caret_spec.js index 4ff7482414c..b2915607a06 100644 --- a/spec/frontend/groups/components/item_caret_spec.js +++ b/spec/frontend/groups/components/item_caret_spec.js @@ -1,38 +1,48 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlIcon } from '@gitlab/ui'; +import ItemCaret from '~/groups/components/item_caret.vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import itemCaretComponent from '~/groups/components/item_caret.vue'; +describe('ItemCaret', () => { + let wrapper; -const createComponent = (isGroupOpen = false) => { - const Component = Vue.extend(itemCaretComponent); + const defaultProps = { + isGroupOpen: false, + }; - return mountComponent(Component, { - isGroupOpen, - }); -}; - -describe('ItemCaretComponent', () => { - let vm; + const createComponent = (props = {}) => { + wrapper = shallowMount(ItemCaret, { + propsData: { ...defaultProps, ...props }, + }); + }; afterEach(() => { - vm.$destroy(); + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); + const findAllGlIcons = () => wrapper.findAll(GlIcon); + const findGlIcon = () => wrapper.find(GlIcon); + describe('template', () => { - it('should render component template correctly', () => { - vm = createComponent(); - expect(vm.$el.classList.contains('folder-caret')).toBeTruthy(); - expect(vm.$el.querySelectorAll('svg').length).toBe(1); - }); + it('renders component template correctly', () => { + createComponent(); - it('should render caret down icon if `isGroupOpen` prop is `true`', () => { - vm = createComponent(true); - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('angle-down-icon'); + expect(wrapper.classes()).toContain('folder-caret'); + expect(findAllGlIcons()).toHaveLength(1); }); - it('should render caret right icon if `isGroupOpen` prop is `false`', () => { - vm = createComponent(); - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('angle-right-icon'); + it.each` + isGroupOpen | icon + ${true} | ${'angle-down'} + ${false} | ${'angle-right'} + `('renders "$icon" icon when `isGroupOpen` is $isGroupOpen', ({ isGroupOpen, icon }) => { + createComponent({ + isGroupOpen, + }); + + expect(findGlIcon().props('name')).toBe(icon); }); }); }); diff --git a/spec/frontend/groups/components/item_stats_spec.js b/spec/frontend/groups/components/item_stats_spec.js index 771643609ec..d8c88a608ac 100644 --- a/spec/frontend/groups/components/item_stats_spec.js +++ b/spec/frontend/groups/components/item_stats_spec.js @@ -1,119 +1,50 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import ItemStats from '~/groups/components/item_stats.vue'; +import ItemStatsValue from '~/groups/components/item_stats_value.vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import itemStatsComponent from '~/groups/components/item_stats.vue'; -import { - mockParentGroupItem, - ITEM_TYPE, - VISIBILITY_TYPE_ICON, - GROUP_VISIBILITY_TYPE, - PROJECT_VISIBILITY_TYPE, -} from '../mock_data'; +import { mockParentGroupItem, ITEM_TYPE } from '../mock_data'; -const createComponent = (item = mockParentGroupItem) => { - const Component = Vue.extend(itemStatsComponent); +describe('ItemStats', () => { + let wrapper; - return mountComponent(Component, { - item, - }); -}; - -describe('ItemStatsComponent', () => { - describe('computed', () => { - describe('visibilityIcon', () => { - it('should return icon class based on `item.visibility` value', () => { - Object.keys(VISIBILITY_TYPE_ICON).forEach(visibility => { - const item = { ...mockParentGroupItem, visibility }; - const vm = createComponent(item); + const defaultProps = { + item: mockParentGroupItem, + }; - expect(vm.visibilityIcon).toBe(VISIBILITY_TYPE_ICON[visibility]); - vm.$destroy(); - }); - }); + const createComponent = (props = {}) => { + wrapper = shallowMount(ItemStats, { + propsData: { ...defaultProps, ...props }, }); + }; - describe('visibilityTooltip', () => { - it('should return tooltip string for Group based on `item.visibility` value', () => { - Object.keys(GROUP_VISIBILITY_TYPE).forEach(visibility => { - const item = { ...mockParentGroupItem, visibility, type: ITEM_TYPE.GROUP }; - const vm = createComponent(item); - - expect(vm.visibilityTooltip).toBe(GROUP_VISIBILITY_TYPE[visibility]); - vm.$destroy(); - }); - }); - - it('should return tooltip string for Project based on `item.visibility` value', () => { - Object.keys(PROJECT_VISIBILITY_TYPE).forEach(visibility => { - const item = { ...mockParentGroupItem, visibility, type: ITEM_TYPE.PROJECT }; - const vm = createComponent(item); - - expect(vm.visibilityTooltip).toBe(PROJECT_VISIBILITY_TYPE[visibility]); - vm.$destroy(); - }); - }); - }); - - describe('isProject', () => { - it('should return boolean value representing whether `item.type` is Project or not', () => { - let item; - let vm; - - item = { ...mockParentGroupItem, type: ITEM_TYPE.PROJECT }; - vm = createComponent(item); - - expect(vm.isProject).toBeTruthy(); - vm.$destroy(); - - item = { ...mockParentGroupItem, type: ITEM_TYPE.GROUP }; - vm = createComponent(item); - - expect(vm.isProject).toBeFalsy(); - vm.$destroy(); - }); - }); - - describe('isGroup', () => { - it('should return boolean value representing whether `item.type` is Group or not', () => { - let item; - let vm; - - item = { ...mockParentGroupItem, type: ITEM_TYPE.GROUP }; - vm = createComponent(item); - - expect(vm.isGroup).toBeTruthy(); - vm.$destroy(); - - item = { ...mockParentGroupItem, type: ITEM_TYPE.PROJECT }; - vm = createComponent(item); - - expect(vm.isGroup).toBeFalsy(); - vm.$destroy(); - }); - }); + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); + const findItemStatsValue = () => wrapper.find(ItemStatsValue); + describe('template', () => { it('renders component container element correctly', () => { - const vm = createComponent(); + createComponent(); - expect(vm.$el.classList.contains('stats')).toBeTruthy(); - - vm.$destroy(); + expect(wrapper.classes()).toContain('stats'); }); it('renders start count and last updated information for project item correctly', () => { - const item = { ...mockParentGroupItem, type: ITEM_TYPE.PROJECT, starCount: 4 }; - const vm = createComponent(item); - - const projectStarIconEl = vm.$el.querySelector('.project-stars'); + const item = { + ...mockParentGroupItem, + type: ITEM_TYPE.PROJECT, + starCount: 4, + }; - expect(projectStarIconEl).not.toBeNull(); - expect(projectStarIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); - expect(projectStarIconEl.querySelectorAll('.stat-value').length).toBeGreaterThan(0); - expect(vm.$el.querySelectorAll('.last-updated').length).toBeGreaterThan(0); + createComponent({ item }); - vm.$destroy(); + expect(findItemStatsValue().exists()).toBe(true); + expect(findItemStatsValue().props('cssClass')).toBe('project-stars'); + expect(wrapper.contains('.last-updated')).toBe(true); }); }); }); diff --git a/spec/frontend/groups/components/item_stats_value_spec.js b/spec/frontend/groups/components/item_stats_value_spec.js index 11246390444..bca233883af 100644 --- a/spec/frontend/groups/components/item_stats_value_spec.js +++ b/spec/frontend/groups/components/item_stats_value_spec.js @@ -1,82 +1,67 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlIcon } from '@gitlab/ui'; +import ItemStatsValue from '~/groups/components/item_stats_value.vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import itemStatsValueComponent from '~/groups/components/item_stats_value.vue'; +describe('ItemStatsValue', () => { + let wrapper; -const createComponent = ({ title, cssClass, iconName, tooltipPlacement, value }) => { - const Component = Vue.extend(itemStatsValueComponent); + const defaultProps = { + title: 'Subgroups', + cssClass: 'number-subgroups', + iconName: 'folder', + tooltipPlacement: 'left', + }; - return mountComponent(Component, { - title, - cssClass, - iconName, - tooltipPlacement, - value, + const createComponent = (props = {}) => { + wrapper = shallowMount(ItemStatsValue, { + propsData: { ...defaultProps, ...props }, + }); + }; + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } }); -}; -describe('ItemStatsValueComponent', () => { - describe('computed', () => { - let vm; - const itemConfig = { - title: 'Subgroups', - cssClass: 'number-subgroups', - iconName: 'folder', - tooltipPlacement: 'left', - }; + const findGlIcon = () => wrapper.find(GlIcon); + const findStatValue = () => wrapper.find('[data-testid="itemStatValue"]'); - describe('isValuePresent', () => { - it('returns true if non-empty `value` is present', () => { - vm = createComponent({ ...itemConfig, value: 10 }); + describe('template', () => { + describe('when `value` is not provided', () => { + it('does not render value count', () => { + createComponent(); - expect(vm.isValuePresent).toBeTruthy(); + expect(findStatValue().exists()).toBe(false); }); + }); - it('returns false if empty `value` is present', () => { - vm = createComponent(itemConfig); - - expect(vm.isValuePresent).toBeFalsy(); + describe('when `value` is provided', () => { + beforeEach(() => { + createComponent({ + value: 10, + }); }); - afterEach(() => { - vm.$destroy(); + it('renders component element correctly', () => { + expect(wrapper.classes()).toContain('number-subgroups'); }); - }); - }); - describe('template', () => { - let vm; - beforeEach(() => { - vm = createComponent({ - title: 'Subgroups', - cssClass: 'number-subgroups', - iconName: 'folder', - tooltipPlacement: 'left', - value: 10, + it('renders element tooltip correctly', () => { + expect(wrapper.attributes('title')).toBe('Subgroups'); + expect(wrapper.attributes('data-placement')).toBe('left'); }); - }); - afterEach(() => { - vm.$destroy(); - }); - - it('renders component element correctly', () => { - expect(vm.$el.classList.contains('number-subgroups')).toBeTruthy(); - expect(vm.$el.querySelectorAll('svg').length).toBeGreaterThan(0); - expect(vm.$el.querySelectorAll('.stat-value').length).toBeGreaterThan(0); - }); - - it('renders element tooltip correctly', () => { - expect(vm.$el.dataset.originalTitle).toBe('Subgroups'); - expect(vm.$el.dataset.placement).toBe('left'); - }); - - it('renders element icon correctly', () => { - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('folder-icon'); - }); + it('renders element icon correctly', () => { + expect(findGlIcon().exists()).toBe(true); + expect(findGlIcon().props('name')).toBe('folder'); + }); - it('renders value count correctly', () => { - expect(vm.$el.querySelector('.stat-value').innerText.trim()).toContain('10'); + it('renders value count correctly', () => { + expect(findStatValue().classes()).toContain('stat-value'); + expect(findStatValue().text()).toBe('10'); + }); }); }); }); diff --git a/spec/frontend/groups/components/item_type_icon_spec.js b/spec/frontend/groups/components/item_type_icon_spec.js index 477c413ddcd..5e7056be218 100644 --- a/spec/frontend/groups/components/item_type_icon_spec.js +++ b/spec/frontend/groups/components/item_type_icon_spec.js @@ -1,53 +1,53 @@ -import Vue from 'vue'; - -import mountComponent from 'helpers/vue_mount_component_helper'; -import itemTypeIconComponent from '~/groups/components/item_type_icon.vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlIcon } from '@gitlab/ui'; +import ItemTypeIcon from '~/groups/components/item_type_icon.vue'; import { ITEM_TYPE } from '../mock_data'; -const createComponent = (itemType = ITEM_TYPE.GROUP, isGroupOpen = false) => { - const Component = Vue.extend(itemTypeIconComponent); - - return mountComponent(Component, { - itemType, - isGroupOpen, - }); -}; +describe('ItemTypeIcon', () => { + let wrapper; -describe('ItemTypeIconComponent', () => { - describe('template', () => { - it('should render component template correctly', () => { - const vm = createComponent(); + const defaultProps = { + itemType: ITEM_TYPE.GROUP, + isGroupOpen: false, + }; - expect(vm.$el.classList.contains('item-type-icon')).toBeTruthy(); - vm.$destroy(); + const createComponent = (props = {}) => { + wrapper = shallowMount(ItemTypeIcon, { + propsData: { ...defaultProps, ...props }, }); + }; - it('should render folder open or close icon based `isGroupOpen` prop value', () => { - let vm; - - vm = createComponent(ITEM_TYPE.GROUP, true); + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } + }); - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('folder-open-icon'); - vm.$destroy(); + const findGlIcon = () => wrapper.find(GlIcon); - vm = createComponent(ITEM_TYPE.GROUP); + describe('template', () => { + it('renders component template correctly', () => { + createComponent(); - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('folder-o-icon'); - vm.$destroy(); + expect(wrapper.classes()).toContain('item-type-icon'); }); - it('should render bookmark icon based on `isProject` prop value', () => { - let vm; - - vm = createComponent(ITEM_TYPE.PROJECT); - - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).toBe('bookmark-icon'); - vm.$destroy(); - - vm = createComponent(ITEM_TYPE.GROUP); - - expect(vm.$el.querySelector('svg').getAttribute('data-testid')).not.toBe('bookmark-icon'); - vm.$destroy(); - }); + it.each` + type | isGroupOpen | icon + ${ITEM_TYPE.GROUP} | ${true} | ${'folder-open'} + ${ITEM_TYPE.GROUP} | ${false} | ${'folder-o'} + ${ITEM_TYPE.PROJECT} | ${true} | ${'bookmark'} + ${ITEM_TYPE.PROJECT} | ${false} | ${'bookmark'} + `( + 'shows "$icon" icon when `itemType` is "$type" and `isGroupOpen` is $isGroupOpen', + ({ type, isGroupOpen, icon }) => { + createComponent({ + itemType: type, + isGroupOpen, + }); + expect(findGlIcon().props('name')).toBe(icon); + }, + ); }); }); diff --git a/spec/frontend/groups/members/components/app_spec.js b/spec/frontend/groups/members/components/app_spec.js new file mode 100644 index 00000000000..de9f30649e9 --- /dev/null +++ b/spec/frontend/groups/members/components/app_spec.js @@ -0,0 +1,89 @@ +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import Vuex from 'vuex'; +import { GlAlert } from '@gitlab/ui'; +import App from '~/groups/members/components/app.vue'; +import * as commonUtils from '~/lib/utils/common_utils'; +import { + RECEIVE_MEMBER_ROLE_ERROR, + HIDE_ERROR, +} from '~/vuex_shared/modules/members/mutation_types'; +import mutations from '~/vuex_shared/modules/members/mutations'; + +describe('GroupMembersApp', () => { + const localVue = createLocalVue(); + localVue.use(Vuex); + + let wrapper; + let store; + + const createComponent = (state = {}) => { + store = new Vuex.Store({ + state: { + showError: true, + errorMessage: 'Something went wrong, please try again.', + ...state, + }, + mutations, + }); + + wrapper = shallowMount(App, { + localVue, + store, + }); + }; + + const findAlert = () => wrapper.find(GlAlert); + + beforeEach(() => { + commonUtils.scrollToElement = jest.fn(); + }); + + afterEach(() => { + wrapper.destroy(); + store = null; + }); + + describe('when `showError` is changed to `true`', () => { + it('renders and scrolls to error alert', async () => { + createComponent({ showError: false, errorMessage: '' }); + + store.commit(RECEIVE_MEMBER_ROLE_ERROR); + + await nextTick(); + + const alert = findAlert(); + + expect(alert.exists()).toBe(true); + expect(alert.text()).toBe( + "An error occurred while updating the member's role, please try again.", + ); + expect(commonUtils.scrollToElement).toHaveBeenCalledWith(alert.element); + }); + }); + + describe('when `showError` is changed to `false`', () => { + it('does not render and scroll to error alert', async () => { + createComponent(); + + store.commit(HIDE_ERROR); + + await nextTick(); + + expect(findAlert().exists()).toBe(false); + expect(commonUtils.scrollToElement).not.toHaveBeenCalled(); + }); + }); + + describe('when alert is dismissed', () => { + it('hides alert', async () => { + createComponent(); + + findAlert().vm.$emit('dismiss'); + + await nextTick(); + + expect(findAlert().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/groups/members/index_spec.js b/spec/frontend/groups/members/index_spec.js index 70fce0d60fb..2fb7904bcfe 100644 --- a/spec/frontend/groups/members/index_spec.js +++ b/spec/frontend/groups/members/index_spec.js @@ -1,5 +1,5 @@ import { createWrapper } from '@vue/test-utils'; -import initGroupMembersApp from '~/groups/members'; +import { initGroupMembersApp } from '~/groups/members'; import GroupMembersApp from '~/groups/members/components/app.vue'; import { membersJsonString, membersParsed } from './mock_data'; @@ -9,7 +9,7 @@ describe('initGroupMembersApp', () => { let wrapper; const setup = () => { - vm = initGroupMembersApp(el); + vm = initGroupMembersApp(el, ['account'], () => ({})); wrapper = createWrapper(vm); }; @@ -17,14 +17,12 @@ describe('initGroupMembersApp', () => { el = document.createElement('div'); el.setAttribute('data-members', membersJsonString); el.setAttribute('data-group-id', '234'); + el.setAttribute('data-member-path', '/groups/foo-bar/-/group_members/:id'); window.gon = { current_user_id: 123 }; - - document.body.appendChild(el); }); afterEach(() => { - document.body.innerHTML = ''; el = null; wrapper.destroy(); @@ -63,4 +61,22 @@ describe('initGroupMembersApp', () => { expect(vm.$store.state.members).toEqual(membersParsed); }); + + it('sets `tableFields` in Vuex store', () => { + setup(); + + expect(vm.$store.state.tableFields).toEqual(['account']); + }); + + it('sets `requestFormatter` in Vuex store', () => { + setup(); + + expect(vm.$store.state.requestFormatter()).toEqual({}); + }); + + it('sets `memberPath` in Vuex store', () => { + setup(); + + expect(vm.$store.state.memberPath).toBe('/groups/foo-bar/-/group_members/:id'); + }); }); diff --git a/spec/frontend/groups/members/utils_spec.js b/spec/frontend/groups/members/utils_spec.js new file mode 100644 index 00000000000..b0921c7642f --- /dev/null +++ b/spec/frontend/groups/members/utils_spec.js @@ -0,0 +1,51 @@ +import { membersJsonString, membersParsed } from './mock_data'; +import { + parseDataAttributes, + memberRequestFormatter, + groupLinkRequestFormatter, +} from '~/groups/members/utils'; + +describe('group member utils', () => { + describe('parseDataAttributes', () => { + let el; + + beforeEach(() => { + el = document.createElement('div'); + el.setAttribute('data-members', membersJsonString); + el.setAttribute('data-group-id', '234'); + }); + + afterEach(() => { + el = null; + }); + + it('correctly parses the data attributes', () => { + expect(parseDataAttributes(el)).toEqual({ + members: membersParsed, + sourceId: 234, + }); + }); + }); + + describe('memberRequestFormatter', () => { + it('returns expected format', () => { + expect( + memberRequestFormatter({ + accessLevel: 50, + expires_at: '2020-10-16', + }), + ).toEqual({ group_member: { access_level: 50, expires_at: '2020-10-16' } }); + }); + }); + + describe('groupLinkRequestFormatter', () => { + it('returns expected format', () => { + expect( + groupLinkRequestFormatter({ + accessLevel: 50, + expires_at: '2020-10-16', + }), + ).toEqual({ group_link: { group_access: 50, expires_at: '2020-10-16' } }); + }); + }); +}); |