Commit b7049969 authored by David O'Regan's avatar David O'Regan

Merge branch...

Merge branch '324675-group-project-members-migrate-non-reactive-state-to-provide-inject' into 'master'

Migrate non-reactive group/project member state to `provide/inject`

See merge request gitlab-org/gitlab!57633
parents ce08db1b d871b9a4
...@@ -5,7 +5,6 @@ import { ...@@ -5,7 +5,6 @@ import {
GlBadge, GlBadge,
GlSafeHtmlDirective as SafeHtml, GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { mapState } from 'vuex';
import { generateBadges } from 'ee_else_ce/members/utils'; import { generateBadges } from 'ee_else_ce/members/utils';
import { glEmojiTag } from '~/emoji'; import { glEmojiTag } from '~/emoji';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -24,6 +23,7 @@ export default { ...@@ -24,6 +23,7 @@ export default {
directives: { directives: {
SafeHtml, SafeHtml,
}, },
inject: ['canManageMembers'],
props: { props: {
member: { member: {
type: Object, type: Object,
...@@ -35,7 +35,6 @@ export default { ...@@ -35,7 +35,6 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['canManageMembers']),
user() { user() {
return this.member.user; return this.member.user;
}, },
......
...@@ -37,13 +37,14 @@ export default { ...@@ -37,13 +37,14 @@ export default {
], ],
}, },
], ],
inject: ['sourceId', 'canManageMembers'],
data() { data() {
return { return {
initialFilterValue: [], initialFilterValue: [],
}; };
}, },
computed: { computed: {
...mapState(['sourceId', 'filteredSearchBar', 'canManageMembers']), ...mapState(['filteredSearchBar']),
tokens() { tokens() {
return this.$options.availableTokens.filter((token) => { return this.$options.availableTokens.filter((token) => {
if ( if (
......
...@@ -31,8 +31,9 @@ export default { ...@@ -31,8 +31,9 @@ export default {
LdapOverrideConfirmationModal: () => LdapOverrideConfirmationModal: () =>
import('ee_component/members/components/ldap/ldap_override_confirmation_modal.vue'), import('ee_component/members/components/ldap/ldap_override_confirmation_modal.vue'),
}, },
inject: ['currentUserId'],
computed: { computed: {
...mapState(['members', 'tableFields', 'tableAttrs', 'currentUserId']), ...mapState(['members', 'tableFields', 'tableAttrs']),
filteredFields() { filteredFields() {
return FIELDS.filter( return FIELDS.filter(
(field) => this.tableFields.includes(field.key) && this.showField(field), (field) => this.tableFields.includes(field.key) && this.showField(field),
......
<script> <script>
import { mapState } from 'vuex';
import { MEMBER_TYPES } from '../../constants'; import { MEMBER_TYPES } from '../../constants';
import { import {
isGroup, isGroup,
...@@ -12,6 +11,7 @@ import { ...@@ -12,6 +11,7 @@ import {
export default { export default {
name: 'MembersTableCell', name: 'MembersTableCell',
inject: ['currentUserId'],
props: { props: {
member: { member: {
type: Object, type: Object,
...@@ -19,7 +19,6 @@ export default { ...@@ -19,7 +19,6 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['currentUserId']),
isGroup() { isGroup() {
return isGroup(this.member); return isGroup(this.member);
}, },
......
...@@ -22,10 +22,11 @@ export const initMembersApp = ( ...@@ -22,10 +22,11 @@ export const initMembersApp = (
Vue.use(Vuex); Vue.use(Vuex);
Vue.use(GlToast); Vue.use(GlToast);
const { sourceId, canManageMembers, ...vuexStoreAttributes } = parseDataAttributes(el);
const store = new Vuex.Store( const store = new Vuex.Store(
membersStore({ membersStore({
...parseDataAttributes(el), ...vuexStoreAttributes,
currentUserId: gon.current_user_id || null,
tableFields, tableFields,
tableAttrs, tableAttrs,
tableSortableFields, tableSortableFields,
...@@ -38,6 +39,11 @@ export const initMembersApp = ( ...@@ -38,6 +39,11 @@ export const initMembersApp = (
el, el,
components: { App }, components: { App },
store, store,
provide: {
currentUserId: gon.current_user_id || null,
sourceId,
canManageMembers,
},
render: (createElement) => createElement('app'), render: (createElement) => createElement('app'),
}); });
}; };
export default ({ export default ({
members, members,
sourceId,
currentUserId,
canManageMembers,
tableFields, tableFields,
tableAttrs, tableAttrs,
tableSortableFields, tableSortableFields,
...@@ -11,9 +8,6 @@ export default ({ ...@@ -11,9 +8,6 @@ export default ({
filteredSearchBar, filteredSearchBar,
}) => ({ }) => ({
members, members,
sourceId,
currentUserId,
canManageMembers,
tableFields, tableFields,
tableAttrs, tableAttrs,
tableSortableFields, tableSortableFields,
......
import { GlBadge } from '@gitlab/ui'; import { GlBadge } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import { member as memberMock } from 'jest/members/mock_data'; import { member as memberMock } from 'jest/members/mock_data';
import UserAvatar from '~/members/components/avatars/user_avatar.vue'; import UserAvatar from '~/members/components/avatars/user_avatar.vue';
Vue.use(Vuex);
describe('UserAvatar', () => { describe('UserAvatar', () => {
let wrapper; let wrapper;
...@@ -16,11 +12,9 @@ describe('UserAvatar', () => { ...@@ -16,11 +12,9 @@ describe('UserAvatar', () => {
isCurrentUser: false, isCurrentUser: false,
...propsData, ...propsData,
}, },
store: new Vuex.Store({ provide: {
state: { canManageMembers: true,
canManageMembers: true, },
},
}),
}); });
}; };
......
...@@ -34,11 +34,7 @@ describe('MemberTableCell', () => { ...@@ -34,11 +34,7 @@ describe('MemberTableCell', () => {
const createStore = (state = {}) => { const createStore = (state = {}) => {
return new Vuex.Store({ return new Vuex.Store({
state: { state,
sourceId: 1,
currentUserId: 1,
...state,
},
}); });
}; };
...@@ -49,6 +45,10 @@ describe('MemberTableCell', () => { ...@@ -49,6 +45,10 @@ describe('MemberTableCell', () => {
localVue, localVue,
propsData, propsData,
store: createStore(state), store: createStore(state),
provide: {
sourceId: 1,
currentUserId: 1,
},
scopedSlots: { scopedSlots: {
default: ` default: `
<wrapped-component <wrapped-component
......
...@@ -19,8 +19,6 @@ describe('MemberList', () => { ...@@ -19,8 +19,6 @@ describe('MemberList', () => {
table: { 'data-qa-selector': 'members_list' }, table: { 'data-qa-selector': 'members_list' },
tr: { 'data-qa-selector': 'member_row' }, tr: { 'data-qa-selector': 'member_row' },
}, },
sourceId: 1,
currentUserId: 1,
...state, ...state,
}, },
}); });
...@@ -30,6 +28,10 @@ describe('MemberList', () => { ...@@ -30,6 +28,10 @@ describe('MemberList', () => {
wrapper = mount(MembersTable, { wrapper = mount(MembersTable, {
localVue, localVue,
store: createStore(state), store: createStore(state),
provide: {
sourceId: 1,
currentUserId: 1,
},
stubs: [ stubs: [
'member-avatar', 'member-avatar',
'member-source', 'member-source',
......
import { GlAvatarLink, GlBadge } from '@gitlab/ui'; import { GlAvatarLink, GlBadge } from '@gitlab/ui';
import { within } from '@testing-library/dom'; import { within } from '@testing-library/dom';
import { mount, createWrapper } from '@vue/test-utils'; import { mount, createWrapper } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import UserAvatar from '~/members/components/avatars/user_avatar.vue'; import UserAvatar from '~/members/components/avatars/user_avatar.vue';
import { member as memberMock, member2faEnabled, orphanedMember } from '../../mock_data'; import { member as memberMock, member2faEnabled, orphanedMember } from '../../mock_data';
Vue.use(Vuex);
describe('UserAvatar', () => { describe('UserAvatar', () => {
let wrapper; let wrapper;
const { user } = memberMock; const { user } = memberMock;
const createComponent = (propsData = {}, state = {}) => { const createComponent = (propsData = {}, provide = {}) => {
wrapper = mount(UserAvatar, { wrapper = mount(UserAvatar, {
propsData: { propsData: {
member: memberMock, member: memberMock,
isCurrentUser: false, isCurrentUser: false,
...propsData, ...propsData,
}, },
store: new Vuex.Store({ provide: {
state: { canManageMembers: true,
canManageMembers: true, ...provide,
...state, },
},
}),
}); });
}; };
......
...@@ -10,10 +10,9 @@ localVue.use(Vuex); ...@@ -10,10 +10,9 @@ localVue.use(Vuex);
describe('MembersFilteredSearchBar', () => { describe('MembersFilteredSearchBar', () => {
let wrapper; let wrapper;
const createComponent = (state) => { const createComponent = ({ state = {}, provide = {} } = {}) => {
const store = new Vuex.Store({ const store = new Vuex.Store({
state: { state: {
sourceId: 1,
filteredSearchBar: { filteredSearchBar: {
show: true, show: true,
tokens: ['two_factor'], tokens: ['two_factor'],
...@@ -21,13 +20,17 @@ describe('MembersFilteredSearchBar', () => { ...@@ -21,13 +20,17 @@ describe('MembersFilteredSearchBar', () => {
placeholder: 'Filter members', placeholder: 'Filter members',
recentSearchesStorageKey: 'group_members', recentSearchesStorageKey: 'group_members',
}, },
canManageMembers: true,
...state, ...state,
}, },
}); });
wrapper = shallowMount(MembersFilteredSearchBar, { wrapper = shallowMount(MembersFilteredSearchBar, {
localVue, localVue,
provide: {
sourceId: 1,
canManageMembers: true,
...provide,
},
store, store,
}); });
}; };
...@@ -68,14 +71,18 @@ describe('MembersFilteredSearchBar', () => { ...@@ -68,14 +71,18 @@ describe('MembersFilteredSearchBar', () => {
describe('when `canManageMembers` is false', () => { describe('when `canManageMembers` is false', () => {
it('excludes 2FA token', () => { it('excludes 2FA token', () => {
createComponent({ createComponent({
filteredSearchBar: { state: {
show: true, filteredSearchBar: {
tokens: ['two_factor', 'with_inherited_permissions'], show: true,
searchParam: 'search', tokens: ['two_factor', 'with_inherited_permissions'],
placeholder: 'Filter members', searchParam: 'search',
recentSearchesStorageKey: 'group_members', placeholder: 'Filter members',
recentSearchesStorageKey: 'group_members',
},
},
provide: {
canManageMembers: false,
}, },
canManageMembers: false,
}); });
expect(findFilteredSearchBar().props('tokens')).toEqual([ expect(findFilteredSearchBar().props('tokens')).toEqual([
......
...@@ -15,7 +15,6 @@ describe('SortDropdown', () => { ...@@ -15,7 +15,6 @@ describe('SortDropdown', () => {
const createComponent = (state) => { const createComponent = (state) => {
const store = new Vuex.Store({ const store = new Vuex.Store({
state: { state: {
sourceId: 1,
tableSortableFields: ['account', 'granted', 'expires', 'maxRole', 'lastSignIn'], tableSortableFields: ['account', 'granted', 'expires', 'maxRole', 'lastSignIn'],
filteredSearchBar: { filteredSearchBar: {
show: true, show: true,
...@@ -30,6 +29,9 @@ describe('SortDropdown', () => { ...@@ -30,6 +29,9 @@ describe('SortDropdown', () => {
wrapper = mount(SortDropdown, { wrapper = mount(SortDropdown, {
localVue, localVue,
provide: {
sourceId: 1,
},
store, store,
}); });
}; };
......
...@@ -42,21 +42,21 @@ describe('MembersTableCell', () => { ...@@ -42,21 +42,21 @@ describe('MembersTableCell', () => {
const createStore = (state = {}) => { const createStore = (state = {}) => {
return new Vuex.Store({ return new Vuex.Store({
state: { state,
sourceId: 1,
currentUserId: 1,
...state,
},
}); });
}; };
let wrapper; let wrapper;
const createComponent = (propsData, state = {}) => { const createComponent = (propsData, state) => {
wrapper = mount(MembersTableCell, { wrapper = mount(MembersTableCell, {
localVue, localVue,
propsData, propsData,
store: createStore(state), store: createStore(state),
provide: {
sourceId: 1,
currentUserId: 1,
},
scopedSlots: { scopedSlots: {
default: ` default: `
<wrapped-component <wrapped-component
......
...@@ -32,17 +32,20 @@ describe('MembersTable', () => { ...@@ -32,17 +32,20 @@ describe('MembersTable', () => {
table: { 'data-qa-selector': 'members_list' }, table: { 'data-qa-selector': 'members_list' },
tr: { 'data-qa-selector': 'member_row' }, tr: { 'data-qa-selector': 'member_row' },
}, },
sourceId: 1,
currentUserId: 1,
...state, ...state,
}, },
}); });
}; };
const createComponent = (state) => { const createComponent = (state, provide = {}) => {
wrapper = mount(MembersTable, { wrapper = mount(MembersTable, {
localVue, localVue,
store: createStore(state), store: createStore(state),
provide: {
sourceId: 1,
currentUserId: 1,
...provide,
},
stubs: [ stubs: [
'member-avatar', 'member-avatar',
'member-source', 'member-source',
...@@ -119,7 +122,7 @@ describe('MembersTable', () => { ...@@ -119,7 +122,7 @@ describe('MembersTable', () => {
describe('when user is not logged in', () => { describe('when user is not logged in', () => {
it('does not render the "Actions" field', () => { it('does not render the "Actions" field', () => {
createComponent({ currentUserId: null, tableFields: ['actions'] }); createComponent({ tableFields: ['actions'] }, { currentUserId: null });
expect(within(wrapper.element).queryByTestId('col-actions')).toBe(null); expect(within(wrapper.element).queryByTestId('col-actions')).toBe(null);
}); });
......
...@@ -42,33 +42,6 @@ describe('initMembersApp', () => { ...@@ -42,33 +42,6 @@ describe('initMembersApp', () => {
expect(wrapper.find(MembersApp).exists()).toBe(true); expect(wrapper.find(MembersApp).exists()).toBe(true);
}); });
it('sets `currentUserId` in Vuex store', () => {
setup();
expect(vm.$store.state.currentUserId).toBe(123);
});
describe('when `gon.current_user_id` is not set (user is not logged in)', () => {
it('sets `currentUserId` as `null` in Vuex store', () => {
window.gon = {};
setup();
expect(vm.$store.state.currentUserId).toBeNull();
});
});
it('parses and sets `data-source-id` as `sourceId` in Vuex store', () => {
setup();
expect(vm.$store.state.sourceId).toBe(234);
});
it('parses and sets `data-can-manage-members` as `canManageMembers` in Vuex store', () => {
setup();
expect(vm.$store.state.canManageMembers).toBe(true);
});
it('parses and sets `members` in Vuex store', () => { it('parses and sets `members` in Vuex store', () => {
setup(); setup();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment