gitlab 2.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -1
  4. data/LICENSE.txt +1 -1
  5. data/README.md +9 -1
  6. data/lib/gitlab.rb +7 -7
  7. data/lib/gitlab/api.rb +1 -1
  8. data/lib/gitlab/client.rb +9 -7
  9. data/lib/gitlab/client/groups.rb +88 -0
  10. data/lib/gitlab/client/issues.rb +13 -16
  11. data/lib/gitlab/client/merge_requests.rb +67 -5
  12. data/lib/gitlab/client/milestones.rb +6 -8
  13. data/lib/gitlab/client/notes.rb +106 -0
  14. data/lib/gitlab/client/projects.rb +98 -17
  15. data/lib/gitlab/client/repositories.rb +4 -6
  16. data/lib/gitlab/client/snippets.rb +22 -15
  17. data/lib/gitlab/configuration.rb +2 -1
  18. data/lib/gitlab/error.rb +9 -0
  19. data/lib/gitlab/request.rb +25 -20
  20. data/lib/gitlab/version.rb +1 -1
  21. data/spec/fixtures/comment_merge_request.json +1 -0
  22. data/spec/fixtures/create_merge_request.json +1 -0
  23. data/spec/fixtures/error_already_exists.json +1 -0
  24. data/spec/fixtures/group.json +60 -0
  25. data/spec/fixtures/group_create.json +1 -0
  26. data/spec/fixtures/group_member.json +1 -0
  27. data/spec/fixtures/group_member_delete.json +1 -0
  28. data/spec/fixtures/group_members.json +1 -0
  29. data/spec/fixtures/groups.json +2 -0
  30. data/spec/fixtures/note.json +1 -0
  31. data/spec/fixtures/notes.json +1 -0
  32. data/spec/fixtures/project.json +1 -1
  33. data/spec/fixtures/project_delete_key.json +8 -0
  34. data/spec/fixtures/project_for_user.json +1 -0
  35. data/spec/fixtures/project_fork_link.json +1 -0
  36. data/spec/fixtures/project_key.json +6 -0
  37. data/spec/fixtures/project_keys.json +6 -0
  38. data/spec/fixtures/update_merge_request.json +1 -0
  39. data/spec/gitlab/client/groups_spec.rb +111 -0
  40. data/spec/gitlab/client/issues_spec.rb +2 -2
  41. data/spec/gitlab/client/merge_requests_spec.rb +57 -0
  42. data/spec/gitlab/client/notes_spec.rb +156 -0
  43. data/spec/gitlab/client/projects_spec.rb +97 -2
  44. data/spec/gitlab/client/users_spec.rb +20 -9
  45. data/spec/gitlab_spec.rb +7 -0
  46. data/spec/spec_helper.rb +2 -2
  47. metadata +55 -31
@@ -20,7 +20,7 @@ class Gitlab::Client
20
20
  # Gitlab.project(3)
21
21
  # Gitlab.project('gitlab')
22
22
  #
23
- # @param [Integer, String] id The ID or code name of a project.
23
+ # @param [Integer, String] id The ID or name of a project.
24
24
  # @return [Gitlab::ObjectifiedHash]
25
25
  def project(id)
26
26
  get("/projects/#{id}")
@@ -35,17 +35,19 @@ class Gitlab::Client
35
35
  #
36
36
  # @param [String] name The name of a project.
37
37
  # @param [Hash] options A customizable set of options.
38
- # @option options [String] :code The code name of a project.
39
- # @option options [String] :path The path of a project.
40
38
  # @option options [String] :description The description of a project.
41
39
  # @option options [String] :default_branch The default branch of a project.
42
40
  # @option options [Boolean] :wiki_enabled The wiki integration for a project (0 = false, 1 = true).
43
41
  # @option options [Boolean] :wall_enabled The wall functionality for a project (0 = false, 1 = true).
44
42
  # @option options [Boolean] :issues_enabled The issues integration for a project (0 = false, 1 = true).
43
+ # @option options [Boolean] :snippets_enabled The snippets integration for a project (0 = false, 1 = true).
45
44
  # @option options [Boolean] :merge_requests_enabled The merge requests functionality for a project (0 = false, 1 = true).
