Commit fe289694 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch...

Merge branch '281815-convert-project-members-list-view-from-haml-to-vue-setup-vue-application' into 'master'

Move some shared code to `members` directory [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!51520
parents 994c02bf db742fb7
export const GROUP_MEMBER_BASE_PROPERTY_NAME = 'group_member'; export const GROUP_MEMBER_BASE_PROPERTY_NAME = 'group_member';
export const GROUP_MEMBER_ACCESS_LEVEL_PROPERTY_NAME = 'access_level';
export const GROUP_LINK_BASE_PROPERTY_NAME = 'group_link';
export const GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME = 'group_access';
import { isUndefined } from 'lodash'; import { baseRequestFormatter } from '~/members/utils';
import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils'; import { MEMBER_ACCESS_LEVEL_PROPERTY_NAME } from '~/members/constants';
import { import { GROUP_MEMBER_BASE_PROPERTY_NAME } from './constants';
GROUP_MEMBER_BASE_PROPERTY_NAME,
GROUP_MEMBER_ACCESS_LEVEL_PROPERTY_NAME,
GROUP_LINK_BASE_PROPERTY_NAME,
GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
} from './constants';
export const parseDataAttributes = (el) => {
const { members, groupId, memberPath, canManageMembers } = el.dataset;
return {
members: convertObjectPropsToCamelCase(JSON.parse(members), { deep: true }),
sourceId: parseInt(groupId, 10),
memberPath,
canManageMembers: parseBoolean(canManageMembers),
};
};
const baseRequestFormatter = (basePropertyName, accessLevelPropertyName) => ({
accessLevel,
...otherProperties
}) => {
const accessLevelProperty = !isUndefined(accessLevel)
? { [accessLevelPropertyName]: accessLevel }
: {};
return { export const groupMemberRequestFormatter = baseRequestFormatter(
[basePropertyName]: {
...accessLevelProperty,
...otherProperties,
},
};
};
export const memberRequestFormatter = baseRequestFormatter(
GROUP_MEMBER_BASE_PROPERTY_NAME, GROUP_MEMBER_BASE_PROPERTY_NAME,
GROUP_MEMBER_ACCESS_LEVEL_PROPERTY_NAME, MEMBER_ACCESS_LEVEL_PROPERTY_NAME,
);
export const groupLinkRequestFormatter = baseRequestFormatter(
GROUP_LINK_BASE_PROPERTY_NAME,
GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
); );
<script> <script>
import { mapState, mapMutations } from 'vuex'; import { mapState, mapMutations } from 'vuex';
import { GlAlert } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import MembersTable from '~/members/components/table/members_table.vue'; import MembersTable from './table/members_table.vue';
import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue'; import FilterSortContainer from './filter_sort/filter_sort_container.vue';
import { HIDE_ERROR } from '../store/mutation_types';
import { scrollToElement } from '~/lib/utils/common_utils'; import { scrollToElement } from '~/lib/utils/common_utils';
import { HIDE_ERROR } from '~/members/store/mutation_types';
export default { export default {
name: 'GroupMembersApp', name: 'MembersApp',
components: { MembersTable, FilterSortContainer, GlAlert }, components: { MembersTable, FilterSortContainer, GlAlert },
computed: { computed: {
...mapState(['showError', 'errorMessage']), ...mapState(['showError', 'errorMessage']),
......
...@@ -98,3 +98,8 @@ export const REMOVE_GROUP_LINK_MODAL_ID = 'remove-group-link-modal-id'; ...@@ -98,3 +98,8 @@ export const REMOVE_GROUP_LINK_MODAL_ID = 'remove-group-link-modal-id';
export const SEARCH_TOKEN_TYPE = 'filtered-search-term'; export const SEARCH_TOKEN_TYPE = 'filtered-search-term';
export const SORT_PARAM = 'sort'; export const SORT_PARAM = 'sort';
export const MEMBER_ACCESS_LEVEL_PROPERTY_NAME = 'access_level';
export const GROUP_LINK_BASE_PROPERTY_NAME = 'group_link';
export const GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME = 'group_access';
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { GlToast } from '@gitlab/ui'; import { GlToast } from '@gitlab/ui';
import { parseDataAttributes } from 'ee_else_ce/groups/members/utils'; import { parseDataAttributes } from 'ee_else_ce/members/utils';
import App from './components/app.vue'; import App from './components/app.vue';
import membersStore from '~/members/store'; import membersStore from './store';
export const initGroupMembersApp = ( export const initMembersApp = (
el, el,
{ {
tableFields = [], tableFields = [],
......
import { isUndefined } from 'lodash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { getParameterByName } from '~/lib/utils/common_utils'; import {
getParameterByName,
convertObjectPropsToCamelCase,
parseBoolean,
} from '~/lib/utils/common_utils';
import { setUrlParams } from '~/lib/utils/url_utility'; import { setUrlParams } from '~/lib/utils/url_utility';
import { FIELDS, DEFAULT_SORT } from './constants'; import {
FIELDS,
DEFAULT_SORT,
GROUP_LINK_BASE_PROPERTY_NAME,
GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
} from './constants';
export const generateBadges = (member, isCurrentUser) => [ export const generateBadges = (member, isCurrentUser) => [
{ {
...@@ -95,3 +105,35 @@ export const buildSortHref = ({ ...@@ -95,3 +105,35 @@ export const buildSortHref = ({
// Defined in `ee/app/assets/javascripts/vue_shared/components/members/utils.js` // Defined in `ee/app/assets/javascripts/vue_shared/components/members/utils.js`
export const canOverride = () => false; export const canOverride = () => false;
export const parseDataAttributes = (el) => {
const { members, sourceId, memberPath, canManageMembers } = el.dataset;
return {
members: convertObjectPropsToCamelCase(JSON.parse(members), { deep: true }),
sourceId: parseInt(sourceId, 10),
memberPath,
canManageMembers: parseBoolean(canManageMembers),
};
};
export const baseRequestFormatter = (basePropertyName, accessLevelPropertyName) => ({
accessLevel,
...otherProperties
}) => {
const accessLevelProperty = !isUndefined(accessLevel)
? { [accessLevelPropertyName]: accessLevel }
: {};
return {
[basePropertyName]: {
...accessLevelProperty,
...otherProperties,
},
};
};
export const groupLinkRequestFormatter = baseRequestFormatter(
GROUP_LINK_BASE_PROPERTY_NAME,
GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
);
...@@ -3,10 +3,11 @@ import memberExpirationDate from '~/member_expiration_date'; ...@@ -3,10 +3,11 @@ import memberExpirationDate from '~/member_expiration_date';
import UsersSelect from '~/users_select'; import UsersSelect from '~/users_select';
import groupsSelect from '~/groups_select'; import groupsSelect from '~/groups_select';
import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue'; import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
import { initGroupMembersApp } from '~/groups/members';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal'; import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger'; import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { memberRequestFormatter, groupLinkRequestFormatter } from '~/groups/members/utils'; import { initMembersApp } from '~/members/index';
import { groupMemberRequestFormatter } from '~/groups/members/utils';
import { groupLinkRequestFormatter } from '~/members/utils';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
function mountRemoveMemberModal() { function mountRemoveMemberModal() {
...@@ -25,11 +26,11 @@ function mountRemoveMemberModal() { ...@@ -25,11 +26,11 @@ function mountRemoveMemberModal() {
const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions']; const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions'];
initGroupMembersApp(document.querySelector('.js-group-members-list'), { initMembersApp(document.querySelector('.js-group-members-list'), {
tableFields: SHARED_FIELDS.concat(['source', 'granted']), tableFields: SHARED_FIELDS.concat(['source', 'granted']),
tableAttrs: { tr: { 'data-qa-selector': 'member_row' } }, tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'], tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'],
requestFormatter: memberRequestFormatter, requestFormatter: groupMemberRequestFormatter,
filteredSearchBar: { filteredSearchBar: {
show: true, show: true,
tokens: ['two_factor', 'with_inherited_permissions'], tokens: ['two_factor', 'with_inherited_permissions'],
...@@ -38,7 +39,8 @@ initGroupMembersApp(document.querySelector('.js-group-members-list'), { ...@@ -38,7 +39,8 @@ initGroupMembersApp(document.querySelector('.js-group-members-list'), {
recentSearchesStorageKey: 'group_members', recentSearchesStorageKey: 'group_members',
}, },
}); });
initGroupMembersApp(document.querySelector('.js-group-linked-list'), {
initMembersApp(document.querySelector('.js-group-group-links-list'), {
tableFields: SHARED_FIELDS.concat('granted'), tableFields: SHARED_FIELDS.concat('granted'),
tableAttrs: { tableAttrs: {
table: { 'data-qa-selector': 'groups_list' }, table: { 'data-qa-selector': 'groups_list' },
...@@ -46,9 +48,9 @@ initGroupMembersApp(document.querySelector('.js-group-linked-list'), { ...@@ -46,9 +48,9 @@ initGroupMembersApp(document.querySelector('.js-group-linked-list'), {
}, },
requestFormatter: groupLinkRequestFormatter, requestFormatter: groupLinkRequestFormatter,
}); });
initGroupMembersApp(document.querySelector('.js-group-invited-members-list'), { initMembersApp(document.querySelector('.js-group-invited-members-list'), {
tableFields: SHARED_FIELDS.concat('invited'), tableFields: SHARED_FIELDS.concat('invited'),
requestFormatter: memberRequestFormatter, requestFormatter: groupMemberRequestFormatter,
filteredSearchBar: { filteredSearchBar: {
show: true, show: true,
tokens: [], tokens: [],
...@@ -57,9 +59,9 @@ initGroupMembersApp(document.querySelector('.js-group-invited-members-list'), { ...@@ -57,9 +59,9 @@ initGroupMembersApp(document.querySelector('.js-group-invited-members-list'), {
recentSearchesStorageKey: 'group_invited_members', recentSearchesStorageKey: 'group_invited_members',
}, },
}); });
initGroupMembersApp(document.querySelector('.js-group-access-requests-list'), { initMembersApp(document.querySelector('.js-group-access-requests-list'), {
tableFields: SHARED_FIELDS.concat('requested'), tableFields: SHARED_FIELDS.concat('requested'),
requestFormatter: memberRequestFormatter, requestFormatter: groupMemberRequestFormatter,
}); });
groupsSelect(); groupsSelect();
......
...@@ -13,7 +13,7 @@ module Groups::GroupMembersHelper ...@@ -13,7 +13,7 @@ module Groups::GroupMembersHelper
render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level
end end
def linked_groups_data_json(group_links) def group_group_links_data_json(group_links)
GroupGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json GroupGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json
end end
...@@ -26,16 +26,16 @@ module Groups::GroupMembersHelper ...@@ -26,16 +26,16 @@ module Groups::GroupMembersHelper
{ {
members: members_data_json(group, members), members: members_data_json(group, members),
member_path: group_group_member_path(group, ':id'), member_path: group_group_member_path(group, ':id'),
group_id: group.id, source_id: group.id,
can_manage_members: can?(current_user, :admin_group_member, group).to_s can_manage_members: can?(current_user, :admin_group_member, group).to_s
} }
end end
def linked_groups_list_data_attributes(group) def group_group_links_list_data_attributes(group)
{ {
members: linked_groups_data_json(group.shared_with_group_links), members: group_group_links_data_json(group.shared_with_group_links),
member_path: group_group_link_path(group, ':id'), member_path: group_group_link_path(group, ':id'),
group_id: group.id source_id: group.id
} }
end end
end end
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
= paginate @members, theme: 'gitlab', params: { invited_members_page: nil, search_invited: nil } = paginate @members, theme: 'gitlab', params: { invited_members_page: nil, search_invited: nil }
- if @group.shared_with_group_links.any? - if @group.shared_with_group_links.any?
#tab-groups.tab-pane #tab-groups.tab-pane
.js-group-linked-list{ data: linked_groups_list_data_attributes(@group) } .js-group-group-links-list{ data: group_group_links_list_data_attributes(@group) }
.loading .loading
.spinner.spinner-md .spinner.spinner-md
- if show_invited_members - if show_invited_members
......
import { parseDataAttributes as CEParseDataAttributes } from '~/groups/members/utils';
export const parseDataAttributes = (el) => {
const { ldapOverridePath } = el.dataset;
return {
...CEParseDataAttributes(el),
ldapOverridePath,
};
};
import { __ } from '~/locale'; import { __ } from '~/locale';
import { generateBadges as CEGenerateBadges } from '~/members/utils'; import {
generateBadges as CEGenerateBadges,
parseDataAttributes as CEParseDataAttributes,
} from '~/members/utils';
export { export {
isGroup, isGroup,
...@@ -35,3 +38,12 @@ export const generateBadges = (member, isCurrentUser) => [ ...@@ -35,3 +38,12 @@ export const generateBadges = (member, isCurrentUser) => [
]; ];
export const canOverride = (member) => member.canOverride; export const canOverride = (member) => member.canOverride;
export const parseDataAttributes = (el) => {
const { ldapOverridePath } = el.dataset;
return {
...CEParseDataAttributes(el),
ldapOverridePath,
};
};
import { parseDataAttributes } from 'ee/groups/members/utils';
import { membersJsonString, membersParsed } from 'jest/groups/members/mock_data';
describe('group member utils', () => {
describe('parseDataAttributes', () => {
let el;
beforeEach(() => {
el = document.createElement('div');
el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-group-id', '234');
el.setAttribute('data-can-manage-members', 'true');
el.setAttribute('data-ldap-override-path', '/groups/ldap-group/-/group_members/:id/override');
});
afterEach(() => {
el = null;
});
it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({
members: membersParsed,
sourceId: 234,
canManageMembers: true,
ldapOverridePath: '/groups/ldap-group/-/group_members/:id/override',
});
});
});
});
import { membersJsonString } from 'jest/groups/members/mock_data'; import { membersJsonString } from 'jest/members/mock_data';
import { initGroupMembersApp } from '~/groups/members'; import { initMembersApp } from '~/members/index';
describe('initGroupMembersApp', () => { describe('initMembersApp', () => {
let el; let el;
let vm; let vm;
const createVm = () => { const createVm = () => {
vm = initGroupMembersApp(el, {}); vm = initMembersApp(el, {});
}; };
beforeEach(() => { beforeEach(() => {
el = document.createElement('div'); el = document.createElement('div');
el.setAttribute('data-members', membersJsonString); el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-group-id', '234'); el.setAttribute('data-source-id', '234');
el.setAttribute('data-member-path', '/groups/foo-bar/-/group_members/:id'); el.setAttribute('data-member-path', '/groups/foo-bar/-/group_members/:id');
el.setAttribute('data-ldap-override-path', '/groups/ldap-group/-/group_members/:id/override'); el.setAttribute('data-ldap-override-path', '/groups/ldap-group/-/group_members/:id/override');
}); });
......
import { member as memberMock } from 'jest/members/mock_data'; import { member as memberMock, membersJsonString, members } from 'jest/members/mock_data';
import { generateBadges, canOverride } from 'ee/members/utils'; import { generateBadges, canOverride, parseDataAttributes } from 'ee/members/utils';
describe('Members Utils', () => { describe('Members Utils', () => {
describe('generateBadges', () => { describe('generateBadges', () => {
...@@ -37,4 +37,34 @@ describe('Members Utils', () => { ...@@ -37,4 +37,34 @@ describe('Members Utils', () => {
expect(canOverride(member)).toBe(expected); expect(canOverride(member)).toBe(expected);
}); });
}); });
describe('group member utils', () => {
describe('parseDataAttributes', () => {
let el;
beforeEach(() => {
el = document.createElement('div');
el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-source-id', '234');
el.setAttribute('data-can-manage-members', 'true');
el.setAttribute(
'data-ldap-override-path',
'/groups/ldap-group/-/group_members/:id/override',
);
});
afterEach(() => {
el = null;
});
it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({
members,
sourceId: 234,
canManageMembers: true,
ldapOverridePath: '/groups/ldap-group/-/group_members/:id/override',
});
});
});
});
}); });
export const membersJsonString =
'[{"requested_at":null,"can_update":true,"can_remove":true,"can_override":false,"access_level":{"integer_value":50,"string_value":"Owner"},"source":{"id":323,"name":"My group / my subgroup","web_url":"http://127.0.0.1:3000/groups/my-group/my-subgroup"},"user":{"id":1,"name":"Administrator","username":"root","web_url":"http://127.0.0.1:3000/root","avatar_url":"https://www.gravatar.com/avatar/4816142ef496f956a277bedf1a40607b?s=80\u0026d=identicon","blocked":false,"two_factor_enabled":false},"id":524,"created_at":"2020-08-21T21:33:27.631Z","expires_at":null,"using_license":false,"group_sso":false,"group_managed_account":false}]';
export const membersParsed = [
{
requestedAt: null,
canUpdate: true,
canRemove: true,
canOverride: false,
accessLevel: { integerValue: 50, stringValue: 'Owner' },
source: {
id: 323,
name: 'My group / my subgroup',
webUrl: 'http://127.0.0.1:3000/groups/my-group/my-subgroup',
},
user: {
id: 1,
name: 'Administrator',
username: 'root',
webUrl: 'http://127.0.0.1:3000/root',
avatarUrl:
'https://www.gravatar.com/avatar/4816142ef496f956a277bedf1a40607b?s=80&d=identicon',
blocked: false,
twoFactorEnabled: false,
},
id: 524,
createdAt: '2020-08-21T21:33:27.631Z',
expiresAt: null,
usingLicense: false,
groupSso: false,
groupManagedAccount: false,
},
];
import { membersJsonString, membersParsed } from './mock_data'; import { groupMemberRequestFormatter } from '~/groups/members/utils';
import {
parseDataAttributes,
memberRequestFormatter,
groupLinkRequestFormatter,
} from '~/groups/members/utils';
describe('group member utils', () => { describe('group member utils', () => {
describe('parseDataAttributes', () => { describe('groupMemberRequestFormatter', () => {
let el;
beforeEach(() => {
el = document.createElement('div');
el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-group-id', '234');
el.setAttribute('data-can-manage-members', 'true');
});
afterEach(() => {
el = null;
});
it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({
members: membersParsed,
sourceId: 234,
canManageMembers: true,
});
});
});
describe('memberRequestFormatter', () => {
it('returns expected format', () => { it('returns expected format', () => {
expect( expect(
memberRequestFormatter({ groupMemberRequestFormatter({
accessLevel: 50, accessLevel: 50,
expires_at: '2020-10-16', expires_at: '2020-10-16',
}), }),
).toEqual({ group_member: { access_level: 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' } });
});
});
}); });
...@@ -2,13 +2,13 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; ...@@ -2,13 +2,13 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { GlAlert } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import App from '~/groups/members/components/app.vue'; import MembersApp from '~/members/components/app.vue';
import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue'; import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue';
import * as commonUtils from '~/lib/utils/common_utils'; import * as commonUtils from '~/lib/utils/common_utils';
import { RECEIVE_MEMBER_ROLE_ERROR, HIDE_ERROR } from '~/members/store/mutation_types'; import { RECEIVE_MEMBER_ROLE_ERROR, HIDE_ERROR } from '~/members/store/mutation_types';
import mutations from '~/members/store/mutations'; import mutations from '~/members/store/mutations';
describe('GroupMembersApp', () => { describe('MembersApp', () => {
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -25,7 +25,7 @@ describe('GroupMembersApp', () => { ...@@ -25,7 +25,7 @@ describe('GroupMembersApp', () => {
mutations, mutations,
}); });
wrapper = shallowMount(App, { wrapper = shallowMount(MembersApp, {
localVue, localVue,
store, store,
...options, ...options,
......
import { createWrapper } from '@vue/test-utils'; import { createWrapper } from '@vue/test-utils';
import { initGroupMembersApp } from '~/groups/members'; import { initMembersApp } from '~/members/index';
import GroupMembersApp from '~/groups/members/components/app.vue'; import MembersApp from '~/members/components/app.vue';
import { membersJsonString, membersParsed } from './mock_data'; import { membersJsonString, members } from './mock_data';
describe('initGroupMembersApp', () => { describe('initMembersApp', () => {
let el; let el;
let vm; let vm;
let wrapper; let wrapper;
const setup = () => { const setup = () => {
vm = initGroupMembersApp(el, { vm = initMembersApp(el, {
tableFields: ['account'], tableFields: ['account'],
tableAttrs: { table: { 'data-qa-selector': 'members_list' } }, tableAttrs: { table: { 'data-qa-selector': 'members_list' } },
tableSortableFields: ['account'], tableSortableFields: ['account'],
...@@ -22,7 +22,7 @@ describe('initGroupMembersApp', () => { ...@@ -22,7 +22,7 @@ describe('initGroupMembersApp', () => {
beforeEach(() => { beforeEach(() => {
el = document.createElement('div'); el = document.createElement('div');
el.setAttribute('data-members', membersJsonString); el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-group-id', '234'); el.setAttribute('data-source-id', '234');
el.setAttribute('data-can-manage-members', 'true'); el.setAttribute('data-can-manage-members', 'true');
el.setAttribute('data-member-path', '/groups/foo-bar/-/group_members/:id'); el.setAttribute('data-member-path', '/groups/foo-bar/-/group_members/:id');
...@@ -36,10 +36,10 @@ describe('initGroupMembersApp', () => { ...@@ -36,10 +36,10 @@ describe('initGroupMembersApp', () => {
wrapper = null; wrapper = null;
}); });
it('renders `GroupMembersApp`', () => { it('renders `MembersApp`', () => {
setup(); setup();
expect(wrapper.find(GroupMembersApp).exists()).toBe(true); expect(wrapper.find(MembersApp).exists()).toBe(true);
}); });
it('sets `currentUserId` in Vuex store', () => { it('sets `currentUserId` in Vuex store', () => {
...@@ -57,7 +57,7 @@ describe('initGroupMembersApp', () => { ...@@ -57,7 +57,7 @@ describe('initGroupMembersApp', () => {
}); });
}); });
it('parses and sets `data-group-id` as `sourceId` in Vuex store', () => { it('parses and sets `data-source-id` as `sourceId` in Vuex store', () => {
setup(); setup();
expect(vm.$store.state.sourceId).toBe(234); expect(vm.$store.state.sourceId).toBe(234);
...@@ -72,7 +72,7 @@ describe('initGroupMembersApp', () => { ...@@ -72,7 +72,7 @@ describe('initGroupMembersApp', () => {
it('parses and sets `members` in Vuex store', () => { it('parses and sets `members` in Vuex store', () => {
setup(); setup();
expect(vm.$store.state.members).toEqual(membersParsed); expect(vm.$store.state.members).toEqual(members);
}); });
it('sets `tableFields` in Vuex store', () => { it('sets `tableFields` in Vuex store', () => {
......
...@@ -69,3 +69,5 @@ export const accessRequest = { ...@@ -69,3 +69,5 @@ export const accessRequest = {
}; };
export const members = [member]; export const members = [member];
export const membersJsonString = JSON.stringify(members);
...@@ -9,9 +9,11 @@ import { ...@@ -9,9 +9,11 @@ import {
canOverride, canOverride,
parseSortParam, parseSortParam,
buildSortHref, buildSortHref,
parseDataAttributes,
groupLinkRequestFormatter,
} from '~/members/utils'; } from '~/members/utils';
import { DEFAULT_SORT } from '~/members/constants'; import { DEFAULT_SORT } from '~/members/constants';
import { member as memberMock, group, invite } from './mock_data'; import { member as memberMock, group, invite, membersJsonString, members } from './mock_data';
const DIRECT_MEMBER_ID = 178; const DIRECT_MEMBER_ID = 178;
const INHERITED_MEMBER_ID = 179; const INHERITED_MEMBER_ID = 179;
...@@ -229,4 +231,38 @@ describe('Members Utils', () => { ...@@ -229,4 +231,38 @@ describe('Members Utils', () => {
}); });
}); });
}); });
describe('parseDataAttributes', () => {
let el;
beforeEach(() => {
el = document.createElement('div');
el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-source-id', '234');
el.setAttribute('data-can-manage-members', 'true');
});
afterEach(() => {
el = null;
});
it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({
members,
sourceId: 234,
canManageMembers: true,
});
});
});
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' } });
});
});
}); });
...@@ -23,11 +23,11 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -23,11 +23,11 @@ RSpec.describe Groups::GroupMembersHelper do
end end
end end
describe '#linked_groups_data_json' do describe '#group_group_links_data_json' do
include_context 'group_group_link' include_context 'group_group_link'
it 'matches json schema' do it 'matches json schema' do
json = helper.linked_groups_data_json(shared_group.shared_with_group_links) json = helper.group_group_links_data_json(shared_group.shared_with_group_links)
expect(json).to match_schema('group_group_links') expect(json).to match_schema('group_group_links')
end end
...@@ -81,13 +81,13 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -81,13 +81,13 @@ RSpec.describe Groups::GroupMembersHelper do
expect(helper.group_members_list_data_attributes(group, present_members([group_member]))).to include({ expect(helper.group_members_list_data_attributes(group, present_members([group_member]))).to include({
members: helper.members_data_json(group, present_members([group_member])), members: helper.members_data_json(group, present_members([group_member])),
member_path: '/groups/foo-bar/-/group_members/:id', member_path: '/groups/foo-bar/-/group_members/:id',
group_id: group.id, source_id: group.id,
can_manage_members: 'true' can_manage_members: 'true'
}) })
end end
end end
describe '#linked_groups_list_data_attributes' do describe '#group_group_links_list_data_attributes' do
include_context 'group_group_link' include_context 'group_group_link'
before do before do
...@@ -95,10 +95,10 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -95,10 +95,10 @@ RSpec.describe Groups::GroupMembersHelper do
end end
it 'returns expected hash' do it 'returns expected hash' do
expect(helper.linked_groups_list_data_attributes(shared_group)).to include({ expect(helper.group_group_links_list_data_attributes(shared_group)).to include({
members: helper.linked_groups_data_json(shared_group.shared_with_group_links), members: helper.group_group_links_data_json(shared_group.shared_with_group_links),
member_path: '/groups/foo-bar/-/group_links/:id', member_path: '/groups/foo-bar/-/group_links/:id',
group_id: shared_group.id source_id: shared_group.id
}) })
end end
end end
......
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