desk_api 0.6.1 → 0.6.2

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +26 -8
  4. data/lib/desk.rb +1 -1
  5. data/lib/desk_api.rb +2 -3
  6. data/lib/desk_api/client.rb +6 -6
  7. data/lib/desk_api/configuration.rb +5 -2
  8. data/lib/desk_api/default.rb +2 -2
  9. data/lib/desk_api/error.rb +2 -2
  10. data/lib/desk_api/error/bad_gateway.rb +1 -1
  11. data/lib/desk_api/error/bad_request.rb +1 -1
  12. data/lib/desk_api/error/client_error.rb +1 -1
  13. data/lib/desk_api/error/configuration_error.rb +1 -1
  14. data/lib/desk_api/error/conflict.rb +1 -1
  15. data/lib/desk_api/error/follow_redirect_error.rb +1 -1
  16. data/lib/desk_api/error/forbidden.rb +1 -1
  17. data/lib/desk_api/error/gateway_timeout.rb +1 -1
  18. data/lib/desk_api/error/internal_server_error.rb +1 -1
  19. data/lib/desk_api/error/method_not_allowed.rb +1 -1
  20. data/lib/desk_api/error/not_acceptable.rb +1 -1
  21. data/lib/desk_api/error/not_found.rb +1 -1
  22. data/lib/desk_api/error/parser_error.rb +1 -1
  23. data/lib/desk_api/error/server_error.rb +1 -1
  24. data/lib/desk_api/error/service_unavailable.rb +1 -1
  25. data/lib/desk_api/error/too_many_requests.rb +1 -1
  26. data/lib/desk_api/error/unauthorized.rb +1 -1
  27. data/lib/desk_api/error/unprocessable_entity.rb +1 -1
  28. data/lib/desk_api/error/unsupported_media_type.rb +1 -1
  29. data/lib/desk_api/rate_limit.rb +2 -2
  30. data/lib/desk_api/request/encode_dates.rb +73 -0
  31. data/lib/desk_api/request/encode_json.rb +2 -2
  32. data/lib/desk_api/request/oauth.rb +2 -2
  33. data/lib/desk_api/request/retry.rb +4 -3
  34. data/lib/desk_api/resource.rb +22 -194
  35. data/lib/desk_api/resource/download.rb +57 -0
  36. data/lib/desk_api/resource/pagination.rb +77 -0
  37. data/lib/desk_api/resource/query_params.rb +106 -0
  38. data/lib/desk_api/resource/scrud.rb +145 -0
  39. data/lib/desk_api/response/follow_redirects.rb +2 -2
  40. data/lib/desk_api/response/parse_dates.rb +2 -2
  41. data/lib/desk_api/response/parse_json.rb +2 -2
  42. data/lib/desk_api/response/raise_error.rb +2 -2
  43. data/lib/desk_api/version.rb +2 -2
  44. data/spec/cassettes/DeskApi_Resource/_next_/returns_nil_on_non-page_resources.yml +207 -0
  45. data/spec/cassettes/DeskApi_Resource/_next_/throws_an_error_on_non-page_resources.yml +207 -0
  46. data/spec/cassettes/DeskApi_Resource_Download/downloads_the_attachment.yml +238 -0
  47. data/spec/cassettes/DeskApi_Resource_Download/throws_an_error_on_non_attachment_resources.yml +47 -0
  48. data/spec/cassettes/DeskApi_Resource_Pagination/_all/iterates_over_each_resource_on_each_page.yml +13538 -0
  49. data/spec/cassettes/DeskApi_Resource_Pagination/_each_page/iterates_over_each_page.yml +13538 -0
  50. data/spec/cassettes/DeskApi_Resource_Pagination/_each_page/raises_NoMethodError_is_called_on_non-page_resources.yml +2093 -0
  51. data/spec/cassettes/DeskApi_Resource_Pagination/_each_page/uses_a_default_per_page_of_1000.yml +13538 -0
  52. data/spec/cassettes/DeskApi_Resource_QueryParams/_page/keeps_the_resource_as_loaded.yml +2093 -0
  53. data/spec/cassettes/DeskApi_Resource_QueryParams/_page/returns_the_current_page_and_loads_if_page_not_defined.yml +1207 -0
  54. data/spec/cassettes/DeskApi_Resource_QueryParams/_page/sets_the_resource_to_not_loaded.yml +2093 -0
  55. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_create/creates_a_new_topic.yml +0 -0
  56. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_create/throws_an_error_creating_a_user.yml +0 -0
  57. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_delete/deletes_a_resource.yml +0 -0
  58. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_delete/throws_an_error_deleting_a_non_deletalbe_resource.yml +0 -0
  59. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_find/has_an_alias_by_id.yml +0 -0
  60. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_find/loads_the_requested_resource.yml +0 -0
  61. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_search/allows_searching_on_search_enabled_resources.yml +0 -0
  62. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_search/throws_an_error_if_search_is_not_enabled.yml +0 -0
  63. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/can_handle_action_params.yml +0 -0
  64. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/can_handle_links.yml +0 -0
  65. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/can_handle_update_action_params.yml +0 -0
  66. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/can_replace_instead_of_append.yml +0 -0
  67. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/can_update_without_a_hash.yml +0 -0
  68. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/throws_an_error_updating_a_user.yml +0 -0
  69. data/spec/cassettes/{DeskApi_Resource → DeskApi_Resource_SCRUD}/_update/updates_a_topic.yml +0 -0
  70. data/spec/desk_api/client_spec.rb +33 -7
  71. data/spec/desk_api/configuration_spec.rb +4 -4
  72. data/spec/desk_api/default_spec.rb +1 -1
  73. data/spec/desk_api/error_spec.rb +1 -1
  74. data/spec/desk_api/rate_limit_spec.rb +1 -1
  75. data/spec/desk_api/request/encode_dates_spec.rb +63 -0
  76. data/spec/desk_api/request/encode_json_spec.rb +4 -4
  77. data/spec/desk_api/request/oauth_spec.rb +1 -1
  78. data/spec/desk_api/request/retry_spec.rb +1 -1
  79. data/spec/desk_api/resource/download_spec.rb +45 -0
  80. data/spec/desk_api/resource/pagination_spec.rb +77 -0
  81. data/spec/desk_api/resource/query_params_spec.rb +145 -0
  82. data/spec/desk_api/resource/scrud_spec.rb +216 -0
  83. data/spec/desk_api/resource_spec.rb +14 -321
  84. data/spec/desk_api/response/follow_redirects_spec.rb +1 -1
  85. data/spec/desk_api/response/parse_dates_spec.rb +1 -1
  86. data/spec/desk_api/response/parse_json_spec.rb +1 -1
  87. data/spec/desk_api/response/raise_error_spec.rb +1 -1
  88. data/spec/desk_api_spec.rb +1 -1
  89. data/spec/spec_helper.rb +1 -2
  90. data/spec/stubs/file.jpg +0 -0
  91. metadata +128 -104
  92. data/spec/cassettes/DeskApi_Resource/_all/iterates_over_each_resource_on_each_page.yml +0 -1953
  93. data/spec/cassettes/DeskApi_Resource/_each_page/iterates_over_each_page.yml +0 -1953
  94. data/spec/cassettes/DeskApi_Resource/_each_page/raises_NoMethodError_is_called_on_non-page_resources.yml +0 -207
  95. data/spec/cassettes/DeskApi_Resource/_each_page/uses_a_default_per_page_of_1000.yml +0 -1953
  96. data/spec/cassettes/DeskApi_Resource/_page/keeps_the_resource_as_loaded.yml +0 -113
  97. data/spec/cassettes/DeskApi_Resource/_page/returns_the_current_page_and_loads_if_page_not_defined.yml +0 -62
  98. data/spec/cassettes/DeskApi_Resource/_page/sets_the_resource_to_not_loaded.yml +0 -113
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014, Salesforce.com, Inc.
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without modification,
@@ -33,7 +33,7 @@ module DeskApi
33
33
  # the request body. It also sets the "Content-Type" header.