45
+ # @option options [Boolean] :public The setting for making a project public (0 = false, 1 = true).
46
+ # @option options [Integer] :user_id The user/owner id of a project.
46
47
  # @return [Gitlab::ObjectifiedHash] Information about created project.
47
48
  def create_project(name, options={})
48
- post("/projects", :body => {:name => name}.merge(options))
49
+ url = options[:user_id] ? "/projects/user/#{options[:user_id]}" : "/projects"
50
+ post(url, :body => {:name => name}.merge(options))
49
51
  end
50
52
 
51
53
  # Gets a list of project team members.
@@ -54,8 +56,9 @@ class Gitlab::Client
54
56
  # Gitlab.team_members(42)
55
57
  # Gitlab.team_members('gitlab')
56
58
  #
57
- # @param [Integer, String] project The ID or code name of a project.
59
+ # @param [Integer, String] project The ID or name of a project.
58
60
  # @param [Hash] options A customizable set of options.
61
+ # @option options [String] :query The search query.
59
62
  # @option options [Integer] :page The page number.
60
63
  # @option options [Integer] :per_page The number of results per page.
61
64
  # @return [Array<Gitlab::ObjectifiedHash>]
@@ -68,9 +71,9 @@ class Gitlab::Client
68
71
  # @example
69
72
  # Gitlab.team_member('gitlab', 2)
70
73
  #
71
- # @param [Integer, String] project The ID or code name of a project.
74
+ # @param [Integer, String] project The ID or name of a project.
72
75
  # @param [Integer] id The ID of a project team member.
73
- # @return [Array<Gitlab::ObjectifiedHash>]
76
+ # @return [Gitlab::ObjectifiedHash]
74
77
  def team_member(project, id)
75
78
  get("/projects/#{project}/members/#{id}")
76
79
  end
@@ -80,10 +83,11 @@ class Gitlab::Client
80
83
  # @example
81
84
  # Gitlab.add_team_member('gitlab', 2, 40)
82
85
  #
83
- # @param [Integer, String] project The ID or code name of a project.
86
+ # @param [Integer, String] project The ID or name of a project.
84
87
  # @param [Integer] id The ID of a user.
85
88
  # @param [Integer] access_level The access level to project.
86
- # @return [Array<Gitlab::ObjectifiedHash>] Information about added team member.
89
+ # @param [Hash] options A customizable set of options.
90
+ # @return [Gitlab::ObjectifiedHash] Information about added team member.
87
91
  def add_team_member(project, id, access_level)
88
92
  post("/projects/#{project}/members", :body => {:user_id => id, :access_level => access_level})
89
93
  end
@@ -93,9 +97,10 @@ class Gitlab::Client
93
97
  # @example
94
98
  # Gitlab.edit_team_member('gitlab', 3, 20)
95
99
  #
96
- # @param [Integer, String] project The ID or code name of a project.
100
+ # @param [Integer, String] project The ID or name of a project.
97
101
  # @param [Integer] id The ID of a user.
98
102
  # @param [Integer] access_level The access level to project.
103
+ # @param [Hash] options A customizable set of options.
99
104
  # @return [Array<Gitlab::ObjectifiedHash>] Information about updated team member.
100
105
  def edit_team_member(project, id, access_level)
101
106
  put("/projects/#{project}/members/#{id}", :body => {:access_level => access_level})
@@ -106,9 +111,10 @@ class Gitlab::Client
106
111
  # @example
107
112
  # Gitlab.remove_team_member('gitlab', 2)
108
113
  #
109
- # @param [Integer, String] project The ID or code name of a project.
114
+ # @param [Integer, String] project The ID or name of a project.
110
115
  # @param [Integer] id The ID of a user.
111
- # @return [Array<Gitlab::ObjectifiedHash>] Information about removed team member.
116
+ # @param [Hash] options A customizable set of options.
117
+ # @return [Gitlab::ObjectifiedHash] Information about removed team member.
112
118
  def remove_team_member(project, id)
113
119
  delete("/projects/#{project}/members/#{id}")
114
120
  end
@@ -119,7 +125,7 @@ class Gitlab::Client
119
125
  # Gitlab.project_hooks(42)
120
126
  # Gitlab.project_hooks('gitlab')
121
127
  #
122
- # @param [Integer, String] project The ID or code name of a project.
128
+ # @param [Integer, String] project The ID or name of a project.
123
129
  # @param [Hash] options A customizable set of options.
