zendesk_api 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.yardopts +1 -1
  2. data/Gemfile.lock +3 -1
  3. data/Rakefile +1 -0
  4. data/Readme.md +38 -0
  5. data/lib/zendesk_api.rb +2 -3
  6. data/lib/zendesk_api/actions.rb +9 -2
  7. data/lib/zendesk_api/association.rb +28 -54
  8. data/lib/zendesk_api/client.rb +20 -5
  9. data/lib/zendesk_api/collection.rb +31 -16
  10. data/lib/zendesk_api/configuration.rb +1 -0
  11. data/lib/zendesk_api/helpers.rb +1 -0
  12. data/lib/zendesk_api/lru_cache.rb +1 -0
  13. data/lib/zendesk_api/middleware/request/etag_cache.rb +1 -0
  14. data/lib/zendesk_api/middleware/request/retry.rb +2 -0
  15. data/lib/zendesk_api/middleware/request/upload.rb +1 -0
  16. data/lib/zendesk_api/middleware/response/callback.rb +1 -0
  17. data/lib/zendesk_api/middleware/response/deflate.rb +1 -0
  18. data/lib/zendesk_api/middleware/response/gzip.rb +2 -0
  19. data/lib/zendesk_api/middleware/response/logger.rb +1 -0
  20. data/lib/zendesk_api/middleware/response/parse_iso_dates.rb +1 -0
  21. data/lib/zendesk_api/rescue.rb +2 -0
  22. data/lib/zendesk_api/resource.rb +11 -6
  23. data/lib/zendesk_api/resources.rb +319 -0
  24. data/lib/zendesk_api/sideloading.rb +1 -0
  25. data/lib/zendesk_api/track_changes.rb +3 -2
  26. data/lib/zendesk_api/trackie.rb +1 -0
  27. data/lib/zendesk_api/version.rb +1 -1
  28. data/spec/association_spec.rb +1 -1
  29. data/spec/client_spec.rb +13 -2
  30. data/spec/collection_spec.rb +7 -7
  31. data/spec/data_resource_spec.rb +53 -66
  32. data/spec/read_resource_spec.rb +1 -1
  33. data/spec/resource_spec.rb +6 -6
  34. data/spec/spec_helper.rb +1 -1
  35. data/util/resource_handler.rb +68 -0
  36. data/util/verb_handler.rb +16 -0
  37. data/zendesk_api.gemspec +3 -2
  38. metadata +27 -12
  39. data/lib/zendesk_api/resources/forum.rb +0 -51
  40. data/lib/zendesk_api/resources/misc.rb +0 -79
  41. data/lib/zendesk_api/resources/ticket.rb +0 -97
  42. data/lib/zendesk_api/resources/user.rb +0 -59
@@ -1,4 +1,5 @@
1
1
  module ZendeskAPI
2
+ # Holds the configuration options for the client and connection
2
3
  class Configuration
3
4
  # @return [String] The basic auth username.
4
5
  attr_accessor :username
@@ -1,4 +1,5 @@
1
1
  module ZendeskAPI
2
+ # @private
2
3
  module Helpers
3
4
  # From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
4
5
  def self.modulize_string(string)
@@ -1,5 +1,6 @@
1
1
  module ZendeskAPI
2
2
  # http://codesnippets.joyent.com/posts/show/12329
3
+ # @private
3
4
  class ZendeskAPI::LRUCache
4
5
  attr_accessor :size
5
6
 
@@ -5,6 +5,7 @@ module ZendeskAPI
5
5
  module Request
6
6
  # Request middleware that caches responses based on etags
7
7
  # can be removed once this is merged: https://github.com/pengwynn/faraday_middleware/pull/42
8
+ # @private
8
9
  class EtagCache < Faraday::Middleware
9
10
  def initialize(app, options = {})
10
11
  @app = app
@@ -2,8 +2,10 @@ require "faraday/middleware"
2
2
 
3
3
  module ZendeskAPI
4
4
  module Middleware
5
+ # @private
5
6
  module Request
6
7
  # Faraday middleware to handle HTTP Status 429 (rate limiting) / 503 (maintenance)
8
+ # @private
7
9
  class Retry < Faraday::Middleware
8
10
  DEFAULT_RETRY_AFTER = 10
9
11
  ERROR_CODES = [429, 503]
@@ -5,6 +5,7 @@ require 'tempfile'
5
5
  module ZendeskAPI
6
6
  module Middleware
7
7
  module Request
8
+ # @private
8
9
  class Upload < Faraday::Middleware
9
10
  def call(env)
10
11
  if env[:body]
@@ -3,6 +3,7 @@ require "faraday/response"
3
3
  module ZendeskAPI
4
4
  module Middleware
5
5
  module Response
