hipchat 1.5.4 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDBiYjZkZDVmYzJiYTFlMGI0YWVjZTZkNGIxMzI2ZTkzOTc0Yzk5OA==
5
- data.tar.gz: !binary |-
6
- ZjE0YmMzM2MxNjEwZjUyZTg5MGU2MDUxYTlkMjQ0MjZmMGU0ZmM5YQ==
2
+ SHA1:
3
+ metadata.gz: f06cfd02a9621ac268502235156b565ee8a53b00
4
+ data.tar.gz: ade9310c79b73892f9e837bd87ec51339a6cbb18
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGJlOGFhMGQzOTBhYjliZDg5ZTI0OGRkNWVlYWU3ZDBmYmM2ZGI1ZDBiODYz
10
- OGExMmFmNzE2ZGUwZGFhNWUxNDRkZGIxNGI3ODE4M2YxMjYxNDE4ZWEzYWMz
11
- Zjk4NTcyZjE5YzI5M2QyM2JlNjM0MjU3OWZhM2I5YWJmNTA0ZTU=
12
- data.tar.gz: !binary |-
13
- MjIyMzRmNDMxZTA2NjE2NmI0NDllOTI5MGZkYTc5MTlmNTVhMzc4NzE5NGE1
14
- NjkzNTMyMjAyNTJmMjE0YTFjNTU3OWZjYjY2MGE5NTk1MTA3ZGE4OWU1NDY2
15
- N2JlZjhiNzY1MGUyODkxZjBkMDBlYzdlNDM3ZGYyNTA3OTQzYTU=
6
+ metadata.gz: 9c4a0072f4197265cd8bac579b35470bb424451ac963700a42ff9b535972d1d1df2ce3bd7d22a0cb82fe189cc24d7b8ce3db2b081fd73017e9b4dc549c40d09a
7
+ data.tar.gz: e914f9f8c2b4ce389a9120db5d32279618aed97ba456e2fa817165bd073500874cd854e4302eaac63bede8e73a8fbd6e02607e618c0483f5680ab95ae26f5e9b
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.4.0
@@ -6,6 +6,8 @@ before_install:
6
6
  - gem update bundler
7
7
 
8
8
  rvm:
9
- - 1.9.3
10
9
  - 2.0.0
11
10
  - 2.1
11
+ - 2.2.6
12
+ - 2.3.3
13
+ - 2.4.0
@@ -8,7 +8,7 @@ h2. CI Status
8
8
  !https://coveralls.io/repos/hipchat/hipchat-rb/badge.svg(Coverage Status)!:https://coveralls.io/r/hipchat/hipchat-rb
9
9
 
10
10
  h2. Requirements
11
- * Ruby 1.9.3 or higher
11
+ * Ruby 2.0.0 or higher
12
12
  * HipChat Account, sign up "here!":https://hipchat.com/
13
13
 
14
14
  h2. Installation
@@ -108,6 +108,15 @@ client['my room'].invite("USER_ID_OR_NAME", options = {})
108
108
  # Sends a user a private message. Valid value for user are user id or email address
109
109
  client.user('foo@bar.org').send('I can send private messages')
110
110
 
111
+ # Update a user status. Available options for show are 'away', 'chat', 'dnd', 'xa'
112
+ client.user('foo@bar.org').status('this is my status',
113
+ :name=>'Foo Bar',
114
+ :status=>'Doing very important stuff',
115
+ :show=>'xa',
116
+ :mention_name=>'foo',
117
+ :email=>'foo@barr.org')
118
+
119
+
111
120
  h2. Custom Server URL
112
121
 
113
122
  bc.. client = HipChat::Client.new(api_token, :api_version => 'v2', :server_url => 'https://domain.com')
@@ -18,16 +18,19 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.required_ruby_version = '>= 1.9.3'
21
+ spec.required_ruby_version = '>= 2.0.0'
22
22
 
23
23
  spec.add_dependency "httparty"
24
24
  spec.add_dependency "mimemagic"
25
25
 
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
  spec.add_development_dependency "rr"
28
- spec.add_development_dependency "bundler", "~> 1.13.0"
28
+ spec.add_development_dependency "bundler", "~> 1.14.0"
29
29
  spec.add_development_dependency "rake"
30
- spec.add_development_dependency "webmock", "= 1.22.1"
30
+ spec.add_development_dependency "webmock", "> 1.22.6"
31
+ spec.add_development_dependency "addressable", "= 2.4.0"
32
+ spec.add_development_dependency "term-ansicolor", "~> 1.4.0"
33
+ spec.add_development_dependency "json", "> 1.8.4"
31
34
  spec.add_development_dependency 'rdoc', '> 2.4.2'
32
35
  spec.add_development_dependency 'tins', '~> 1.6.0'
33
36
  spec.add_development_dependency 'coveralls'
@@ -83,6 +83,15 @@ module HipChat
83
83
  }
84
84
  }[version]
85
85
  end
86
+
87
+ def scopes_config
88
+ raise InvalidApiVersion, 'This functionality is not supported in API v1' unless version.eql?('v2')
89
+ {
90
+ 'v2' => {
91
+ :url => URI::escape("/oauth/token")
92
+ }
93
+ }[version]
94
+ end
86
95
  end
87
96
 
88
97
  class Room < ApiVersion
@@ -186,6 +195,17 @@ module HipChat
186
195
  }[version]
187
196
  end
188
197
 
198
+ def reply_config
199
+ {
200
+ 'v2' => {
201
+ :url => URI::escape("/#{room_id}/reply"),
202
+ :method => :post,
203
+ :query_params => { },
204
+ :body_format => :to_json
205
+ }
206
+ }[version]
207
+ end
208
+
189
209
  def send_file_config