124
130
  # @option options [Integer] :page The page number.
125
131
  # @option options [Integer] :per_page The number of results per page.
@@ -134,7 +140,7 @@ class Gitlab::Client
134
140
  # Gitlab.project_hook(42, 5)
135
141
  # Gitlab.project_hook('gitlab', 5)
136
142
  #
137
- # @param [Integer, String] project The ID or code name of a project.
143
+ # @param [Integer, String] project The ID or name of a project.
138
144
  # @param [Integer] id The ID of a hook.
139
145
  # @return [Gitlab::ObjectifiedHash]
140
146
  def project_hook(project, id)
@@ -146,7 +152,7 @@ class Gitlab::Client
146
152
  # @example
147
153
  # Gitlab.add_project_hook(42, 'https://api.example.net/v1/webhooks/ci')
148
154
  #
149
- # @param [Integer, String] project The ID or code name of a project.
155
+ # @param [Integer, String] project The ID or name of a project.
150
156
  # @param [String] url The hook URL.
151
157
  # @return [Gitlab::ObjectifiedHash] Information about added hook.
152
158
  def add_project_hook(project, url)
@@ -158,7 +164,7 @@ class Gitlab::Client
158
164
  # @example
159
165
  # Gitlab.edit_project_hook(42, 1, 'https://api.example.net/v1/webhooks/ci')
160
166
  #
161
- # @param [Integer, String] project The ID or code name of a project.
167
+ # @param [Integer, String] project The ID or name of a project.
162
168
  # @param [Integer] id The ID of the hook.
163
169
  # @param [String] url The hook URL.
164
170
  # @return [Gitlab::ObjectifiedHash] Information about updated hook.
@@ -171,11 +177,86 @@ class Gitlab::Client
171
177
  # @example
172
178
  # Gitlab.delete_project_hook('gitlab', 4)
173
179
  #
174
- # @param [Integer, String] project The ID or code name of a project.
180
+ # @param [Integer, String] project The ID or name of a project.
175
181
  # @param [String] id The ID of the hook.
176
182
  # @return [Gitlab::ObjectifiedHash] Information about deleted hook.
177
183
  def delete_project_hook(project, id)
178
184
  delete("/projects/#{project}/hooks/#{id}")
179
185
  end
186
+
187
+ # Mark this project as forked from the other
188
+ #
189
+ # @example
190
+ # Gitlab.make_forked(42, 24)
191
+ #
192
+ # @param [Integer, String] project The ID or name of a project.
193
+ # @param [Integer] id The ID of the project it is forked from.
194
+ # @return [Gitlab::ObjectifiedHash] Information about the forked project.
195
+ def make_forked_from(project, id)
196
+ post("/projects/#{project}/fork/#{id}")
197
+ end
198
+
199
+ # Remove a forked_from relationship for a project.
200
+ #
201
+ # @example
202
+ # Gitlab.remove_forked(42)
203
+ #
204
+ # @param [Integer, String] project The ID or name of a project.
205
+ # @param [Integer] project The ID of the project it is forked from
206
+ # @return [Gitlab::ObjectifiedHash] Information about the forked project.
207
+ def remove_forked(project)
208
+ delete("/projects/#{project}/fork")
209
+ end
210
+
211
+ # Gets a project deploy keys.
212
+ #
213
+ # @example
214
+ # Gitlab.deploy_keys(42)
215
+ #
216
+ # @param [Integer] project The ID of a project.
217
+ # @param [Hash] options A customizable set of options.
218
+ # @option options [Integer] :page The page number.
219
+ # @option options [Integer] :per_page The number of results per page.
220
+ # @return [Array<Gitlab::ObjectifiedHash>]
221
+ def deploy_keys(project, options={})
222
+ get("/projects/#{project}/keys", :query => options)
223
+ end
224
+
225
+ # Gets a single project deploy key.
226
+ #
227
+ # @example
228
+ # Gitlab.deploy_key(42, 1)
229
+ #
230
+ # @param [Integer, String] project The ID of a project.
231
+ # @param [Integer] id The ID of a deploy key.
232
+ # @return [Gitlab::ObjectifiedHash]
233
+ def deploy_key(project, id)
234
+ get("/projects/#{project}/keys/#{id}")
235
+ end
236
+
237
+ # Creates a new deploy key.
238
+ #
239
+ # @example
240
+ # Gitlab.create_deploy_key(42, 'My Key', 'Key contents')
241
+ #
242
+ # @param [Integer] project The ID of a project.
243
+ # @param [String] title The title of a deploy key.
244
+ # @param [String] key The content of a deploy key.
245
+ # @return [Gitlab::ObjectifiedHash] Information about created deploy key.
246
+ def create_deploy_key(project, title, key)
247
+ post("/projects/#{project}/keys", title: title, key: key)
248
+ end
249
+
250
+ # Deletes a deploy key from project.
251
+ #
252
+ # @example
253
+ # Gitlab.delete_deploy_key(42, 1)
254
+ #
255
+ # @param [Integer] project The ID of a project.
256
+ # @param [Integer] id The ID of a deploy key.
257
+ # @return [Gitlab::ObjectifiedHash] Information about deleted deploy key.
258
+ def delete_deploy_key(project, id)
259
+ delete("/projects/#{project}/keys/#{id}")
260
+ end
180
261
  end