34
34
  #
35
35
  # @author Thomas Stachl <tstachl@salesforce.com>
36
- # @copyright Copyright (c) 2013-2014 Salesforce.com
36
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
37
37
  # @license BSD 3-Clause License
38
38
  class EncodeJson < Faraday::Middleware
39
39
  dependency 'json'
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014, Salesforce.com, Inc.
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without modification,
@@ -32,7 +32,7 @@ module DeskApi
32
32
  # sign requests with an OAuth header.
33
33
  #
34
34
  # @author Thomas Stachl <tstachl@salesforce.com>
35
- # @copyright Copyright (c) 2013-2014 Salesforce.com
35
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
36
36
  # @license BSD 3-Clause License
37
37
  class OAuth < Faraday::Middleware
38
38
  dependency 'simple_oauth'
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014, Salesforce.com, Inc.
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without modification,
@@ -33,7 +33,7 @@ module DeskApi
33
33
  # desk.com's rate limiting which are retried only once.
34
34
  #
35
35
  # @author Thomas Stachl <tstachl@salesforce.com>
36
- # @copyright Copyright (c) 2013-2014 Salesforce.com
36
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
37
37
  # @license BSD 3-Clause License
38
38
  class Retry < Faraday::Middleware
39
39
  class << self
@@ -45,7 +45,8 @@ module DeskApi
45
45
  Errno::ETIMEDOUT,