190
210
  {
191
211
  'v2' => {
@@ -302,6 +322,34 @@ module HipChat
302
322
  }[version]
303
323
  end
304
324
 
325
+ def user_joined_rooms_config
326
+ raise InvalidApiVersion, 'This functionality is not supported in API v1' unless version.eql?('v2')
327
+
328
+ {
329
+ 'v2' => {
330
+ :url => URI::escape("/#{user_id}/preference/auto-join"),
331
+ :body_format => :to_json,
332
+ :query_params => {}
333
+ }
334
+ }[version]
335
+ end
336
+
337
+ #Same signature as view_config but separating code to keep any future changes safe
338
+ def user_update_config
339
+ {
340
+ 'v1' => {
341
+ :url => URI::escape('/show'),
342
+ :body_format => :to_json,
343
+ :query_params => { :user_id => user_id }
344
+ },
345
+ 'v2' => {
346
+ :url => URI::escape("/#{user_id}"),
347
+ :body_format => :to_json,
348
+ :query_params => {}
349
+ }
350
+ }[version]
351
+ end
352
+
305
353
 
306
354
  def delete_config
307
355
  {
@@ -7,7 +7,7 @@ module HipChat
7
7
 
8
8
  def initialize(token, options={})
9
9
  @token = token
10
- default_options = { api_version: 'v1', server_url: 'https://api.hipchat.com' }
10
+ default_options = { api_version: 'v2', server_url: 'https://api.hipchat.com' }
11
11
  @options = default_options.merge options
12
12
  @api_version = @options[:api_version]
13
13
  @api = HipChat::ApiVersion::Client.new(@options)
@@ -24,6 +24,43 @@ module HipChat
24
24
  HipChat::Room.new(@token, { room_id: name, :api_version => @api_version, :server_url => @options[:server_url] })
25
25
  end
26
26
 
27
+ # Returns the scopes for the Auth token
28
+ #
29
+ # Calls the endpoint:
30
+ #
31
+ # https://api.hipchat.com/v2/oauth/token/#{token}
32
+ #
33
+ # The response is a JSON object containing a client key. The client
34
+ # object contains a list of allowed scopes.
35
+ #
36
+ # There are two possible response types, for a global API token, the
37
+ # room object will be nil. For a room API token, the room object will
38
+ # be populated:
39
+ #
40
+ # Optional room parameter can be passed in. The method will return the
41
+ # following:
42
+ #
43
+ # - if it's a global API token and room param is nil: scopes
44
+ # - if it's a global API token and room param is not nil: scopes
45
+ # - if it's a room API token and room param is nil: nil
46
+ # - if it's a room API token and room param is not nil
47
+ # - if room param's room_id matches token room_id: scopes
48
+ # - if room param's room_id doesn't match token room_id: nil
49
+ #
50
+ # Raises errors if response is unrecognizable
51
+ def scopes(room: nil)
52
+ path = "#{@api.scopes_config[:url]}/#{URI::escape(@token)}"
53
+ response = self.class.get(path,
54
+ :query => { :auth_token => @token },
55
+ :headers => @api.headers
56
+ )
57
+ ErrorHandler.response_code_to_exception_for :room, 'scopes', response
58
+ return response['scopes'] unless response['client']['room']
59
+ if room && response['client']['room']['id'] == room.room_id
60
+ return response['scopes']
61
+ end
62
+ end
63
+
27
64
  def create_room(name, options={})
28
65
  if @api.version == 'v1' && options[:owner_user_id].nil?
29
66
  raise RoomMissingOwnerUserId, 'V1 API Requires owner_user_id'
@@ -96,12 +133,7 @@ module HipChat
96
133
  end
97
134
 
98
135
  def _rooms
99
- response = self.class.get(@api.rooms_config[:url],
100
- :query => {
101
- :auth_token => @token
102
- },
103
- :headers => @api.headers
104
- )
136
+ response = self.class.get(@api.rooms_config[:url], query: { auth_token: @token }, headers: @api.headers)
105
137
 
106
138
  ErrorHandler.response_code_to_exception_for :room, nil, response
107
139
  response[@api.rooms_config[:data_key]].map do |r|
@@ -1,5 +1,21 @@
1
1
  module HipChat
2
- class ServiceError < StandardError; end
2
+ class ServiceError < StandardError
3
+ attr_accessor :response
4
+
5
+ def initialize(msg, response: nil)
6
+ @response = response
7
+ @msg = msg
8
+ end
9
+
10
+ def message
11
+ if @response.respond_to? :body
12
+ "#{@msg}:\nResponse: #{@response.body}"
13
+ else
14
+ @msg
15
+ end
16
+ end
17
+ end
18
+
3
19
  class RoomNameTooLong < ServiceError; end
4
20
  class RoomMissingOwnerUserId < ServiceError; end
5
21
  class UnknownResponseCode < ServiceError; end
@@ -24,24 +40,24 @@ module HipChat
24
40
  # @param response {HTTParty::Response} The HTTParty response/request object
25
41
  def self.response_code_to_exception_for(klass, identifier, response)
26
42
  # Supports user, room and webhook objects. If we get something other than that, bail.
27
- raise ServiceError "Unknown class #{klass}" unless [:user, :room, :webhook].include? klass
43
+ raise(ServiceError.new("Unknown class #{klass}", response: response)) unless [:user, :room, :webhook].include? klass
28
44
  # Grab the corresponding unknown object exception class and constantize it for the 404 case to call
29
45
  not_found_exception = Module.const_get(HipChat.to_s.to_sym).const_get("Unknown#{klass.capitalize}".to_sym)
30
46
  case response.code
31
47
  when 200, 201, 202, 204;
32
48
  return
33
49
  when 400
34
- raise BadRequest, "The request was invalid. You may be missing a required argument or provided bad data. path:#{response.request.path.to_s} method:#{response.request.http_method.to_s}"
50
+ raise BadRequest.new("The request was invalid. You may be missing a required argument or provided bad data. path:#{response.request.path} method:#{response.request.http_method}", response: response)
35
51
  when 401, 403
36
- raise Unauthorized, "Access denied to #{klass} `#{identifier}'"
52
+ raise Unauthorized.new("Access denied to #{klass} `#{identifier}'", response: response)
37
53
  when 404
38
- raise not_found_exception, "Unknown #{klass}: `#{identifier}'"
54
+ raise not_found_exception.new("Unknown #{klass}: `#{identifier}'", response: response)
39
55
  when 405
40
- raise MethodNotAllowed, "You requested an invalid method. path:#{response.request.path.to_s} method:#{response.request.http_method.to_s}"
56
+ raise MethodNotAllowed.new("You requested an invalid method. path:#{response.request.path} method:#{response.request.http_method}", response: response)
41
57
  when 429
42
- raise TooManyRequests, 'You have exceeded the rate limit. `https://www.hipchat.com/docs/apiv2/rate_limiting`'
58
+ raise TooManyRequests.new('You have exceeded the rate limit. `https://www.hipchat.com/docs/apiv2/rate_limiting`', response: response)
43
59
  else
44
- raise UnknownResponseCode, "Unexpected #{response.code} for #{klass} `#{identifier}'"
60
+ raise UnknownResponseCode.new("Unexpected #{response.code} for #{klass} `#{identifier}'", response: response)
45
61
  end
46
62
  end
47
63
  end
@@ -29,7 +29,7 @@ module HipChat
29
29
 
30
30
  # Update a room
31
31
  def update_room(options = {})
32
- options = {
32
+ merged_options = {
33
33
  :privacy => 'public',
34
34
  :is_archived => false,
35
35
  :is_guest_accessible => false
@@ -38,12 +38,12 @@ module HipChat
38
38
  response = self.class.send(@api.topic_config[:method], @api.update_room_config[:url],
39
39
  :query => { :auth_token => @token },
40
40
  :body => {
41
- :name => options[:name],
42
- :topic => options[:topic],
43
- :privacy => options[:privacy],
44
- :is_archived => @api.bool_val(options[:is_archived]),
45
- :is_guest_accessible => @api.bool_val(options[:is_guest_accessible]),
46
- :owner => options[:owner]
41
+ :name => merged_options[:name],
42
+ :topic => merged_options[:topic],
43
+ :privacy => merged_options[:privacy],
44
+ :is_archived => @api.bool_val(merged_options[:is_archived]),
45
+ :is_guest_accessible => @api.bool_val(merged_options[:is_guest_accessible]),
46
+ :owner => merged_options[:owner]
47
47
  }.to_json,
48
48
  :headers => @api.headers)
49
49
 
@@ -132,23 +132,23 @@ module HipChat
132
132
  if from.length > 20
133
133
  raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 20'"
134
134
  end
135
- options = if options_or_notify == true or options_or_notify == false
135
+ if options_or_notify == true or options_or_notify == false
136
136
  warn 'DEPRECATED: Specify notify flag as an option (e.g., :notify => true)'
137
- { :notify => options_or_notify }
137
+ options = { :notify => options_or_notify }
138
138
  else
139
- options_or_notify || {}
139
+ options = options_or_notify
140
140
  end
141
141
 
142
- options = { :color => 'yellow', :notify => false, :message_format => 'html' }.merge options
142
+ merged_options = { :color => 'yellow', :notify => false, :message_format => 'html' }.merge options
143
143
 
144
144
  body = {
145
145
  :room_id => room_id,
146
146
  :from => from,
147
147
  :message => message,
148
- :message_format => options[:message_format],
149
- :color => options[:color],
150
- :card => options[:card],
151
- :notify => @api.bool_val(options[:notify])
148
+ :message_format => merged_options[:message_format],
149
+ :color => merged_options[:color],
150
+ :card => merged_options[:card],
151
+ :notify => @api.bool_val(merged_options[:notify])
152
152
  }.delete_if { |_k, v| v.nil? }
153
153
 
154
154
  response = self.class.post(@api.send_config[:url],
@@ -161,6 +161,16 @@ module HipChat
161
161
  true
162
162
  end
163
163
 
164
+ def reply(parent_message_id, message)
165
+ query_params = { auth_token: @token }.merge(@api.reply_config[:query_params])
166
+ body = { message: message, parent_message_id: parent_message_id }.send(@api.reply_config[:body_format])
167
+
168
+ response = self.class.post(@api.reply_config[:url], query: query_params, body: body, headers: @api.headers)
169
+
170
+ ErrorHandler.response_code_to_exception_for :room, 'all', response
171
+ response.parsed_response
172
+ end
173
+
164
174
  def share_link(from, message, link)
165
175
  if from.length > 20
166
176
  raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 20'"
@@ -221,13 +231,13 @@ module HipChat
221
231
  # (default "API")
222
232
  def topic(new_topic, options = {})
223
233
 
224
- options = { :from => 'API' }.merge options
234
+ merged_options = { :from => 'API' }.merge options
225
235
 
226
236
  response = self.class.send(@api.topic_config[:method], @api.topic_config[:url],
227
237
  :query => { :auth_token => @token },
228
238
  :body => {
229
239
  :room_id => room_id,
230
- :from => options[:from],
240
+ :from => merged_options[:from],
231
241
  :topic => new_topic
232
242
  }.send(@api.topic_config[:body_format]),
233
243
  :headers => @api.headers
@@ -254,7 +264,7 @@ module HipChat
254
264
  # (default "JSON")
255
265
  def history(options = {})
256
266
 
257
- options = {
267
+ merged_options = {
258
268
  :date => 'recent',
259
269
  :timezone => 'UTC',
260
270
  :format => 'JSON',
@@ -266,14 +276,14 @@ module HipChat
266
276
  response = self.class.get(@api.history_config[:url],
267
277
  :query => {
268
278
  :room_id => room_id,
269
- :date => options[:date],
270
- :timezone => options[:timezone],
271
- :format => options[:format],
272
- :'max-results' => options[:'max-results'],
273
- :'start-index' => options[:'start-index'],
274
- :'end-date' => options[:'end-date'],
279
+ :date => merged_options[:date],
280
+ :timezone => merged_options[:timezone],
281
+ :format => merged_options[:format],
282
+ :'max-results' => merged_options[:'max-results'],
283
+ :'start-index' => merged_options[:'start-index'],
284
+ :'end-date' => merged_options[:'end-date'],
275
285
  :auth_token => @token
276
- },
286
+ }.reject!{|k,v| v.nil?},
277
287
  :headers => @api.headers
278
288
  )
279
289
 
@@ -291,7 +301,7 @@ module HipChat
291
301
  :timezone => options[:timezone],
292
302
  :format => options[:format],
293
303
  :auth_token => @token,
294
- },
304
+ }.reject!{|k,v| v.nil?},
295
305
  :headers => @api.headers
296
306
  )
297
307
 
@@ -313,16 +323,16 @@ module HipChat
313
323
  # +name+:: The label for this webhook
314
324
  # (default "")
315
325
  def create_webhook(url, event, options = {})
316
- raise InvalidEvent unless %w(room_message room_notification room_exit room_enter room_topic_change room_archived room_deleted room_unarchived).include? event
326
+ raise InvalidEvent.new("Invalid event: #{event}") unless %w(room_message room_notification room_exit room_enter room_topic_change room_archived room_deleted room_unarchived).include? event
317
327
 
318
328
  begin
319
329
  u = URI::parse(url)
320
- raise InvalidUrl unless %w(http https).include? u.scheme
330
+ raise InvalidUrl.new("Invalid Scheme: #{url}") unless %w(http https).include? u.scheme
321
331
  rescue URI::InvalidURIError
322
- raise InvalidUrl
332
+ raise InvalidUrl.new("Invalid URL: #{url}")
323
333
  end
324
334
 
325
- options = {
335
+ merged_options = {
326
336
  :pattern => '',
327
337
  :name => ''
328
338
  }.merge options
@@ -331,7 +341,7 @@ module HipChat
331
341
  :query => {
332
342
  :auth_token => @token
333
343
  },
334
- :body => {:url => url, :pattern => options[:pattern], :event => event, :name => options[:name]}.send(@api.send_config[:body_format]),
344
+ :body => {:url => url, :pattern => merged_options[:pattern], :event => event, :name => merged_options[:name]}.send(@api.send_config[:body_format]),
335
345
  :headers => @api.headers
336
346
  )
337
347
 
@@ -371,13 +381,13 @@ module HipChat
371
381
  # +max-results+:: The label for this webhook
372
382
  # (default "")
373
383
  def get_all_webhooks(options = {})
374
- options = {:'start-index' => 0, :'max-results' => 100}.merge(options)
384
+ merged_options = {:'start-index' => 0, :'max-results' => 100}.merge(options)
375
385
 
376
386
  response = self.class.get(@api.webhook_config[:url],
377
387
  :query => {
378
388
  :auth_token => @token,
379
- :'start-index' => options[:'start-index'],
380
- :'max-results' => options[:'max-results']
389
+ :'start-index' => merged_options[:'start-index'],
390
+ :'max-results' => merged_options[:'max-results']
381
391
  },
382
392
  :headers => @api.headers
383
393
  )
@@ -32,7 +32,6 @@ module HipChat
32
32
  }.send(@api.send_config[:body_format]),
33
33
  :headers => @api.headers
34
34
  )
35
-
36
35
  ErrorHandler.response_code_to_exception_for :user, user_id, response
37
36
  true
38
37
  end
@@ -61,7 +60,7 @@ module HipChat
61
60
  )
62
61
 
63
62
  ErrorHandler.response_code_to_exception_for :user, user_id, response
64
- User.new(@token, response.merge(:api_version => @api.version))
63
+ User.new(@token, response.merge(:api_version => @api.version, :server_url => server_url))
65
64
  end
66
65
 
67
66
  #
@@ -100,5 +99,68 @@ module HipChat
100
99
  true
101
100
  end
102
101
 
102
+ #
103
+ # User update.
104
+ # API: https://www.hipchat.com/docs/apiv2/method/update_user
105
+ # Request body
106
+ # name - REQUIRED - User's full name. Valid length range: 1-50
107
+ # roles - The list of roles for the user. For example "owner", "administrator", "user", "delegated administrator"
108
+ # title - User's title
109
+ # status - string may be null
110
+ # show - REQUIRED - string - the status to show for the user. Available options 'away', 'chat', 'dnd', 'xa'
111
+ # mention_name - REQUIRED - User's @mention name without the @
112
+ # is_group_admin - Whether or not this user is an administrator
113
+ # timezone - User's timezone. Must be a supported timezone. Defaults to 'UTC'
114
+ # password - User's password. If not provided, the existing password is kept
115
+ # email - REQUIRED - User's email
116
+ def update(options = {})
117
+ name = options[:name]
118
+ roles = options[:roles] ? options[:roles] : nil
119
+ title = options[:title] ? options[:title] : nil
120
+ status = options[:status] ? options[:status] : nil
121
+ show = options[:show] ? options[:show] : nil
122
+ mention_name = options[:mention_name]
123
+ is_group_admin = options[:is_group_admin] ? options[:is_group_admin] : nil
124
+ timezone = options[:timezone] ? options[:timezone] : 'UTC'
125
+ password = options[:password] ? options[:password] : nil
126
+ email = options[:email]
127
+
128
+ #create body format
129
+ body = {
130
+
131
+ }
132
+
133
+
134
+ response = self.class.put(@api.user_update_config[:url],
135
+ :query => { :auth_token => @token },
136
+ :body => {
137
+ :name => name,
138
+ :presence => {:status=>status, :show=>show},
139
+ :mention_name => mention_name,
140
+ :timezone => timezone,
141
+ :email => email
142
+ }
143
+ .merge(title ? {:title =>title} : {})
144
+ .merge(password ? {:password => password} : {})
145
+ .merge(is_group_admin ? {:is_group_admin => is_group_admin} : {})
146
+ .merge(roles ? {:roles => roles} : {})
147
+ .send(@api.user_update_config[:body_format]),
148
+ :headers => @api.headers
149
+ )
150
+
151
+ ErrorHandler.response_code_to_exception_for :user, user_id, response
152
+ end
153
+
154
+ #
155
+ # Getting all rooms details in which user is present
156
+ #
157
+ def rooms
158
+ response = self.class.get(@api.user_joined_rooms_config[:url],
159
+ :query => { :auth_token => @token }.merge(@api.user_joined_rooms_config[:query_params]),
160
+ :headers => @api.headers
161
+ )
162
+ ErrorHandler.response_code_to_exception_for :user, user_id, response
163
+ User.new(@token, response.merge(:api_version => @api.version))
164
+ end
103
165
  end
104
166
  end
@@ -1,3 +1,3 @@
1
1
  module HipChat
2
- VERSION = '1.5.4'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require'tempfile'
2
3
 
3
4
  describe "HipChat (API V2)" do
4
5
 
@@ -7,6 +8,62 @@ describe "HipChat (API V2)" do
7
8
  let(:room) { subject["Hipchat"] }
8
9
  let(:user) { subject.user "12345678" }
9
10
 
11
+ describe "#scopes" do
12
+ include_context "HipChatV2"
13
+ let(:token_room) { nil }
14
+ before { mock_successful_scopes room: token_room }
15
+
16
+ context 'with a global API token' do
17
+ context 'room parameter given' do
18
+ it 'returns an array of global scopes' do
19
+ expect(subject.scopes(room: room))
20
+ .to match_array(['view_room', 'send_notification'])
21
+ end
22
+ end
23
+
24
+ context 'no room parameter given' do
25
+ it 'returns an array of global scopes' do
26
+ expect(subject.scopes)
27
+ .to match_array(['view_room', 'send_notification'])
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'with a room API token' do
33
+ let(:token_room) { room }
34
+
35
+ context 'room parameter given' do
36
+ context 'room parameter matches API token room' do
37
+ it 'returns an array of global scopes' do
38
+ expect(subject.scopes(room: room))
39
+ .to match_array(['view_room', 'send_notification'])
40
+ end
41
+ end
42
+
43
+ context 'room parameter does not match API token room' do
44
+ let(:token_room) { double(room_id: 'Not-Hipchat') }
45
+ it 'returns nil' do
46
+ expect(subject.scopes(room: room)).to eq nil
47
+ end
48
+ end
49
+ end
50
+
51
+ context 'no room parameter given' do
52
+ it 'returns nil' do
53
+ expect(subject.scopes).to eq nil
54
+ end
55
+ end
56
+ end
57
+
58
+ it "fails if we get an unknown response code" do
59
+ allow(subject.class)
60
+ .to receive(:get).with(anything, anything)
61
+ .and_return(OpenStruct.new(:code => 403))
62
+
63
+ expect { subject.scopes }.to raise_error(HipChat::Unauthorized)
64
+ end
65
+ end
66
+
10
67
  describe "#history" do
11
68
  include_context "HipChatV2"
12
69
  it "is successful without custom options" do
@@ -28,7 +85,7 @@ describe "HipChat (API V2)" do
28
85
  expect(subject.rooms.first.history).to be_truthy
29
86
  end
30
87
 
31
- it "fails when the room doen't exist" do
88
+ it "fails when the room doesn't exist" do
32
89
  allow(room.class).to receive(:get).with(anything, anything).and_return(OpenStruct.new(:code => 404))
33
90
 
34
91
  expect { room.history }.to raise_error(HipChat::UnknownRoom)
@@ -63,7 +120,7 @@ describe "HipChat (API V2)" do
63
120
  expect(subject.rooms.first.statistics).to be_truthy
64
121
  end
65
122
 
66
- it "fails when the room doen't exist" do
123
+ it "fails when the room doesn't exist" do
67
124
  allow(room.class).to receive(:get).with(anything, anything).and_return(OpenStruct.new(:code => 404))
68
125
 
69
126
  expect { room.statistics }.to raise_error(HipChat::UnknownRoom)
@@ -115,6 +172,8 @@ describe "HipChat (API V2)" do
115
172
  end
116
173
  end
117
174
 
175
+
176
+
118
177
  describe "#send_message" do
119
178
  include_context "HipChatV2"
120
179
  it "successfully without custom options" do
@@ -202,6 +261,36 @@ describe "HipChat (API V2)" do
202
261
  end
203
262
  end
204
263
 
264
+ describe '#reply' do
265
+ include_context 'HipChatV2'
266
+ let(:parent_id) { '100000' }
267
+ let(:message) { 'Hello world' }
268
+
269
+ it 'successfully' do
270
+ mock_successful_reply parent_id, message
271
+
272
+ expect(room.reply(parent_id, message))
273
+ end
274
+
275
+ it "but fails when the parent_id doesn't exist" do
276
+ allow(room.class).to receive(:post).and_return(OpenStruct.new(:code => 404))
277
+
278
+ expect { room.reply parent_id, message }.to raise_error(HipChat::UnknownRoom)
279
+ end
280
+
281
+ it "but fails when we're not allowed to do so" do
282
+ allow(room.class).to receive(:post).and_return(OpenStruct.new(:code => 401))
283
+
284
+ expect { room.reply parent_id, message }.to raise_error(HipChat::Unauthorized)
285
+ end
286
+
287
+ it 'but fails if we get an unknown response code' do
288
+ allow(room.class).to receive(:post).and_return(OpenStruct.new(:code => 403))
289
+
290
+ expect { room.reply parent_id, message }.to raise_error(HipChat::Unauthorized)
291
+ end
292
+ end
293
+
205
294
  describe '#share_link' do
206
295
  let(:link) { "http://i.imgur.com/cZ6GDFY.jpg" }
207
296
  include_context "HipChatV2"
@@ -317,6 +406,31 @@ describe "HipChat (API V2)" do
317
406
  end
318
407
  end
319
408
 
409
+ describe "#user_update" do
410
+ include_context "HipChatV2"
411
+
412
+ let(:user_update) {
413
+ {
414
+ :name => "Foo Bar",
415
+ :presence => { status: "Away", show: "away" },
416
+ :mention_name => "foo",
417
+ :timezone => "GMT",
418
+ :email => "foo@bar.org",
419
+ :title => "mister",
420
+ :is_group_admin => 0,
421
+ :roles => []
422
+ }
423
+ }
424
+
425
+ it "successfull" do
426
+ mock_successful_user_update(user_update)
427
+
428
+ user_update.delete(:presence)
429
+ .each { |key, value| user_update[key] = value }
430
+ expect(user.update(user_update))
431
+ end
432
+ end
433
+
320
434
  describe "#get_room" do
321
435
  include_context "HipChatV2"
322
436
 
@@ -0,0 +1,133 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe HipChat::ErrorHandler do
4
+ let(:body) { { error: { code: code, message: 'any', type: 'any' } } }
5
+ let(:request) { HTTParty::Request.new(Net::HTTP::Get, 'http://foo.com/') }
6
+ let(:response) { HTTParty::Response.new(request, response_object, lambda { body }) }
7
+ let(:room_id) { 'Hipchat' }
8
+ before do
9
+ allow(response_object).to receive_messages(body: body.to_json)
10
+ end
11
+
12
+
13
+ describe 'response_code_to_exception_for' do
14
+ subject { HipChat::ErrorHandler.response_code_to_exception_for(:room, room_id, response) }
15
+
16
+ context 'success codes' do
17
+ shared_examples 'the error handler' do
18
+ it "does not raise an error" do
19
+ expect { subject }.not_to raise_error
20
+ end
21
+ end
22
+
23
+ context 'Hipchat API responds with success' do
24
+ describe 'code 200' do
25
+ let(:response_object) { Net::HTTPOK.new('1.1', code, '') }
26
+ let(:code) { 200 }
27
+ it_should_behave_like 'the error handler'
28
+ end
29
+
30
+ describe 'code 201' do
31
+ let(:response_object) { Net::HTTPCreated.new('1.1', code, '') }
32
+ let(:code) { 201 }
33
+ it_should_behave_like 'the error handler'
34
+ end
35
+
36
+ describe 'code 202' do
37
+ let(:response_object) { Net::HTTPAccepted.new('1.1', code, '') }
38
+ let(:code) { 202 }
39
+ it_should_behave_like 'the error handler'
40
+ end
41
+
42
+ describe 'code 204' do
43
+ let(:response_object) { Net::HTTPNoContent.new('1.1', code, '') }
44
+ let(:code) { 204 }
45
+ it_should_behave_like 'the error handler'
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'failure codes' do
51
+ shared_examples 'the error handler' do
52
+ it "raises the correct client error" do
53
+ expect { subject }
54
+ .to raise_error(client_error) do |error|
55
+ expect(error.message)
56
+ .to match message
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'Hipchat API responds with Not Found' do
62
+ let(:response_object) { Net::HTTPNotFound.new('1.1', code, '') }
63
+ let(:client_error) { HipChat::UnknownRoom }
64
+ let(:message) { "Unknown room: `#{room_id}\':\nResponse: #{body.to_json}" }
65
+
66
+ describe 'code 404' do
67
+ let(:code) { 404 }
68
+ it_should_behave_like 'the error handler'
69
+ end
70
+ end
71
+
72
+ context 'Hipchat API responds with Unauthorized' do
73
+ let(:response_object) { Net::HTTPUnauthorized.new('1.1', code, '') }
74
+ let(:client_error) { HipChat::Unauthorized }
75
+ let(:message) { "Access denied to room `#{room_id}\':\nResponse: #{body.to_json}" }
76
+
77
+ describe 'code 401' do
78
+ let(:code) { 401 }
79
+ it_should_behave_like 'the error handler'
80
+ end
81
+
82
+ describe 'code 403' do
83
+ let(:code) { 403 }
84
+ it_should_behave_like 'the error handler'
85
+ end
86
+ end
87
+
88
+ context 'Hipchat API responds with Bad Request' do
89
+ let(:response_object) { Net::HTTPBadRequest.new('1.1', code, '') }
90
+ let(:client_error) { HipChat::BadRequest }
91
+ let(:message) { "The request was invalid. You may be missing a required argument or provided bad data. path:http://foo.com/ method:Net::HTTP::Get:\nResponse: #{body.to_json}" }
92
+
93
+ describe 'code 400' do
94
+ let(:code) { 400 }
95
+ it_should_behave_like 'the error handler'
96
+ end
97
+ end
98
+
99
+ context 'Hipchat API responds with MethodNotAllowed' do
100
+ let(:response_object) { Net::HTTPMethodNotAllowed.new('1.1', code, '') }
101
+ let(:client_error) { HipChat::MethodNotAllowed }
102
+ let(:message) { "You requested an invalid method. path:http://foo.com/ method:Net::HTTP::Get:\nResponse: #{body.to_json}" }
103
+
104
+ describe 'code 405' do
105
+ let(:code) { 405 }
106
+ it_should_behave_like 'the error handler'
107
+ end
108
+ end
109
+
110
+ context 'Hipchat API responds with TooManyRequests' do
111
+ let(:response_object) { Net::HTTPTooManyRequests.new('1.1', code, '') }
112
+ let(:client_error) { HipChat::TooManyRequests }
113
+ let(:message) { "You have exceeded the rate limit. `https://www.hipchat.com/docs/apiv2/rate_limiting`:\nResponse: #{body.to_json}" }
114
+
115
+ describe 'code 429' do
116
+ let(:code) { 429 }
117
+ it_should_behave_like 'the error handler'
118
+ end
119
+ end
120
+
121
+ context 'Hipchat API responds with an unknown response code' do
122
+ let(:response_object) { Net::HTTPBadGateway.new('1.1', code, '') }
123
+ let(:client_error) { HipChat::UnknownResponseCode }
124
+ let(:message) { "Unexpected 502 for room `#{room_id}\'" }
125
+
126
+ describe 'code 502' do
127
+ let(:code) { 502 }
128
+ it_should_behave_like 'the error handler'
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -40,9 +40,9 @@ describe HipChat do
40
40
 
41
41
  context "api_version" do
42
42
 
43
- it "defaults to a v1 client" do
43
+ it "defaults to a v2 client" do
44
44
  client = HipChat::Client.new("blah")
45
- expect(client[:example].api_version).to eql('v1')
45
+ expect(client[:example].api_version).to eql('v2')
46
46
  end
47
47
 
48
48
  it "when given 'v1' it registers a v1 client" do
@@ -50,7 +50,7 @@ shared_context "HipChatV1" do
50
50
  :'max-results' => options[:'max-results'],
51
51
  :'start-index' => options[:'start-index'],
52
52
  :'end-date' => options[:'end-date'],
53
- :format => options[:format]}).to_return(canned_response)
53
+ :format => options[:format]}.reject!{|k,v| v.nil?}).to_return(canned_response)
54
54
  end