181
262
  end
@@ -5,9 +5,8 @@ class Gitlab::Client
5
5
  #
6
6
  # @example
7
7
  # Gitlab.tags(42)
8
- # Gitlab.repo_tags('gitlab')
9
8
  #
10
- # @param [Integer, String] project The ID or code name of a project.
9
+ # @param [Integer] project The ID of a project.
11
10
  # @param [Hash] options A customizable set of options.
12
11
  # @option options [Integer] :page The page number.
13
12
  # @option options [Integer] :per_page The number of results per page.
@@ -21,9 +20,8 @@ class Gitlab::Client
21
20
  #
22
21
  # @example
23
22
  # Gitlab.branches(42)
24
- # Gitlab.repo_branches('gitlab')
25
23
  #
26
- # @param [Integer, String] project The ID or code name of a project.
24
+ # @param [Integer] project The ID of a project.
27
25
  # @param [Hash] options A customizable set of options.
28
26
  # @option options [Integer] :page The page number.
29
27
  # @option options [Integer] :per_page The number of results per page.
@@ -39,7 +37,7 @@ class Gitlab::Client
39
37
  # Gitlab.branch(3, 'api')
40
38
  # Gitlab.repo_branch(5, 'master')
41
39
  #
42
- # @param [Integer, String] project The ID or code name of a project.
40
+ # @param [Integer] project The ID of a project.
43
41
  # @param [String] branch The name of the branch.
44
42
  # @return [Gitlab::ObjectifiedHash]
45
43
  def branch(project, branch)
@@ -53,7 +51,7 @@ class Gitlab::Client
53
51
  # Gitlab.commits('viking')
54
52
  # Gitlab.repo_commits('gitlab', :ref_name => 'api')
55
53
  #
56
- # @param [String] project The name of a project.
54
+ # @param [Integer] project The ID of a project.
57
55
  # @param [Hash] options A customizable set of options.
58
56
  # @option options [String] :ref_name The branch or tag name of a project repository.
59
57
  # @option options [Integer] :page The page number.
@@ -5,9 +5,8 @@ class Gitlab::Client
5
5
  #
6
6
  # @example
7
7
  # Gitlab.snippets(42)
8
- # Gitlab.snippets('gitlab')
9
8
  #
10
- # @param [Integer, String] project The ID or code name of a project.
9
+ # @param [Integer] project The ID of a project.
11
10
  # @param [Hash] options A customizable set of options.
12
11
  # @option options [Integer] :page The page number.
13
12
  # @option options [Integer] :per_page The number of results per page.
@@ -20,9 +19,8 @@ class Gitlab::Client
20
19
  #
21
20
  # @example
22
21
  # Gitlab.snippet(2, 14)
23
- # Gitlab.snippet('gitlab', 34)
24
22
  #
25
- # @param [Integer, String] project The ID or code name of a project.
23
+ # @param [Integer] project The ID of a project.
26
24
  # @param [Integer] id The ID of a snippet.
27
25
  # @return [Gitlab::ObjectifiedHash]
28
26
  def snippet(project, id)
@@ -32,26 +30,26 @@ class Gitlab::Client
32
30
  # Creates a new snippet.
33
31
  #
34
32
  # @example