6
+ # @private
6
7
  class Callback < Faraday::Response::Middleware
7
8
  def initialize(app, client)
8
9
  super(app)
@@ -4,6 +4,7 @@ module ZendeskAPI
4
4
  module Middleware
5
5
  module Response
6
6
  # Faraday middleware to handle content-encoding = inflate
7
+ # @private
7
8
  class Deflate < FaradayMiddleware::ResponseMiddleware
8
9
  define_parser do |body|
9
10
  Zlib::Inflate.inflate(body)
@@ -1,7 +1,9 @@
1
1
  require 'faraday_middleware/response_middleware'
2
2
 
3
3
  module ZendeskAPI
4
+ # @private
4
5
  module Middleware
6
+ # @private
5
7
  module Response
6
8
  # Faraday middleware to handle content-encoding = gzip
7
9
  class Gzip < FaradayMiddleware::ResponseMiddleware
@@ -4,6 +4,7 @@ module ZendeskAPI
4
4
  module Middleware
5
5
  module Response
6
6
  # Faraday middleware to handle logging
7
+ # @private
7
8
  class Logger < Faraday::Response::Middleware
8
9
  def initialize(app, logger = nil)
9
10
  super(app)
@@ -5,6 +5,7 @@ module ZendeskAPI
5
5
  module Middleware
6
6
  module Response
7
7
  # Parse ISO dates from response body
8
+ # @private
8
9
  class ParseIsoDates < Faraday::Response::Middleware
9
10
  def call(env)
10
11
  response = @app.call(env)
@@ -1,10 +1,12 @@
1
1
  module ZendeskAPI
2
+ # @private
2
3
  module Rescue
3
4
  def self.included(klass)
4
5
  klass.extend(Methods)
5
6
  klass.send(:include, Methods)
6
7
  end
7
8
 
9
+ # @private
8
10
  module Methods
9
11
  def log_error(e, method = false)
10
12
  if logger = (@client ? @client.config.logger : Kernel)
@@ -23,15 +23,12 @@ module ZendeskAPI
23
23
 
24
24
  alias :model_key :resource_name
25
25
 
26
- # Rails tries to load dependencies, which messes up automatic resource our own loading
27
- if method_defined?(:const_missing_without_dependencies)
28
- alias :const_missing :const_missing_without_dependencies
29
- end
30
-
26
+ # @private
31
27
  def only_send_unnested_params
32
28
  @unnested_params = true
33
29
  end
34
30
 
31
+ # @private
35
32
  def unnested_params
36
33
  @unnested_params ||= false
37
34
  end
@@ -50,7 +47,10 @@ module ZendeskAPI
50
47
  @association = attributes.delete(:association) || Association.new(:class => self.class)
51
48
  @client = client
52
49
  @attributes = ZendeskAPI::Trackie.new(attributes)
53
- ZendeskAPI::Client.check_deprecated_namespace_usage @attributes, self.class.singular_resource_name
50
+
51
+ if self.class.associations.none? {|a| a[:name] == self.class.singular_resource_name}
52
+ ZendeskAPI::Client.check_deprecated_namespace_usage @attributes, self.class.singular_resource_name
53
+ end
54
54
 
55
55
  @attributes.clear_changes unless new_record?
56
56
  end
@@ -72,6 +72,7 @@ module ZendeskAPI
72
72
  id.nil?
73
73
  end
74
74
 
75
+ # @private
75
76
  def loaded_associations
76
77
  self.class.associations.select do |association|
77
78
  loaded = @attributes.method_missing(association[:name])
@@ -84,15 +85,18 @@ module ZendeskAPI
84
85
  @association.generate_path(self, *args)
85
86
  end
86
87
 
88
+ # Passes #to_json to the underlying attributes hash
87
89
  def to_json(*args)
88
90
  method_missing(:to_json, *args)
89
91
  end
90
92
 
93
+ # @private
91
94
  def to_s
92
95
  "#{self.class.singular_resource_name}: #{attributes.inspect}"
93
96
  end
94
97
  alias :inspect :to_s
95
98
 
99
+ # Compares resources by class and id. If id is nil, then by object_id
96
100
  def ==(other)
97
101
  warn "Trying to compare #{other.class} to a Resource" if other && !other.is_a?(Data)
98
102
  other.is_a?(self.class) && ((other.id && other.id == id) || (other.object_id == self.object_id))
@@ -100,6 +104,7 @@ module ZendeskAPI
100
104
  alias :eql :==
101
105
  alias :hash :id
102
106
 
107
+ # @private
103
108
  def inspect
104
109
  "#<#{self.class.name} #{@attributes.to_hash.inspect}>"
105
110
  end