55
55
 
56
56
  def mock_successful_room_creation(name, options={})
@@ -123,6 +123,16 @@ shared_context "HipChatV2" do
123
123
  'Content-Type' => 'application/json'}).to_return(:status => 200, :body => "", :headers => {})
124
124
  end
125
125
 
126
+ def mock_successful_reply(parent_message_id, message)
127
+ stub_request(:post, 'https://api.hipchat.com/v2/room/Hipchat/reply?auth_token=blah')
128
+ .with(query: { auth_token: 'blah' },
129
+ body: { parent_message_id: parent_message_id,
130
+ message: message },
131
+ headers: { 'Accept' => 'application/json',
132
+ 'Content-Type' => 'application/json' })
133
+ .to_return(status: 200, body: '', headers: {})
134
+ end
135
+
126
136
  def mock_successful_link_share(from, message, link)
127
137
  stub_request(:post, "https://api.hipchat.com/v2/room/Hipchat/share/link").with(
128
138
  :query => {:auth_token => "blah"},
@@ -179,6 +189,29 @@ shared_context "HipChatV2" do
179
189
  :headers => {})
180
190
  end
181
191
 
192
+ def mock_successful_scopes(room: nil)
193
+ token_room = room ? { id: room.room_id, name: 'example' } : nil
194
+ stub_request(:get, 'https://api.hipchat.com/v2/oauth/token/blah').with(
195
+ :query => { :auth_token => 'blah' },
196
+ :body => '',
197
+ :headers => {
198
+ 'Accept' => 'application/json',
199
+ 'Content-Type' => 'application/json'
200
+ }
201
+ ).to_return(
202
+ :status => 200,
203
+ :body => {
204
+ client: {
205
+ allowed_scopes: [:view_room, :send_notification],
206
+ name: 'All perms',
207
+ room: token_room
208
+ },
209
+ scopes: [:view_room, :send_notification]
210
+ }.to_json,
211
+ :headers => {}
212
+ )
213
+ end
214
+
182
215
  def mock_successful_history(options={})
