Commit d3edd8d9 authored by Peter Hegman's avatar Peter Hegman Committed by Vitaly Slobodin

Refactor members pagination from HAML to Vue

parent 0a63b4ac
<script> <script>
import { GlTable, GlBadge } from '@gitlab/ui'; import { GlTable, GlBadge, GlPagination } from '@gitlab/ui';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import MembersTableCell from 'ee_else_ce/members/components/table/members_table_cell.vue'; import MembersTableCell from 'ee_else_ce/members/components/table/members_table_cell.vue';
import { canOverride, canRemove, canResend, canUpdate } from 'ee_else_ce/members/utils'; import { canOverride, canRemove, canResend, canUpdate } from 'ee_else_ce/members/utils';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import initUserPopovers from '~/user_popovers'; import initUserPopovers from '~/user_popovers';
import { FIELDS } from '../../constants'; import { FIELDS } from '../../constants';
import RemoveGroupLinkModal from '../modals/remove_group_link_modal.vue'; import RemoveGroupLinkModal from '../modals/remove_group_link_modal.vue';
...@@ -19,6 +20,7 @@ export default { ...@@ -19,6 +20,7 @@ export default {
components: { components: {
GlTable, GlTable,
GlBadge, GlBadge,
GlPagination,
MemberAvatar, MemberAvatar,
CreatedAt, CreatedAt,
ExpiresAt, ExpiresAt,
...@@ -43,6 +45,9 @@ export default { ...@@ -43,6 +45,9 @@ export default {
tableAttrs(state) { tableAttrs(state) {
return state[this.namespace].tableAttrs; return state[this.namespace].tableAttrs;
}, },
pagination(state) {
return state[this.namespace].pagination;
},
}), }),
filteredFields() { filteredFields() {
return FIELDS.filter( return FIELDS.filter(
...@@ -59,6 +64,11 @@ export default { ...@@ -59,6 +64,11 @@ export default {
userIsLoggedIn() { userIsLoggedIn() {
return this.currentUserId !== null; return this.currentUserId !== null;
}, },
showPagination() {
const { paramName, currentPage, perPage, totalItems } = this.pagination;
return paramName && currentPage && perPage && totalItems;
},
}, },
mounted() { mounted() {
initUserPopovers(this.$el.querySelectorAll('.js-user-link')); initUserPopovers(this.$el.querySelectorAll('.js-user-link'));
...@@ -99,6 +109,11 @@ export default { ...@@ -99,6 +109,11 @@ export default {
...(member?.id && { 'data-testid': `members-table-row-${member.id}` }), ...(member?.id && { 'data-testid': `members-table-row-${member.id}` }),
}; };
}, },
paginationLinkGenerator(page) {
const { params = {}, paramName } = this.pagination;
return mergeUrlParams({ ...params, [paramName]: page }, window.location.href);
},
}, },
}; };
</script> </script>
...@@ -179,6 +194,18 @@ export default { ...@@ -179,6 +194,18 @@ export default {
<span data-testid="col-actions" class="gl-sr-only">{{ label }}</span> <span data-testid="col-actions" class="gl-sr-only">{{ label }}</span>
</template> </template>
</gl-table> </gl-table>
<gl-pagination
v-if="showPagination"
:value="pagination.currentPage"
:per-page="pagination.perPage"
:total-items="pagination.totalItems"
:link-gen="paginationLinkGenerator"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
/>
<remove-group-link-modal /> <remove-group-link-modal />
<ldap-override-confirmation-modal /> <ldap-override-confirmation-modal />
</div> </div>
......
export default ({ export default ({
members, members,
pagination,
tableFields, tableFields,
tableAttrs, tableAttrs,
tableSortableFields, tableSortableFields,
...@@ -8,6 +9,7 @@ export default ({ ...@@ -8,6 +9,7 @@ export default ({
filteredSearchBar, filteredSearchBar,
}) => ({ }) => ({
members, members,
pagination,
tableFields, tableFields,
tableAttrs, tableAttrs,
tableSortableFields, tableSortableFields,
......
...@@ -105,10 +105,14 @@ export const buildSortHref = ({ ...@@ -105,10 +105,14 @@ export const buildSortHref = ({
export const canOverride = () => false; export const canOverride = () => false;
export const parseDataAttributes = (el) => { export const parseDataAttributes = (el) => {
const { members, sourceId, memberPath, canManageMembers } = el.dataset; const { members, pagination, sourceId, memberPath, canManageMembers } = el.dataset;
return { return {
members: convertObjectPropsToCamelCase(JSON.parse(members), { deep: true }), members: convertObjectPropsToCamelCase(JSON.parse(members), { deep: true }),
pagination: convertObjectPropsToCamelCase(JSON.parse(pagination || '{}'), {
deep: true,
ignoreKeyNames: ['params'],
}),
sourceId: parseInt(sourceId, 10), sourceId: parseInt(sourceId, 10),
memberPath, memberPath,
canManageMembers: parseBoolean(canManageMembers), canManageMembers: parseBoolean(canManageMembers),
......
...@@ -22,9 +22,10 @@ module Groups::GroupMembersHelper ...@@ -22,9 +22,10 @@ module Groups::GroupMembersHelper
end end
# Overridden in `ee/app/helpers/ee/groups/group_members_helper.rb` # Overridden in `ee/app/helpers/ee/groups/group_members_helper.rb`
def group_members_list_data_attributes(group, members) def group_members_list_data_attributes(group, members, pagination = {})
{ {
members: members_data_json(group, members), members: members_data_json(group, members),
pagination: members_pagination_data_json(members, pagination),
member_path: group_group_member_path(group, ':id'), member_path: group_group_member_path(group, ':id'),
source_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
...@@ -32,8 +33,11 @@ module Groups::GroupMembersHelper ...@@ -32,8 +33,11 @@ module Groups::GroupMembersHelper
end end
def group_group_links_list_data_attributes(group) def group_group_links_list_data_attributes(group)
group_links = group.shared_with_group_links
{ {
members: group_group_links_data_json(group.shared_with_group_links), members: group_group_links_data_json(group_links),
pagination: members_pagination_data_json(group_links),
member_path: group_group_link_path(group, ':id'), member_path: group_group_link_path(group, ':id'),
source_id: group.id source_id: group.id
} }
......
...@@ -65,4 +65,14 @@ module MembersHelper ...@@ -65,4 +65,14 @@ module MembersHelper
'group and any subresources' 'group and any subresources'
end end
def members_pagination_data_json(members, pagination = {})
{
current_page: members.respond_to?(:current_page) ? members.current_page : nil,
per_page: members.respond_to?(:limit_value) ? members.limit_value : nil,
total_items: members.respond_to?(:total_count) ? members.total_count : members.count,
param_name: pagination[:param_name] || nil,
params: pagination[:params] || {}
}.to_json
end
end end
...@@ -35,9 +35,10 @@ module Projects::ProjectMembersHelper ...@@ -35,9 +35,10 @@ module Projects::ProjectMembersHelper
MemberSerializer.new.represent(members, { current_user: current_user, group: project.group, source: project }).to_json MemberSerializer.new.represent(members, { current_user: current_user, group: project.group, source: project }).to_json
end end
def project_members_list_data_attributes(project, members) def project_members_list_data_attributes(project, members, pagination = {})
{ {
members: project_members_data_json(project, members), members: project_members_data_json(project, members),
pagination: members_pagination_data_json(members, pagination),
member_path: project_project_member_path(project, ':id'), member_path: project_project_member_path(project, ':id'),
source_id: project.id, source_id: project.id,
can_manage_members: can_manage_project_members?(project).to_s can_manage_members: can_manage_project_members?(project).to_s
...@@ -47,6 +48,7 @@ module Projects::ProjectMembersHelper ...@@ -47,6 +48,7 @@ module Projects::ProjectMembersHelper
def project_group_links_list_data_attributes(project, group_links) def project_group_links_list_data_attributes(project, group_links)
{ {
members: project_group_links_data_json(group_links), members: project_group_links_data_json(group_links),
pagination: members_pagination_data_json(group_links),
member_path: project_group_link_path(project, ':id'), member_path: project_group_link_path(project, ':id'),
source_id: project.id, source_id: project.id,
can_manage_members: can_manage_project_members?(project).to_s can_manage_members: can_manage_project_members?(project).to_s
......
...@@ -62,10 +62,9 @@ ...@@ -62,10 +62,9 @@
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count
.tab-content .tab-content
#tab-members.tab-pane{ class: ('active' unless invited_active) } #tab-members.tab-pane{ class: ('active' unless invited_active) }
.js-group-members-list{ data: group_members_list_data_attributes(@group, @members) } .js-group-members-list{ data: group_members_list_data_attributes(@group, @members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }) }
.loading .loading
.spinner.spinner-md .spinner.spinner-md
= 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-group-links-list{ data: group_group_links_list_data_attributes(@group) } .js-group-group-links-list{ data: group_group_links_list_data_attributes(@group) }
...@@ -73,10 +72,9 @@ ...@@ -73,10 +72,9 @@
.spinner.spinner-md .spinner.spinner-md
- if show_invited_members - if show_invited_members
#tab-invited-members.tab-pane{ class: ('active' if invited_active) } #tab-invited-members.tab-pane{ class: ('active' if invited_active) }
.js-group-invited-members-list{ data: group_members_list_data_attributes(@group, @invited_members) } .js-group-invited-members-list{ data: group_members_list_data_attributes(@group, @invited_members, { param_name: :invited_members_page, params: { page: nil } }) }
.loading .loading
.spinner.spinner-md .spinner.spinner-md
= paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab', params: { page: nil }
- if show_access_requests - if show_access_requests
#tab-access-requests.tab-pane #tab-access-requests.tab-pane
.js-group-access-requests-list{ data: group_members_list_data_attributes(@group, @requesters) } .js-group-access-requests-list{ data: group_members_list_data_attributes(@group, @requesters) }
......
...@@ -75,10 +75,9 @@ ...@@ -75,10 +75,9 @@
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @requesters.count
.tab-content .tab-content
#tab-members.tab-pane{ class: ('active' unless groups_tab_active?) } #tab-members.tab-pane{ class: ('active' unless groups_tab_active?) }
.js-project-members-list{ data: project_members_list_data_attributes(@project, @project_members) } .js-project-members-list{ data: project_members_list_data_attributes(@project, @project_members, { param_name: :page, params: { search_groups: nil } }) }
.loading .loading
.spinner.spinner-md .spinner.spinner-md
= paginate @project_members, theme: "gitlab", params: { search_groups: nil }
- if show_groups?(@group_links) - if show_groups?(@group_links)
#tab-groups.tab-pane{ class: ('active' if groups_tab_active?) } #tab-groups.tab-pane{ class: ('active' if groups_tab_active?) }
.js-project-group-links-list{ data: project_group_links_list_data_attributes(@project, @group_links) } .js-project-group-links-list{ data: project_group_links_list_data_attributes(@project, @group_links) }
......
...@@ -9,7 +9,7 @@ module EE::Groups::GroupMembersHelper ...@@ -9,7 +9,7 @@ module EE::Groups::GroupMembersHelper
end end
override :group_members_list_data_attributes override :group_members_list_data_attributes
def group_members_list_data_attributes(group, _members) def group_members_list_data_attributes(group, _members, _pagination = {})
super.merge!({ super.merge!({
ldap_override_path: override_group_group_member_path(group, ':id') ldap_override_path: override_group_group_member_path(group, ':id')
}) })
......
...@@ -23,6 +23,7 @@ describe('MemberList', () => { ...@@ -23,6 +23,7 @@ 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' },
}, },
pagination: {},
...state, ...state,
}, },
}, },
......
...@@ -5,6 +5,8 @@ import { ...@@ -5,6 +5,8 @@ import {
inheritedMember, inheritedMember,
membersJsonString, membersJsonString,
members, members,
paginationJsonString,
pagination,
} from 'jest/members/mock_data'; } from 'jest/members/mock_data';
describe('Members Utils', () => { describe('Members Utils', () => {
...@@ -59,6 +61,7 @@ describe('Members Utils', () => { ...@@ -59,6 +61,7 @@ describe('Members Utils', () => {
beforeEach(() => { beforeEach(() => {
el = document.createElement('div'); el = document.createElement('div');
el.setAttribute('data-members', membersJsonString); el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-pagination', paginationJsonString);
el.setAttribute('data-source-id', '234'); el.setAttribute('data-source-id', '234');
el.setAttribute('data-can-manage-members', 'true'); el.setAttribute('data-can-manage-members', 'true');
el.setAttribute( el.setAttribute(
...@@ -74,6 +77,7 @@ describe('Members Utils', () => { ...@@ -74,6 +77,7 @@ describe('Members Utils', () => {
it('correctly parses the data attributes', () => { it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({ expect(parseDataAttributes(el)).toEqual({
members, members,
pagination,
sourceId: 234, sourceId: 234,
canManageMembers: true, canManageMembers: true,
ldapOverridePath: '/groups/ldap-group/-/group_members/:id/override', ldapOverridePath: '/groups/ldap-group/-/group_members/:id/override',
......
...@@ -15028,9 +15028,15 @@ msgstr "" ...@@ -15028,9 +15028,15 @@ msgstr ""
msgid "Go to metrics" msgid "Go to metrics"
msgstr "" msgstr ""
msgid "Go to next page"
msgstr ""
msgid "Go to parent" msgid "Go to parent"
msgstr "" msgstr ""
msgid "Go to previous page"
msgstr ""
msgid "Go to project" msgid "Go to project"
msgstr "" msgstr ""
......
import { GlBadge, GlTable } from '@gitlab/ui'; import { GlBadge, GlPagination, GlTable } from '@gitlab/ui';
import { import {
getByText as getByTextHelper, getByText as getByTextHelper,
getByTestId as getByTestIdHelper, getByTestId as getByTestIdHelper,
...@@ -6,6 +6,7 @@ import { ...@@ -6,6 +6,7 @@ import {
} from '@testing-library/dom'; } from '@testing-library/dom';
import { mount, createLocalVue, createWrapper } from '@vue/test-utils'; import { mount, createLocalVue, createWrapper } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import CreatedAt from '~/members/components/table/created_at.vue'; import CreatedAt from '~/members/components/table/created_at.vue';
import ExpirationDatepicker from '~/members/components/table/expiration_datepicker.vue'; import ExpirationDatepicker from '~/members/components/table/expiration_datepicker.vue';
import ExpiresAt from '~/members/components/table/expires_at.vue'; import ExpiresAt from '~/members/components/table/expires_at.vue';
...@@ -16,7 +17,13 @@ import MembersTable from '~/members/components/table/members_table.vue'; ...@@ -16,7 +17,13 @@ import MembersTable from '~/members/components/table/members_table.vue';
import RoleDropdown from '~/members/components/table/role_dropdown.vue'; import RoleDropdown from '~/members/components/table/role_dropdown.vue';
import { MEMBER_TYPES } from '~/members/constants'; import { MEMBER_TYPES } from '~/members/constants';
import * as initUserPopovers from '~/user_popovers'; import * as initUserPopovers from '~/user_popovers';
import { member as memberMock, directMember, invite, accessRequest } from '../../mock_data'; import {
member as memberMock,
directMember,
invite,
accessRequest,
pagination,
} from '../../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -36,6 +43,7 @@ describe('MembersTable', () => { ...@@ -36,6 +43,7 @@ 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' },
}, },
pagination,
...state, ...state,
}, },
}, },
...@@ -66,6 +74,8 @@ describe('MembersTable', () => { ...@@ -66,6 +74,8 @@ describe('MembersTable', () => {
}); });
}; };
const url = 'https://localhost/foo-bar/-/project_members';
const getByText = (text, options) => const getByText = (text, options) =>
createWrapper(getByTextHelper(wrapper.element, text, options)); createWrapper(getByTextHelper(wrapper.element, text, options));
...@@ -78,6 +88,14 @@ describe('MembersTable', () => { ...@@ -78,6 +88,14 @@ describe('MembersTable', () => {
`[data-label="${tableCellLabel}"][role="cell"]`, `[data-label="${tableCellLabel}"][role="cell"]`,
); );
const findPagination = () => extendedWrapper(wrapper.find(GlPagination));
const expectCorrectLinkToPage2 = () => {
expect(findPagination().findByText('2', { selector: 'a' }).attributes('href')).toBe(
`${url}?page=2`,
);
};
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
...@@ -219,4 +237,80 @@ describe('MembersTable', () => { ...@@ -219,4 +237,80 @@ describe('MembersTable', () => {
expect(findTable().find('tbody tr').attributes('data-qa-selector')).toBe('member_row'); expect(findTable().find('tbody tr').attributes('data-qa-selector')).toBe('member_row');
}); });
describe('when required pagination data is provided', () => {
beforeEach(() => {
delete window.location;
});
it('renders `gl-pagination` component with correct props', () => {
window.location = new URL(url);
createComponent();
const glPagination = findPagination();
expect(glPagination.exists()).toBe(true);
expect(glPagination.props()).toMatchObject({
value: pagination.currentPage,
perPage: pagination.perPage,
totalItems: pagination.totalItems,
prevText: 'Prev',
nextText: 'Next',
labelNextPage: 'Go to next page',
labelPrevPage: 'Go to previous page',
align: 'center',
});
});
it('uses `pagination.paramName` to generate the pagination links', () => {
window.location = new URL(url);
createComponent({
pagination: {
currentPage: 1,
perPage: 5,
totalItems: 10,
paramName: 'page',
},
});
expectCorrectLinkToPage2();
});
it('removes any url params defined as `null` in the `params` attribute', () => {
window.location = new URL(`${url}?search_groups=foo`);
createComponent({
pagination: {
currentPage: 1,
perPage: 5,
totalItems: 10,
paramName: 'page',
params: { search_groups: null },
},
});
expectCorrectLinkToPage2();
});
});
describe.each`
attribute | value
${'paramName'} | ${null}
${'currentPage'} | ${null}
${'perPage'} | ${null}
${'totalItems'} | ${0}
`('when pagination.$attribute is $value', ({ attribute, value }) => {
it('does not render `gl-pagination`', () => {
createComponent({
pagination: {
...pagination,
[attribute]: value,
},
});
expect(findPagination().exists()).toBe(false);
});
});
}); });
...@@ -2,7 +2,7 @@ import { createWrapper } from '@vue/test-utils'; ...@@ -2,7 +2,7 @@ import { createWrapper } from '@vue/test-utils';
import MembersApp from '~/members/components/app.vue'; import MembersApp from '~/members/components/app.vue';
import { MEMBER_TYPES } from '~/members/constants'; import { MEMBER_TYPES } from '~/members/constants';
import { initMembersApp } from '~/members/index'; import { initMembersApp } from '~/members/index';
import { membersJsonString, members } from './mock_data'; import { membersJsonString, members, paginationJsonString, pagination } from './mock_data';
describe('initMembersApp', () => { describe('initMembersApp', () => {
let el; let el;
...@@ -24,6 +24,7 @@ describe('initMembersApp', () => { ...@@ -24,6 +24,7 @@ describe('initMembersApp', () => {
beforeEach(() => { beforeEach(() => {
el = document.createElement('div'); el = document.createElement('div');
el.setAttribute('data-members', membersJsonString); el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-pagination', paginationJsonString);
el.setAttribute('data-source-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');
...@@ -50,6 +51,12 @@ describe('initMembersApp', () => { ...@@ -50,6 +51,12 @@ describe('initMembersApp', () => {
expect(vm.$store.state[MEMBER_TYPES.user].members).toEqual(members); expect(vm.$store.state[MEMBER_TYPES.user].members).toEqual(members);
}); });
it('parses and sets `pagination` in Vuex store', () => {
setup();
expect(vm.$store.state[MEMBER_TYPES.user].pagination).toEqual(pagination);
});
it('sets `tableFields` in Vuex store', () => { it('sets `tableFields` in Vuex store', () => {
setup(); setup();
......
...@@ -79,3 +79,19 @@ export const directMember = { ...member, isDirectMember: true }; ...@@ -79,3 +79,19 @@ export const directMember = { ...member, isDirectMember: true };
export const inheritedMember = { ...member, isDirectMember: false }; export const inheritedMember = { ...member, isDirectMember: false };
export const member2faEnabled = { ...member, user: { ...member.user, twoFactorEnabled: true } }; export const member2faEnabled = { ...member, user: { ...member.user, twoFactorEnabled: true } };
export const paginationJsonString = JSON.stringify({
current_page: 1,
per_page: 5,
total_items: 10,
param_name: 'page',
params: { search_groups: null },
});
export const pagination = {
currentPage: 1,
perPage: 5,
totalItems: 10,
paramName: 'page',
params: { search_groups: null },
};
...@@ -22,6 +22,8 @@ import { ...@@ -22,6 +22,8 @@ import {
invite, invite,
membersJsonString, membersJsonString,
members, members,
paginationJsonString,
pagination,
} from './mock_data'; } from './mock_data';
const IS_CURRENT_USER_ID = 123; const IS_CURRENT_USER_ID = 123;
...@@ -259,6 +261,7 @@ describe('Members Utils', () => { ...@@ -259,6 +261,7 @@ describe('Members Utils', () => {
beforeEach(() => { beforeEach(() => {
el = document.createElement('div'); el = document.createElement('div');
el.setAttribute('data-members', membersJsonString); el.setAttribute('data-members', membersJsonString);
el.setAttribute('data-pagination', paginationJsonString);
el.setAttribute('data-source-id', '234'); el.setAttribute('data-source-id', '234');
el.setAttribute('data-can-manage-members', 'true'); el.setAttribute('data-can-manage-members', 'true');
}); });
...@@ -270,6 +273,7 @@ describe('Members Utils', () => { ...@@ -270,6 +273,7 @@ describe('Members Utils', () => {
it('correctly parses the data attributes', () => { it('correctly parses the data attributes', () => {
expect(parseDataAttributes(el)).toEqual({ expect(parseDataAttributes(el)).toEqual({
members, members,
pagination,
sourceId: 234, sourceId: 234,
canManageMembers: true, canManageMembers: true,
}); });
......
...@@ -70,7 +70,7 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -70,7 +70,7 @@ RSpec.describe Groups::GroupMembersHelper do
end end
describe '#group_members_list_data_attributes' do describe '#group_members_list_data_attributes' do
let(:group_member) { create(:group_member, group: group, created_by: current_user) } let_it_be(:group_members) { create_list(:group_member, 2, group: group, created_by: current_user) }
before do before do
allow(helper).to receive(:group_group_member_path).with(group, ':id').and_return('/groups/foo-bar/-/group_members/:id') allow(helper).to receive(:group_group_member_path).with(group, ':id').and_return('/groups/foo-bar/-/group_members/:id')
...@@ -78,13 +78,45 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -78,13 +78,45 @@ RSpec.describe Groups::GroupMembersHelper do
end end
it 'returns expected hash' do it 'returns expected hash' 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_members))).to include({
members: helper.members_data_json(group, present_members([group_member])), members: helper.members_data_json(group, present_members(group_members)),
member_path: '/groups/foo-bar/-/group_members/:id', member_path: '/groups/foo-bar/-/group_members/:id',
source_id: group.id, source_id: group.id,
can_manage_members: 'true' can_manage_members: 'true'
}) })
end end
context 'when pagination is not available' do
it 'sets `pagination` attribute to expected json' do
expect(helper.group_members_list_data_attributes(group, present_members(group_members))[:pagination]).to match({
current_page: nil,
per_page: nil,
total_items: 2,
param_name: nil,
params: {}
}.to_json)
end
end
context 'when pagination is available' do
let(:collection) { Kaminari.paginate_array(group_members).page(1).per(1) }
it 'sets `pagination` attribute to expected json' do
expect(
helper.group_members_list_data_attributes(
group,
present_members(collection),
{ param_name: :page, params: { search_groups: nil } }
)[:pagination]
).to match({
current_page: 1,
per_page: 1,
total_items: 2,
param_name: :page,
params: { search_groups: nil }
}.to_json)
end
end
end end
describe '#group_group_links_list_data_attributes' do describe '#group_group_links_list_data_attributes' do
...@@ -96,6 +128,13 @@ RSpec.describe Groups::GroupMembersHelper do ...@@ -96,6 +128,13 @@ RSpec.describe Groups::GroupMembersHelper do
it 'returns expected hash' do it 'returns expected hash' do
expect(helper.group_group_links_list_data_attributes(shared_group)).to include({ expect(helper.group_group_links_list_data_attributes(shared_group)).to include({
pagination: {
current_page: nil,
per_page: nil,
total_items: 1,
param_name: nil,
params: {}
}.to_json,
members: helper.group_group_links_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',
source_id: shared_group.id source_id: shared_group.id
......
...@@ -147,7 +147,7 @@ RSpec.describe Projects::ProjectMembersHelper do ...@@ -147,7 +147,7 @@ RSpec.describe Projects::ProjectMembersHelper do
end end
describe 'project members' do describe 'project members' do
let_it_be(:project_members) { create_list(:project_member, 1, project: project) } let_it_be(:project_members) { create_list(:project_member, 2, project: project) }
describe '#project_members_data_json' do describe '#project_members_data_json' do
it 'matches json schema' do it 'matches json schema' do
...@@ -170,6 +170,38 @@ RSpec.describe Projects::ProjectMembersHelper do ...@@ -170,6 +170,38 @@ RSpec.describe Projects::ProjectMembersHelper do
can_manage_members: 'true' can_manage_members: 'true'
}) })
end end
context 'when pagination is not available' do
it 'sets `pagination` attribute to expected json' do
expect(helper.project_members_list_data_attributes(project, present_members(project_members))[:pagination]).to match({
current_page: nil,
per_page: nil,
total_items: 2,
param_name: nil,
params: {}
}.to_json)
end
end
context 'when pagination is available' do
let(:collection) { Kaminari.paginate_array(project_members).page(1).per(1) }
it 'sets `pagination` attribute to expected json' do
expect(
helper.project_members_list_data_attributes(
project,
present_members(collection),
{ param_name: :page, params: { search_groups: nil } }
)[:pagination]
).to match({
current_page: 1,
per_page: 1,
total_items: 2,
param_name: :page,
params: { search_groups: nil }
}.to_json)
end
end
end end
end end
...@@ -193,6 +225,13 @@ RSpec.describe Projects::ProjectMembersHelper do ...@@ -193,6 +225,13 @@ RSpec.describe Projects::ProjectMembersHelper do
it 'returns expected hash' do it 'returns expected hash' do
expect(helper.project_group_links_list_data_attributes(project, project_group_links)).to include({ expect(helper.project_group_links_list_data_attributes(project, project_group_links)).to include({
members: helper.project_group_links_data_json(project_group_links), members: helper.project_group_links_data_json(project_group_links),
pagination: {
current_page: nil,
per_page: nil,
total_items: 1,
param_name: nil,
params: {}
}.to_json,
member_path: '/foo-bar/-/group_links/:id', member_path: '/foo-bar/-/group_links/:id',
source_id: project.id, source_id: project.id,
can_manage_members: 'true' can_manage_members: 'true'
......
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