hipchat 1.5.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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