35
- # Gitlab.create_snippet('gitlab',
36
- # {:title => 'REST', :file_name => 'api.rb', :code => 'some code'})
33
+ # Gitlab.create_snippet(42, {:title => 'REST', :file_name => 'api.rb', :code => 'some code'})
37
34
  #
38
- # @param [Integer, String] project The ID or code name of a project.
35
+ # @param [Integer] project The ID of a project.
39
36
  # @param [Hash] options A customizable set of options.
40
- # @option options [String] :title The title of a snippet.
41
- # @option options [String] :file_name The name of a snippet file.
42
- # @option options [String] :code The content of a snippet.
43
- # @option options [String] :lifetime The expiration date of a snippet.
37
+ # @option options [String] :title (required) The title of a snippet.
38
+ # @option options [String] :file_name (required) The name of a snippet file.
39
+ # @option options [String] :code (required) The content of a snippet.
40
+ # @option options [String] :lifetime (optional) The expiration date of a snippet.
44
41
  # @return [Gitlab::ObjectifiedHash] Information about created snippet.
45
42
  def create_snippet(project, options={})
43
+ check_attributes!(options, [:title, :file_name, :code])
46
44
  post("/projects/#{project}/snippets", :body => options)
47
45
  end
48
46
 
49
47
  # Updates a snippet.
50
48
  #
51
49
  # @example
52
- # Gitlab.edit_snippet('gitlab', 34, :file_name => 'README.txt')
50
+ # Gitlab.edit_snippet(42, 34, :file_name => 'README.txt')
53
51
  #
54
- # @param [Integer, String] project The ID or code name of a project.
52
+ # @param [Integer] project The ID of a project.
55
53
  # @param [Integer] id The ID of a snippet.
56
54
  # @param [Hash] options A customizable set of options.
57
55
  # @option options [String] :title The title of a snippet.
@@ -67,13 +65,22 @@ class Gitlab::Client
67
65
  #
68
66
  # @example
69
67
  # Gitlab.delete_snippet(2, 14)
70
- # Gitlab.delete_snippet('gitlab', 34)
71
68
  #
72
- # @param [Integer, String] project The ID or code name of a project.
69
+ # @param [Integer] project The ID of a project.
73
70
  # @param [Integer] id The ID of a snippet.
74
71
  # @return [Gitlab::ObjectifiedHash] Information about deleted snippet.
75
72
  def delete_snippet(project, id)
76
73
  delete("/projects/#{project}/snippets/#{id}")
77
74
  end
75
+
76
+ private
77
+
78
+ def check_attributes!(options, attrs)
79
+ attrs.each do |attr|
80
+ unless options.has_key?(attr) || options.has_key?(attr.to_s)
81
+ raise Gitlab::Error::MissingAttributes.new("Missing '#{attr}' parameter")
82
+ end
83
+ end
84
+ end
78
85
  end
79
86
  end
@@ -2,7 +2,7 @@ module Gitlab
2
2
  # Defines constants and methods related to configuration.
3
3
  module Configuration
4
4
  # An array of valid keys in the options hash when configuring a Gitlab::API.
5
- VALID_OPTIONS_KEYS = [:endpoint, :private_token, :user_agent].freeze
5
+ VALID_OPTIONS_KEYS = [:endpoint, :private_token, :user_agent, :sudo].freeze
6
6
 
7
7
  # The user agent that will be sent to the API endpoint if none is set.
8
8
  DEFAULT_USER_AGENT = "Gitlab Ruby Gem #{Gitlab::VERSION}".freeze
@@ -32,6 +32,7 @@ module Gitlab
32
32
  def reset
33
33
  self.endpoint = nil
34
34
  self.private_token = nil
35
+ self.sudo = nil
35
36
  self.user_agent = DEFAULT_USER_AGENT
36
37
  end
37
38
  end
@@ -3,6 +3,9 @@ module Gitlab
3
3
  # Custom error class for rescuing from all Gitlab errors.
4
4
  class Error < StandardError; end
5
5
 
6
+ # Raise when attributes are missing.
7
+ class MissingAttributes < Error; end
8
+
6
9
  # Raised when API endpoint credentials not configured.
7
10
  class MissingCredentials < Error; end
8
11
 
@@ -21,6 +24,12 @@ module Gitlab
21
24
  # Raised when API endpoint returns the HTTP status code 404.