46
46
  'Timeout::Error',
47
47
  Faraday::Error::TimeoutError,
48
- DeskApi::Error::TooManyRequests
48
+ DeskApi::Error::TooManyRequests,
49
+ DeskApi::Error::BadRequest
49
50
  ]
50
51
  end
51
52
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014, Salesforce.com, Inc.
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without modification,
@@ -26,6 +26,12 @@
26
26
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
27
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
+ require 'addressable/uri'
30
+ require 'desk_api/resource/scrud'
31
+ require 'desk_api/resource/pagination'
32
+ require 'desk_api/resource/query_params'
33
+ require 'desk_api/resource/download'
34
+
29
35
  module DeskApi
30
36
  # {DeskApi::Resource} holds most of the magic of this wrapper. Basically
31
37
  # everything that comes back from Desk.com's API is a Resource, it keeps
@@ -33,7 +39,7 @@ module DeskApi
33
39
  # and allows you access to embedded resources.
34
40
  #
35
41
  # @author Thomas Stachl <tstachl@salesforce.com>
36
- # @copyright Copyright (c) 2013-2014 Salesforce.com
42
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
37
43
  # @license BSD 3-Clause License
38
44
  #
39
45
  # @example get a cases {DeskApi::Resource}
@@ -42,14 +48,19 @@ module DeskApi
42
48
  extend Forwardable
43
49
  def_delegator :@_client, :by_url, :by_url
44
50
 
51
+ include DeskApi::Resource::SCRUD
52
+ include DeskApi::Resource::QueryParams
53
+ include DeskApi::Resource::Pagination
54
+ include DeskApi::Resource::Download
55
+
45
56
  class << self
46
57
  # Returns a {DeskApi::Resource} definition with a self link
47
58
  #
48
59
  # @param link [String/Hash] the self href as string or hash
49
60
  # @return [Hash]
50
61
  def build_self_link(link, params = {})
51
- link = {'href'=>link} if link.kind_of?(String)
52
- {'_links'=>{'self'=>link}}
62
+ link = { 'href' => link } if link.kind_of?(String)
63
+ { '_links' => { 'self' => link } }
53
64
  end
54
65
  end
55
66
 
@@ -64,122 +75,19 @@ module DeskApi
64
75
  @_client, @_definition, @_loaded = client, definition, loaded
65
76
  end
66
77
 
