Commit aee6367c authored by Vijay Hawoldar's avatar Vijay Hawoldar Committed by Etienne Baqué

Allow filtering of members by state in REST API

parent 900de4d9
......@@ -109,6 +109,7 @@ GET /projects/:id/members/all
| `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `query` | string | no | A query string to search for members |
| `user_ids` | array of integers | no | Filter the results on the given user IDs |
| `state` | string | no | Filter results by member state, one of `awaiting`, `active` or `created` **(PREMIUM)** |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/all"
......
......@@ -20,6 +20,10 @@ module EE
params :optional_filter_params_ee do
optional :with_saml_identity, type: Grape::API::Boolean, desc: "List only members with linked SAML identity"
end
params :optional_state_filter_ee do
optional :state, type: String, desc: 'Filter results by member state', values: %w(awaiting active created)
end
end
# rubocop: disable CodeReuse/ActiveRecord
......@@ -35,6 +39,8 @@ module EE
end
end
members = members.with_state(params[:state]) if params[:state].present?
members
end
......
......@@ -7,5 +7,17 @@ FactoryBot.modify do
member.wait
end
end
trait :active do
after(:create) do |member|
member.activate
end
end
trait :created do
after(:create) do |member|
member.update!(state: Member::STATE_CREATED)
end
end
end
end
......@@ -7,5 +7,17 @@ FactoryBot.modify do
member.wait
end
end
trait :active do
after(:create) do |member|
member.activate
end
end
trait :created do
after(:create) do |member|
member.update!(state: Member::STATE_CREATED)
end
end
end
end
......@@ -1104,4 +1104,69 @@ RSpec.describe API::Members do
end
end
end
context 'filtering project and group members' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:owner) { create(:user) }
let(:params) { { state: state } }
before do
group.add_owner(owner)
end
subject do
get api("/#{source_type}/#{source.id}/members/all", owner), params: params
json_response
end
shared_examples 'filtered results' do
context 'for active members' do
let(:state) { 'active' }
it 'returns only active members' do
expect(subject.map { |u| u['id'] }).to match_array [active_member.user_id, owner.id]
end
end
context 'for awaiting members' do
let(:state) { 'awaiting' }
it 'returns only awaiting members' do
expect(subject.map { |u| u['id'] }).to match_array [awaiting_member.user_id]
end
end
context 'for created members' do
let(:state) { 'created' }
it 'returns only created members' do
expect(subject.map { |u| u['id'] }).to match_array [created_member.user_id]
end
end
end
context 'for group sources' do
let(:source_type) { 'groups' }
let(:source) { group }
it_behaves_like 'filtered results' do
let_it_be(:awaiting_member) { create(:group_member, :awaiting, group: group) }
let_it_be(:active_member) { create(:group_member, :active, group: group) }
let_it_be(:created_member) { create(:group_member, :created, group: group) }
end
end
context 'for project sources' do
let(:source_type) { 'projects' }
let(:source) { project }
it_behaves_like 'filtered results' do
let_it_be(:awaiting_member) { create(:project_member, :awaiting, project: project) }
let_it_be(:active_member) { create(:project_member, :active, project: project) }
let_it_be(:created_member) { create(:project_member, :created, project: project) }
end
end
end
end
......@@ -8,6 +8,9 @@ module API
params :optional_filter_params_ee do
end
params :optional_state_filter_ee do
end
def find_source(source_type, id)
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
end
......
......@@ -41,6 +41,7 @@ module API
optional :query, type: String, desc: 'A query string to search for members'
optional :user_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of user ids to look up for membership'
optional :show_seat_info, type: Boolean, desc: 'Show seat information for members'
use :optional_state_filter_ee
use :pagination
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