Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/gitlab/client/groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ def group_members(id, options = {})
get("/groups/#{url_encode id}/members", query: options)
end

# Get a list of descendant groups of a group.
#
# @example
# Gitlab.group_descendants(42)
#
# @param [Integer] id the ID of a group
# @param [Hash] options A customizable set of options.
# @option options [String] :skip_groups Skip the group IDs passed.
# @option options [String] :all_available Show all the groups you have access to (defaults to false for authenticated users).
# @option options [String] :search Return the list of authorized groups matching the search criteria.
# @option options [String] :order_by Order groups by name or path. Default is name.
# @option options [String] :sort Order groups in asc or desc order. Default is asc.
# @option options [String] :statistics Include group statistics (admins only).
# @option options [String] :owned Limit to groups owned by the current user.
# @return [Array<Gitlab::ObjectifiedHash>] List of all subgroups under a group
def group_descendants(id, options = {})
get("/groups/#{url_encode id}/descendant_groups", query: options)
end

# Get a list of group members that are billable.
#
# @example
Expand Down
18 changes: 17 additions & 1 deletion lib/gitlab/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ class BadGateway < ResponseError; end
# Raised when API endpoint returns the HTTP status code 503.
class ServiceUnavailable < ResponseError; end

# Raised when API endpoint returns the HTTP status code 522.
class ConnectionTimedOut < ResponseError; end

# HTTP status codes mapped to error classes.
STATUS_MAPPINGS = {
400 => BadRequest,
Expand All @@ -148,7 +151,20 @@ class ServiceUnavailable < ResponseError; end
429 => TooManyRequests,
500 => InternalServerError,
502 => BadGateway,
503 => ServiceUnavailable
503 => ServiceUnavailable,
522 => ConnectionTimedOut
}.freeze

# Returns error class that should be raised for this response. Returns nil
# if the response status code is not 4xx or 5xx.
#
# @param [HTTParty::Response] response The response object.
# @return [Class<Error::ResponseError>, nil]
def self.klass(response)
error_klass = STATUS_MAPPINGS[response.code]
return error_klass if error_klass

ResponseError if response.server_error? || response.client_error?
end
end
end
2 changes: 1 addition & 1 deletion lib/gitlab/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def self.decode(response)
# Checks the response code for common errors.
# Returns parsed response for successful requests.
def validate(response)
error_klass = Error::STATUS_MAPPINGS[response.code]
error_klass = Error.klass(response)
raise error_klass, response if error_klass

parsed = response.parsed_response
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/group_descendants.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"id": 1,"name":"Foobar Group","path":"foo-bar","description":"An interesting group","visibility":"public","lfs_enabled":true,"avatar_url":"http://gitlab.example.com/uploads/group/avatar/1/foo.jpg","web_url":"http://gitlab.example.com/groups/foo-bar","request_access_enabled":false,"full_name":"Foobar Group","full_path":"foo-bar","parent_id":3},{"id":2,"name": "Foobar Group 2","path":"foo-bar-2","description":"Another interesting group","visibility":"public","lfs_enabled":true,"avatar_url":"http://gitlab.example.com/uploads/group/avatar/2/foo.jpg","web_url":"http://gitlab.example.com/groups/foo-bar-2","request_access_enabled":false,"full_name":"Foobar Group 2","full_path":"foo-bar-2","parent_id":1}]
17 changes: 17 additions & 0 deletions spec/gitlab/client/groups_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@
end
end

describe '.group_descendants' do
before do
stub_get('/groups/3/descendant_groups', 'group_descendants')
@descendants = Gitlab.group_descendants(3)
end

it 'gets the correct resource' do
expect(a_get('/groups/3/descendant_groups')).to have_been_made
end

it "returns information about a group's descendants" do
expect(@descendants).to be_a Gitlab::PaginatedResponse
expect(@descendants.size).to eq(2)
expect(@descendants[1].name).to eq('Foobar Group 2')
end
end

describe '.group_billable_members' do
before do
stub_get('/groups/3/billable_members', 'group_billable_members')
Expand Down
26 changes: 26 additions & 0 deletions spec/gitlab/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@
end
end

describe 'errors' do
before do
@request.private_token = 'token'
@request.endpoint = 'https://example.com/api/v4'
@rpath = "#{@request.endpoint}/version"

allow(@request).to receive(:httparty)
end

it 'raises error for 5xx status code without special error class' do
stub_request(:get, @rpath).to_return(status: 599)

expect { @request.get('/version') }.to raise_error(Gitlab::Error::ResponseError)

expect(a_request(:get, @rpath)).to have_been_made
end

it 'raises error for 4xx status code without special error class' do
stub_request(:get, @rpath).to_return(status: 499)

expect { @request.get('/version') }.to raise_error(Gitlab::Error::ResponseError)

expect(a_request(:get, @rpath)).to have_been_made
end
end

describe 'ratelimiting' do
before do
@request.private_token = 'token'
Expand Down