22
25
  class NotFound < Error; end
23
26
 
27
+ # Raised when API endpoint returns the HTTP status code 405.
28
+ class MethodNotAllowed < Error; end
29
+
30
+ # Raised when API endpoint returns the HTTP status code 409.
31
+ class Conflict < Error; end
32
+
24
33
  # Raised when API endpoint returns the HTTP status code 500.
25
34
  class InternalServerError < Error; end
26
35
 
@@ -4,9 +4,9 @@ module Gitlab
4
4
  # @private
5
5
  class Request
6
6
  include HTTParty
7
- format :json
7
+ format :json
8
8
  headers 'Accept' => 'application/json'
9
- parser Proc.new {|body| parse(body)}
9
+ parser Proc.new { |body, _| parse(body) }
10
10
 
11
11
  # Converts the response body to an ObjectifiedHash.
12
12
  def self.parse(body)
@@ -15,7 +15,7 @@ module Gitlab
15
15
  if body.is_a? Hash
16
16
  ObjectifiedHash.new body
17
17
  elsif body.is_a? Array
18
- body.collect! {|e| ObjectifiedHash.new(e)}
18
+ body.collect! { |e| ObjectifiedHash.new(e) }
19
19
  else
20
20
  raise Error::Parsing.new "Couldn't parse a response body"
21
21
  end
@@ -24,12 +24,8 @@ module Gitlab
24
24
  # Decodes a JSON response into Ruby object.
25
25
  def self.decode(response)
26
26
  begin
27
- if MultiJson.respond_to?(:adapter)
28
- MultiJson.load response
29
- else
30
- MultiJson.decode response
31
- end
32
- rescue MultiJson::DecodeError
27
+ JSON.load response
28
+ rescue JSON::ParserError
33
29
  raise Error::Parsing.new "The response is not a valid JSON"
34
30
  end
35
31
  end
@@ -53,28 +49,37 @@ module Gitlab
53
49
  # Checks the response code for common errors.
54
50
  # Returns parsed response for successful requests.
55
51
  def validate(response)
56
- message = "Server responsed with code #{response.code}"
57
52
  case response.code
58
- when 400; raise Error::BadRequest.new message
59
- when 401; raise Error::Unauthorized.new message
60
- when 403; raise Error::Forbidden.new message
61
- when 404; raise Error::NotFound.new message
62
- when 500; raise Error::InternalServerError.new message
63
- when 502; raise Error::BadGateway.new message
64
- when 503; raise Error::ServiceUnavailable.new message
53
+ when 400; raise Error::BadRequest.new error_message(response)
54
+ when 401; raise Error::Unauthorized.new error_message(response)
55
+ when 403; raise Error::Forbidden.new error_message(response)
56
+ when 404; raise Error::NotFound.new error_message(response)
57
+ when 405; raise Error::MethodNotAllowed.new error_message(response)
58
+ when 409; raise Error::Conflict.new error_message(response)
59
+ when 500; raise Error::InternalServerError.new error_message(response)
60
+ when 502; raise Error::BadGateway.new error_message(response)
61
+ when 503; raise Error::ServiceUnavailable.new error_message(response)
65
62
  end
66
63
 
67
64
  response.parsed_response
68
65
  end
69
66
 
70
- # Sets a base_uri and private_token parameter for requests.
67
+ # Sets a base_uri and default_params for requests.
71
68
  # @raise [Error::MissingCredentials] if endpoint or private_token not set.
72
- def set_request_defaults(endpoint, private_token)
69
+ def set_request_defaults(endpoint, private_token, sudo=nil)
73
70
  raise Error::MissingCredentials.new("Please set an endpoint to API") unless endpoint
74
71
  raise Error::MissingCredentials.new("Please set a private_token for user") unless private_token
75
72
 
76
73
  self.class.base_uri endpoint
77
- self.class.default_params :private_token => private_token
74
+ self.class.default_params :private_token => private_token, :sudo => sudo
75
+ self.class.default_params.delete(:sudo) if sudo.nil?
76
+ end
77
+
78
+ private
79
+
80
+ def error_message(response)
81
+ "Server responded with code #{response.code}, message: #{response.parsed_response.message}. " \
82
+ "Request URI: #{response.request.base_uri}#{response.request.path}"
78
83
  end
79
84
  end
80
85
  end