183
216
  options = { :date => 'recent', :timezone => 'UTC', :format => 'JSON', :'max-results' => 100, :'start-index' => 0 }.merge(options)
184
217
  canned_response = File.new(HISTORY_JSON_PATH)
@@ -189,7 +222,7 @@ shared_context "HipChatV2" do
189
222
  :'max-results' => options[:'max-results'],
190
223
  :'start-index' => options[:'start-index'],
191
224
  :'end-date' => options[:'end-date'],
192
- :format => options[:format]}).to_return(canned_response)
225
+ :format => options[:format]}.reject!{|k,v| v.nil?}).to_return(canned_response)
193
226
  end
194
227
 
195
228
  def mock_successful_statistics(options={})
@@ -197,7 +230,7 @@ shared_context "HipChatV2" do
197
230
  :room_id => "Hipchat",
198
231
  :date => options[:date],
199
232
  :timezone => options[:timezone],
200
- :format => options[:format]}).to_return(
233
+ :format => options[:format]}.reject!{|k,v| v.nil?}).to_return(
201
234
  :status => 200,
202
235
  :body => '{"last_active": "2014-09-02T21:33:54+00:00", "links": {"self": "https://api.hipchat.com/v2/room/12345/statistics"}, "messages_sent": 10}',
203
236
  :headers => {})