67
- # This method will POST to the Desk.com API and create a
68
- # new resource
69
- #
70
- # @param params [Hash] the params to create the resource
71
- # @return [DeskApi::Resource] the newly created resource
72
- def create(params = {})
73
- new_resource(@_client.post(clean_base_url, params).body, true)
74
- end
75
-
76
- # Use this method to update a {DeskApi::Resource}, it'll
77
- # PATCH changes to the Desk.com API
78
- #
79
- # @param params [Hash] the params to update the resource
80
- # @return [DeskApi::Resource] the updated resource
81
- def update(params = {})
82
- changes = filter_update_actions params
83
- changes.merge!(filter_links(params)) # quickfix
84
- params.each_pair{ |key, value| send("#{key}=", value) if respond_to?("#{key}=") }
85
- changes.merge!(@_changed.clone)
86
-
87
- reset!
88
- @_definition, @_loaded = [@_client.patch(href, changes).body, true]
89
-
90
- self
91
- end
92
-
93
- # Deletes the {DeskApi::Resource}.
94
- #
95
- # @return [Boolean] has the resource been deleted?
96
- def delete
97
- @_client.delete(href).status === 204
98
- end
99
-
100
- # Using this method allows you to hit the search endpoint
101
- #
102
- # @param params [Hash] the search params
103
- # @return [DeskApi::Resource] the search page resource
104
- def search(params = {})
105
- params = { q: params } if params.kind_of?(String)
106
- url = Addressable::URI.parse(clean_base_url + '/search')
107
- url.query_values = params
108
- new_resource(self.class.build_self_link(url.to_s))
109
- end
110
-
111
- # Returns a {DeskApi::Resource} based on the given id
112
- #
113
- # @param id [String/Integer] the id of the resource
114
- # @param options [Hash] additional options (currently only embed is supported)
115
- # @return [DeskApi::Resource] the requested resource
116
- def find(id, options = {})
117
- res = new_resource(self.class.build_self_link("#{clean_base_url}/#{id}"))
118
- res.embed(*(options[:embed].kind_of?(Array) ? options[:embed] : [options[:embed]])) if options[:embed]
119
- res.exec!
120
- end
121
- alias_method :by_id, :find
122
-
123
78
  # Change self to the next page
124
79
  #
125
80
  # @return [Desk::Resource] self
126
81
  def next!
127
- self.load
82
+ load
128
83
  next_page = @_definition['_links']['next']
129
84
 
130
85
  if next_page
131
- @_definition = self.class.build_self_link(next_page)
86
+ @_definition = DeskApi::Resource.build_self_link(next_page)
132
87
  self.reset!
133
88
  end
134
89
  end
135
90
 
136
- # Paginate through all the resources on a give page {DeskApi::Resource}
137
- #
138
- # @raise [NoMethodError] if self is not a page resource
139
- # @raise [ArgumentError] if no block is given
140
- # @yield [DeskApi::Resource] the current resource
141
- # @yield [Integer] the current page number
142
- def all
143
- raise ArgumentError, "Block must be given for #all" unless block_given?
144
- each_page do |page, page_num|
145
- page.entries.each { |resource| yield resource, page_num }
146
- end
147
- end
148
-
149
- # Paginate through each page on a give page {DeskApi::Resource}
150
- #
151
- # @raise [NoMethodError] if self is not a page resource
152
- # @raise [ArgumentError] if no block is given
153
- # @yield [DeskApi::Resource] the current page resource
154
- # @yield [Integer] the current page number
155
- def each_page
156
- raise ArgumentError, "Block must be given for #each_page" unless block_given?
157
-
158
- begin
159
- page = self.first.per_page(self.query_params['per_page'] || 1000).dup
160
- rescue NoMethodError => err
161
- raise NoMethodError, "#each_page and #all are only available on resources which offer pagination"
162
- end
163
-
164
- begin
165
- yield page, page.page
166
- end while page.next!
167
- end
168
-
169
- # Allows you to embed/sideload resources
170
- #
171
- # @example embed customers with their cases
172
- # my_cases = client.cases.embed(:customers)
173
- # @example embed assigned_user and assigned_group
174
- # my_cases = client.cases.embed(:assigned_user, :assigned_group)
175
- # @param embedds [Symbol/String] whatever you want to embed
176
- # @return [Desk::Resource] self
177
- def embed(*embedds)
178
- # make sure we don't try to embed anything that's not defined
179
- # add it to the query
180
- self.tap{ |res| res.query_params = { embed: embedds.join(',') } }
181
- end
182
-
183
91
  # Returns the self link hash