@@ -0,0 +1,319 @@
1
+ module ZendeskAPI
2
+ # @internal The following are redefined later, but needed by some circular resources (e.g. Ticket -> User, User -> Ticket)
3
+
4
+
5
+ class Ticket < Resource; end
6
+ class Forum < Resource; end
7
+ class User < Resource; end
8
+ class Category < Resource; end
9
+
10
+ # @internal Begin actual Resource definitions
11
+
12
+ class Locale < ReadResource; end
13
+ class CRMData < DataResource; end
14
+ class CRMDataStatus < DataResource; end
15
+ class CustomRole < DataResource; end
16
+ class Role < DataResource; end
17
+ class Topic < Resource; end
18
+ class Bookmark < Resource; end
19
+ class Ability < DataResource; end
20
+ class Macro < Resource; end
21
+ class Group < Resource; end
22
+ class Trigger < ReadResource; end
23
+ class SharingAgreement < ReadResource; end
24
+ class JobStatus < ReadResource; end
25
+
26
+ class Attachment < Data
27
+ def initialize(client, attributes)
28
+ if attributes.is_a?(Hash)
29
+ super
30
+ else
31
+ super(client, :file => attributes)
32
+ end
33
+ end
34
+
35
+ def save
36
+ upload = Upload.create!(@client, attributes)
37
+ self.token = upload.token
38
+ end
39
+
40
+ def to_param
41
+ token
42
+ end
43
+ end
44
+
45
+ class Upload < Data
46
+ include Create
47
+
48
+ only_send_unnested_params
49
+
50
+ has_many Attachment
51
+ end
52
+
53
+ class MobileDevice < Resource
54
+ # Clears this devices' badge
55
+ put :clear_badge
56
+ end
57
+
58
+ class Organization < Resource
59
+ has Ability, :inline => true
60
+ has Group
61
+
62
+ has_many Ticket
63
+ has_many User
64
+ end
65
+
66
+ class ForumSubscription < Resource
67
+ only_send_unnested_params
68
+ has Forum
69
+ has User
70
+ end
71
+
72
+ class Forum < Resource
73
+ has Category
74
+ has Organization
75
+ has Locale
76
+
77
+ has_many Topic
78
+ has_many :subscriptions, :class => ForumSubscription
79
+ end
80
+
81
+ class Category < Resource
82
+ has_many Forum
83
+ end
84
+
85
+ class TopicSubscription < Resource
86
+ only_send_unnested_params
87
+ has Topic
88
+ has User
89
+ end
90
+
91
+ class Topic < Resource
92
+ class TopicComment < Resource
93
+ has Topic
94
+ has User
95
+ has_many Attachment
96
+ end
97
+
98
+ class TopicVote < SingularResource
99
+ only_send_unnested_params
100
+ has Topic
101
+ has User
102
+ end
103
+
104
+ has Forum
105
+ has_many :comments, :class => TopicComment
106
+ has_many :subscriptions, :class => TopicSubscription
107
+ has :vote, :class => TopicVote
108
+
109
+ def votes(opts = {})
110
+ return @votes if @votes && !opts[:reload]
111
+
112
+ association = ZendeskAPI::Association.new(:class => TopicVote, :parent => self, :path => 'votes')
113
+ @votes = ZendeskAPI::Collection.new(@client, TopicVote, opts.merge(:association => association))
114
+ end
115
+ end
116
+
117
+ class Activity < Resource
118
+ has User
119
+ has :actor, :class => User
120
+ end
121
+
122
+ class Setting < DataResource
123
+ attr_reader :on
124
+
125
+ def initialize(client, attributes = {})
126
+ @on = attributes.first
127
+ super(client, attributes[1])
128
+ end
129
+ end
130
+
131
+ class SatisfactionRating < ReadResource
132
+ has :assignee, :class => User
133
+ has :requester, :class => User
134
+ has Ticket
135
+ has Group
136
+ end
137
+
138
+ class Search
139
+ class Result < Data; end
140
+
141
+ # Creates a search collection
142
+ def self.search(client, options = {})
143
+ unless (%w{query external_id} & options.keys.map(&:to_s)).any?
144
+ warn "you have not specified a query for this search"
145
+ end
146
+
147
+ ZendeskAPI::Collection.new(client, self, options)
148
+ end
149
+
150
+ # Creates the correct resource class from the result_type passed in
151
+ def self.new(client, attributes)
152
+ result_type = attributes["result_type"]
153
+
154
+ if result_type
155
+ result_type = ZendeskAPI::Helpers.modulize_string(result_type)
156
+ klass = ZendeskAPI.const_get(result_type) rescue nil
157
+ end
158
+
159
+ (klass || Result).new(client, attributes)
160
+ end
161
+
162
+ def self.resource_name
163
+ "search"
164
+ end
165
+
166
+ def self.model_key
167
+ "results"
168
+ end
169
+ end
170
+
171
+ class Request < Resource
172
+ class Comment < ReadResource
173
+ has_many Attachment, :inline => true
174
+ end
175
+
176
+ has_many Comment
177
+ has Organization
178
+ end
179
+
180
+ class TicketField < Resource; end
181
+
182
+ class TicketComment < Data
183
+ include Save
184
+
185
+ has_many :uploads, :class => Attachment, :inline => true
186
+ has :author, :class => User
187
+
188
+ def save
189
+ save_associations
190
+ true
191
+ end
192
+
193
+ alias :save! :save
194
+ end
195
+
196
+ class TicketMetric < ReadResource; end
197
+
198
+ class Ticket < Resource
199
+ class Audit < DataResource; end
200
+
201
+ has :requester, :class => User, :inline => :create
202
+ has :submitter, :class => User
203
+ has :assignee, :class => User
204
+ has_many :collaborators, :class => User
205
+ has_many Audit
206
+ has :metrics, :class => TicketMetric
207
+ has Group
208
+ has :forum_topic, :class => Topic
209
+ has Organization
210
+
211
+ has :comment, :class => TicketComment, :inline => true
212
+ has :last_comment, :class => TicketComment, :inline => true
213
+
214
+ # Gets a incremental export of tickets from the start_time until now.
215
+ # @param [Client] client The {Client} object to be used
216
+ # @param [Integer] start_time The start_time parameter
217
+ # @return [Collection] Collection of {Ticket}
218
+ def self.incremental_export(client, start_time)
219
+ ZendeskAPI::Collection.new(client, self, :path => "exports/tickets?start_time=#{start_time.to_i}")
220
+ end
221
+
222
+ # Imports a ticket through the imports/tickets endpoint
223
+ # @param [Client] client The {Client} object to be used
224
+ # @param [Hash] attributes The attributes to create.
225
+ # @return [Ticket] Created object or nil
226
+ def self.import(client, attributes)
227
+ ticket = new(client, attributes)
228
+ return unless ticket.save(:path => "imports/tickets")
229
+ ticket
230
+ end
231
+ end
232
+
233
+ class SuspendedTicket < ReadResource
234
+ include Destroy
235
+
236
+ # Recovers this suspended ticket to an actual ticket
237
+ put :recover
238
+ end
239
+
240
+ class ViewRow < DataResource
241
+ has Ticket
242
+
243
+ # @internal Optional columns
244
+
245
+ has Group
246
+ has :assignee, :class => User
247
+ has :requester, :class => User
248
+ has :submitter, :class => User
249
+ has Organization
250
+
251
+ def self.model_key
252
+ "rows"
253
+ end
254
+ end
255
+
256
+ class ViewExecution < Data
257
+ has_many :custom_fields, :class => TicketField
258
+ end
259
+
260
+ class View < ReadResource
261
+ has_many :rows, :class => ViewRow, :path => "execute"
262
+ has :execution, :class => ViewExecution
263
+
264
+ def self.preview(client, options = {})
265
+ Collection.new(client, ViewRow, options.merge(:path => "views/preview", :verb => :post))
266
+ end
267
+ end
268
+
269
+
270
+ class GroupMembership < Resource
271
+ has User
272
+ has Group
273
+ end
274
+
275
+ class User < Resource
276
+ class Identity < Resource
277
+ # Makes this identity the primary one bumping all other identities down one
278
+ put :make_primary
279
+
280
+ # Verifies this identity
281
+ put :verify
282
+
283
+ # Requests verification for this identity
284
+ put :request_verification
285
+ end
286
+
287
+ def initialize(*)
288
+ super
289
+
290
+ # Needed for side-loading to work
291
+ self.role_id = role.id if self.key?(:role)
292
+ end
293
+
294
+ has Organization
295
+
296
+ has CustomRole, :include => :roles
297
+ has Role, :inline => true, :include_key => :name
298
+ has Ability, :inline => true
299
+
300
+ has_many Identity
301
+
302
+ has_many Request
303
+ has_many :requested_tickets, :class => Ticket, :path => 'tickets/requested'
304
+ has_many :ccd_tickets, :class => Ticket, :path => 'tickets/ccd'
305
+
306
+ has_many Group
307
+ has_many GroupMembership
308
+ has_many Topic
309
+
310
+ has_many ForumSubscription
311
+ has_many TopicSubscription
312
+ has_many :topic_comments, :class => Topic::TopicComment
313
+ has_many :topic_votes, :class => Topic::TopicVote
314
+
315
+ has CRMData
316
+ has CRMDataStatus, :path => 'crm_data/status'
317
+ end
318
+ end
319
+