@@ -326,6 +359,19 @@ shared_context "HipChatV2" do
326
359
  'Content-Type' => 'multipart/related; boundary=sendfileboundary'}).to_return(:status => 200, :body => "", :headers => {})
327
360
  end
328
361
 
362
+ def mock_successful_user_update(options)
363
+ stub_request(:put, "https://api.hipchat.com/v2/user/12345678").with(
364
+ :query => {:auth_token => "blah"},
365
+ :body => options.to_json,
366
+ :headers => {"Accept" => "application/json",
367
+ "Content-Type" => "application/json"}).to_return(
368
+ :status => 204,
369
+ :body => "",
370
+ :headers => {})
371
+
372
+
373
+ end
374
+
329
375
  def mock_successful_create_webhook(room_id, url, event, options = {})
330
376
  options = {:pattern => '', :name => ''}.merge(options)
331
377
  stub_request(:post, "https://api.hipchat.com/v2/room/#{room_id}/webhook").with(
metadata CHANGED
@@ -1,153 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hipchat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HipChat/Atlassian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-12 00:00:00.000000000 Z
11
+ date: 2017-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mimemagic
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rr
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.13.0
75
+ version: 1.14.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.13.0
82
+ version: 1.14.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.22.6
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.22.6
111
+ - !ruby/object:Gem::Dependency
112
+ name: addressable
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - '='
102
116
  - !ruby/object:Gem::Version
103
- version: 1.22.1
117
+ version: 2.4.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - '='
109
123
  - !ruby/object:Gem::Version
110
- version: 1.22.1
124
+ version: 2.4.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: term-ansicolor
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.4.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.4.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: json
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">"
144
+ - !ruby/object:Gem::Version
145
+ version: 1.8.4
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">"
151
+ - !ruby/object:Gem::Version
152
+ version: 1.8.4
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: rdoc
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
- - - ! '>'
157
+ - - ">"
116
158
  - !ruby/object:Gem::Version
117
159
  version: 2.4.2
118
160
  type: :development
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
122
- - - ! '>'
164
+ - - ">"
123
165
  - !ruby/object:Gem::Version
124
166
  version: 2.4.2
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: tins
127
169
  requirement: !ruby/object:Gem::Requirement
128
170
  requirements:
129
- - - ~>
171
+ - - "~>"
130
172
  - !ruby/object:Gem::Version
131
173
  version: 1.6.0
132
174
  type: :development
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
- - - ~>
178
+ - - "~>"
137
179
  - !ruby/object:Gem::Version
138
180
  version: 1.6.0
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: coveralls
141
183
  requirement: !ruby/object:Gem::Requirement
142
184
  requirements:
143
- - - ! '>='
185
+ - - ">="
144
186
  - !ruby/object:Gem::Version
145
187
  version: '0'
146
188
  type: :development
147
189
  prerelease: false
148
190
  version_requirements: !ruby/object:Gem::Requirement
149
191
  requirements:
150
- - - ! '>='
192
+ - - ">="
151
193
  - !ruby/object:Gem::Version
152
194
  version: '0'
153
195
  description: Ruby library to interact with HipChat
@@ -157,12 +199,12 @@ executables: []
157
199
  extensions: []
158
200
  extra_rdoc_files: []
159
201
  files:
160
- - .coveralls.yml
161
- - .document
162
- - .gitignore
163
- - .ruby-gemset
164
- - .ruby-version
165
- - .travis.yml
202
+ - ".coveralls.yml"
203
+ - ".document"
204
+ - ".gitignore"
205
+ - ".ruby-gemset"
206
+ - ".ruby-version"
207
+ - ".travis.yml"
166
208
  - Gemfile
167
209
  - LICENSE
168
210
  - README.textile
@@ -185,6 +227,7 @@ files:
185
227
  - spec/example/history.json
186
228
  - spec/hipchat_api_v1_spec.rb
187
229
  - spec/hipchat_api_v2_spec.rb
230
+ - spec/hipchat_error_handler_spec.rb
188
231
  - spec/hipchat_spec.rb
189
232
  - spec/spec.opts
190
233
  - spec/spec_helper.rb
@@ -200,17 +243,17 @@ require_paths:
200
243
  - lib
201
244
  required_ruby_version: !ruby/object:Gem::Requirement
202
245
  requirements:
203
- - - ! '>='
246
+ - - ">="
204
247
  - !ruby/object:Gem::Version
205
- version: 1.9.3
248
+ version: 2.0.0
206
249
  required_rubygems_version: !ruby/object:Gem::Requirement
207
250
  requirements:
208
- - - ! '>='
251
+ - - ">="
209
252
  - !ruby/object:Gem::Version
210
253
  version: '0'
211
254
  requirements: []
212
255
  rubyforge_project:
213
- rubygems_version: 2.4.8
256
+ rubygems_version: 2.6.8
214
257
  signing_key:
215
258
  specification_version: 4
216
259
  summary: Ruby library to interact with HipChat
@@ -218,6 +261,7 @@ test_files:
218
261
  - spec/example/history.json
219
262
  - spec/hipchat_api_v1_spec.rb
220
263
  - spec/hipchat_api_v2_spec.rb
264
+ - spec/hipchat_error_handler_spec.rb
221
265
  - spec/hipchat_spec.rb
222
266
  - spec/spec.opts
223
267
  - spec/spec_helper.rb