184
92
  #
185
93
  # @return [Hash] self link hash
@@ -207,7 +115,7 @@ module DeskApi
207
115
  #
208
116
  # @return [Hash] definition hash
209
117
  def to_hash
210
- self.load
118
+ load
211
119
 
212
120
  {}.tap do |hash|
213
121
  @_definition.each do |k, v|
@@ -223,62 +131,12 @@ module DeskApi
223
131
  get_self['class']
224
132
  end
225
133
 
226
-
227
- # Get/set the page and per_page query params
228
- #
229
- # @param value [Integer/Nil] the value to use
230
- # @return [Integer/DeskApi::Resource]
231
- %w(page per_page).each do |method|
232
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
233
- def #{method}(value = nil)
234
- unless value
235
- exec! if query_params_include?('#{method}') == nil
236
- return query_params_include?('#{method}').to_i
237
- end
238
- tap{ |res| res.query_params = Hash['#{method}', value.to_s] }
239
- end
240
- RUBY
241
- end
242
-
243
- # Converts the current self href query params to a hash
244
- #
245
- # @return [Hash] current self href query params
246
- def query_params
247
- Addressable::URI.parse(href).query_values || {}
248
- end
249
-
250
- # Checks if the specified param is included
251
- #
252
- # @param param [String] the param to check for
253
- # @return [Boolean]
254
- def query_params_include?(param)
255
- query_params.include?(param) ? query_params[param] : nil
256
- end
257
-
258
- # Sets the query params based on the provided hash
259
- #
260
- # @param params [Hash] the query params
261
- # @return [String] the generated href
262
- def query_params=(params = {})
263
- return href if params.empty?
264
-
265
- params.keys.each{ |key| params[key] = params[key].join(',') if params[key].is_a?(Array) }
266
-
267
- uri = Addressable::URI.parse(href)
268
- params = (uri.query_values || {}).merge(params)
269
-
270
- @_loaded = false unless params == uri.query_values
271
-
272
- uri.query_values = params
273
- self.href = uri.to_s
274
- end
275
-
276
134
  # Checks if this resource responds to a specific method
277
135
  #
278
136
  # @param method [String/Symbol]
279
137
  # @return [Boolean]
280
138
  def respond_to?(method)
281
- self.load
139
+ load
282
140
  meth = method.to_s
283
141
 
284
142
  return true if is_embedded?(meth)
@@ -308,20 +166,7 @@ module DeskApi
308
166
  #
309
167
  # @return [Boolean]
310
168
  def loaded?
311
- @_loaded
312
- end
313
-
314
- protected
315
-
316
- # Returns a clean base url
317
- #
318
- # @example removes the search if called from a search resource
319
- # '/api/v2/cases/search' => '/api/v2/cases'
320
- # @example removes the id if your on a specific resource
321
- # '/api/v2/cases/1' => '/api/v2/cases'
322
- # @return [String] the clean base url
323
- def clean_base_url
324
- Addressable::URI.parse(href).path.gsub(/\/(search|\d+)$/, '')
169
+ !!@_loaded
325
170
  end
326
171
 
327
172
  # Executes the request to the Desk.com API if the resource
@@ -330,7 +175,7 @@ module DeskApi
330
175
  # @param reload [Boolean] should reload the resource
331
176
  # @return [DeskApi::Resource] self
332
177
  def exec!(reload = false)
333
- return self if @_loaded and !reload
178
+ return self if loaded? and !reload
334
179
  @_definition, @_loaded = @_client.get(href).body, true
335
180
  self
336
181
  end
@@ -346,23 +191,6 @@ module DeskApi
346
191
  private
347
192
  attr_accessor :_client, :_loaded, :_changed, :_embedded, :_links, :_definition
348
193
 
349
- # Filters update actions from the params
350
- #
351
- # @see http://dev.desk.com/API/customers/#update
352
- # @param params [Hash]
353
- # @return [Hash]
354
- def filter_update_actions(params = {})
355
- params.select{ |key, _| key.to_s.include?('_action') }
356
- end
357
-
358
- # Filters the links
359
- #
360
- # @param params [Hash]
361
- # @return [Hash]
362
- def filter_links(params = {})
363
- params.select{ |key, _| key.to_s == '_links' }
364
- end
365
-
366
194
  # Checks if the given `method` is a field on the current
367
195
  # resource definition
368
196
  #
@@ -445,7 +273,7 @@ module DeskApi
445
273
  # @param block [Proc]
446
274
  # @return [Mixed]
447
275
  def method_missing(method, *args, &block)
448
- self.load
276
+ load
449
277
 
450
278
  meth = method.to_s
451
279
 
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice, this
8
+ # list of conditions and the following disclaimer.
9
+ #
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # * Neither the name of Salesforce.com nor the names of its contributors may be
15
+ # used to endorse or promote products derived from this software without
16
+ # specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ module DeskApi
30
+ class Resource
31
+ # {DeskApi::Resource::Download} is responsible for download helper methods
32
+ # like `#download`
33
+ #
34
+ # @author Thomas Stachl <tstachl@salesforce.com>
35
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
36
+ # @license BSD 3-Clause License
37
+ #
38
+ # @example download an attachment {DeskApi::Resource}
39
+ # DeskApi.cases.find(123).attachments.entries.first.download
40
+ module Download
41
+
42
+ # Download the attachment {DeskApi::Resource}
43
+ #
44
+ # @raise [NoMethodError] if self is not an attachment resource
45
+ def download
46
+ unless resource_type == 'attachment'
47
+ raise NoMethodError, "#download is only available on attachment resources"
48
+ end
49
+
50
+ Tempfile.new(file_name).tap do |f|
51
+ f.write(@_client.get(url).body)
52
+ f.rewind
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,77 @@
1
+ # Copyright (c) 2013-2016, Salesforce.com, Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice, this
8
+ # list of conditions and the following disclaimer.
9
+ #
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # * Neither the name of Salesforce.com nor the names of its contributors may be
15
+ # used to endorse or promote products derived from this software without
16
+ # specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ module DeskApi
30
+ class Resource
31
+ # {DeskApi::Resource::Pagination} is responsible for pagination helper
32
+ # methods like `#each_page` or `#all`
33
+ #
34
+ # @author Thomas Stachl <tstachl@salesforce.com>
35
+ # @copyright Copyright (c) 2013-2016 Salesforce.com
36
+ # @license BSD 3-Clause License
37
+ #
38
+ # @example search for cases {DeskApi::Resource}
39
+ # DeskApi.cases.each_page{ |page, num| do_something(page) }
40
+ module Pagination
41
+
42
+ # Paginate through all the resources on a give page {DeskApi::Resource}
43
+ #
44
+ # @raise [NoMethodError] if self is not a page resource
45
+ # @raise [ArgumentError] if no block is given
46
+ # @yield [DeskApi::Resource] the current resource
47
+ # @yield [Integer] the current page number
48
+ def all
49
+ raise ArgumentError, "Block must be given for #all" unless block_given?
50
+ each_page do |page, page_num|
51
+ page.entries.each { |resource| yield resource, page_num }
52
+ end
53
+ end
54
+
55
+ # Paginate through each page on a give page {DeskApi::Resource}
56
+ #
57
+ # @raise [NoMethodError] if self is not a page resource
58
+ # @raise [ArgumentError] if no block is given
59
+ # @yield [DeskApi::Resource] the current page resource
60
+ # @yield [Integer] the current page number
61
+ def each_page
62
+ raise ArgumentError, "Block must be given for #each_page" unless block_given?
63
+
64
+ begin
65
+ page = self.first.per_page(self.query_params['per_page'] || 1000).dup
66
+ rescue NoMethodError => err
67
+ raise NoMethodError, "#each_page and #all are only available on resources which offer pagination"
68
+ end
69
+
70
+ begin
71
+ yield page, page.page
72
+ end while page.next!
73
+ end
74
+
75
+ end
76
+ end
77
+ end