zendesk_api 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +3 -3
- data/Readme.md +0 -5
- data/lib/zendesk_api.rb +0 -3
- data/lib/zendesk_api/actions.rb +10 -2
- data/lib/zendesk_api/association.rb +78 -7
- data/lib/zendesk_api/client.rb +4 -8
- data/lib/zendesk_api/collection.rb +29 -9
- data/lib/zendesk_api/core_ext/inflection.rb +0 -10
- data/lib/zendesk_api/helpers.rb +23 -0
- data/lib/zendesk_api/middleware/response/logger.rb +40 -0
- data/lib/zendesk_api/resource.rb +10 -2
- data/lib/zendesk_api/resources/misc.rb +14 -1
- data/lib/zendesk_api/resources/ticket.rb +2 -0
- data/lib/zendesk_api/resources/user.rb +14 -1
- data/lib/zendesk_api/sideloading.rb +50 -0
- data/lib/zendesk_api/version.rb +1 -1
- data/live/group_spec.rb +0 -1
- data/live/ticket_spec.rb +2 -2
- data/spec/client_spec.rb +4 -17
- data/spec/collection_spec.rb +143 -0
- data/spec/{string_spec.rb → inflection_spec.rb} +1 -1
- data/spec/read_resource_spec.rb +23 -5
- data/spec/search_spec.rb +23 -0
- data/spec/spec_helper.rb +0 -1
- metadata +9 -9
- data/lib/zendesk_api/core_ext/modulize.rb +0 -10
- data/lib/zendesk_api/core_ext/snakecase.rb +0 -12
- data/lib/zendesk_api/resources/playlist.rb +0 -64
- data/spec/playlist_spec.rb +0 -95
data/Gemfile.lock
CHANGED
@@ -7,7 +7,7 @@ GIT
|
|
7
7
|
PATH
|
8
8
|
remote: .
|
9
9
|
specs:
|
10
|
-
zendesk_api (0.1.
|
10
|
+
zendesk_api (0.1.6)
|
11
11
|
faraday (>= 0.8.0)
|
12
12
|
faraday_middleware (>= 0.8.7)
|
13
13
|
hashie
|
@@ -39,13 +39,13 @@ GEM
|
|
39
39
|
rspec-core (2.11.1)
|
40
40
|
rspec-expectations (2.11.3)
|
41
41
|
diff-lcs (~> 1.1.3)
|
42
|
-
rspec-mocks (2.11.
|
42
|
+
rspec-mocks (2.11.3)
|
43
43
|
simplecov (0.6.4)
|
44
44
|
multi_json (~> 1.0)
|
45
45
|
simplecov-html (~> 0.5.3)
|
46
46
|
simplecov-html (0.5.3)
|
47
47
|
vcr (2.2.5)
|
48
|
-
webmock (1.8.
|
48
|
+
webmock (1.8.11)
|
49
49
|
addressable (>= 2.2.7)
|
50
50
|
crack (>= 0.1.7)
|
51
51
|
yard (0.8.2.1)
|
data/Readme.md
CHANGED
@@ -178,11 +178,6 @@ ticket.comment.uploads << File.new("img.jpg")
|
|
178
178
|
ticket.save
|
179
179
|
```
|
180
180
|
|
181
|
-
## TODO
|
182
|
-
|
183
|
-
* Search class detection
|
184
|
-
* Live Testing
|
185
|
-
|
186
181
|
## Note on Patches/Pull Requests
|
187
182
|
1. Fork the project.
|
188
183
|
2. Make your feature addition or bug fix.
|
data/lib/zendesk_api.rb
CHANGED
data/lib/zendesk_api/actions.rb
CHANGED
@@ -56,7 +56,6 @@ module ZendeskAPI
|
|
56
56
|
self.send("#{association_name}=", association) # set id/ids columns
|
57
57
|
end
|
58
58
|
|
59
|
-
|
60
59
|
if association_data[:inline] == true || inline_creation
|
61
60
|
attributes[association_name] = (association.is_a?(Collection) ? association.map(&:to_param) : association.to_param)
|
62
61
|
end
|
@@ -67,6 +66,10 @@ module ZendeskAPI
|
|
67
66
|
module Read
|
68
67
|
include Rescue
|
69
68
|
|
69
|
+
def self.extended(klass)
|
70
|
+
klass.send(:include, ZendeskAPI::Sideloading)
|
71
|
+
end
|
72
|
+
|
70
73
|
# Finds a resource by an id and any options passed in.
|
71
74
|
# A custom path to search at can be passed into opts. It defaults to the {DataResource.resource_name} of the class.
|
72
75
|
# @param [Client] client The {Client} object to be used
|
@@ -77,11 +80,16 @@ module ZendeskAPI
|
|
77
80
|
raise ArgumentError, "No :id given" unless options[:id] || options["id"] || ancestors.include?(SingularResource)
|
78
81
|
association = options.delete(:association) || Association.new(:class => self)
|
79
82
|
|
83
|
+
includes = Array(options[:include])
|
84
|
+
options[:include] = includes.join(",") if includes.any?
|
85
|
+
|
80
86
|
response = client.connection.get(association.generate_path(options)) do |req|
|
81
87
|
req.params = options
|
82
88
|
end
|
83
89
|
|
84
|
-
new(client, response.body[singular_resource_name])
|
90
|
+
new(client, response.body[singular_resource_name]).tap do |resource|
|
91
|
+
resource.set_includes(resource, includes, response.body)
|
92
|
+
end
|
85
93
|
end
|
86
94
|
|
87
95
|
rescue_client_error :find
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'zendesk_api/helpers'
|
2
|
+
|
1
3
|
module ZendeskAPI
|
2
4
|
# Represents an association between two resources
|
3
5
|
class Association
|
@@ -48,8 +50,56 @@ module ZendeskAPI
|
|
48
50
|
namespace.join("/")
|
49
51
|
end
|
50
52
|
|
53
|
+
def side_load(resources, side_loads)
|
54
|
+
key = "#{options.name}_id"
|
55
|
+
plural_key = "#{Inflection.singular options.name.to_s}_ids"
|
56
|
+
|
57
|
+
resources.each do |resource|
|
58
|
+
if resource.key?(plural_key) # Grab associations from child_ids field on resource
|
59
|
+
ids = resource.send(plural_key)
|
60
|
+
|
61
|
+
resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
|
62
|
+
ids.include?(side_load[options.include_key])
|
63
|
+
}))
|
64
|
+
elsif resource.key?(key) || options.singular
|
65
|
+
# Either grab association from child_id field on resource or parent_id on child resource
|
66
|
+
if resource.key?(key)
|
67
|
+
id = resource.send(key)
|
68
|
+
key = options.include_key
|
69
|
+
else
|
70
|
+
id = resource.id
|
71
|
+
key = "#{resource.class.singular_resource_name}_id"
|
72
|
+
end
|
73
|
+
|
74
|
+
next unless id
|
75
|
+
|
76
|
+
side_load = side_loads.detect do |side_load|
|
77
|
+
id == side_load[key]
|
78
|
+
end
|
79
|
+
|
80
|
+
resource.send("#{options.name}=", side_load) if side_load
|
81
|
+
else # Grab associations from parent_id field from multiple child resources
|
82
|
+
key = "#{resource.class.singular_resource_name}_id"
|
83
|
+
|
84
|
+
resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
|
85
|
+
side_load[key] == resource.id
|
86
|
+
}))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
51
91
|
private
|
52
92
|
|
93
|
+
def _side_load(resource, side_loads)
|
94
|
+
side_loads.map! do |side_load|
|
95
|
+
resource.send(:wrap_resource, side_load, options[:class], options)
|
96
|
+
end
|
97
|
+
|
98
|
+
ZendeskAPI::Collection.new(resource.client, options[:class]).tap do |collection|
|
99
|
+
collection.replace(side_loads)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
53
103
|
def build_parent_namespace(parent_class, instance, options, original_options)
|
54
104
|
return unless association_on_parent = parent_class.associations.detect {|a| a[:class] == @options[:class] }
|
55
105
|
[
|
@@ -110,7 +160,17 @@ module ZendeskAPI
|
|
110
160
|
include Rescue
|
111
161
|
|
112
162
|
def associations
|
113
|
-
@
|
163
|
+
@associations ||= []
|
164
|
+
end
|
165
|
+
|
166
|
+
def associated_with(name)
|
167
|
+
associations.inject([]) do |associated_with, association|
|
168
|
+
if association[:include] == name.to_s
|
169
|
+
associated_with.push(Association.new(association))
|
170
|
+
end
|
171
|
+
|
172
|
+
associated_with
|
173
|
+
end
|
114
174
|
end
|
115
175
|
|
116
176
|
# Represents a parent-to-child association between resources. Options to pass in are: class, path.
|
@@ -118,13 +178,19 @@ module ZendeskAPI
|
|
118
178
|
# @param [Hash] opts The options to pass to the method definition.
|
119
179
|
def has(resource_name, class_level_options = {})
|
120
180
|
klass = get_class(class_level_options.delete(:class)) || get_class(resource_name)
|
181
|
+
|
121
182
|
class_level_association = {
|
122
183
|
:class => klass,
|
123
184
|
:name => resource_name,
|
124
185
|
:inline => class_level_options.delete(:inline),
|
125
|
-
:path => class_level_options.delete(:path)
|
186
|
+
:path => class_level_options.delete(:path),
|
187
|
+
:include => (class_level_options.delete(:include) || klass.resource_name).to_s,
|
188
|
+
:include_key => (class_level_options.delete(:include_key) || :id).to_s,
|
189
|
+
:singular => true
|
126
190
|
}
|
191
|
+
|
127
192
|
associations << class_level_association
|
193
|
+
|
128
194
|
id_column = "#{resource_name}_id"
|
129
195
|
|
130
196
|
define_method "#{resource_name}_used?" do
|
@@ -166,13 +232,18 @@ module ZendeskAPI
|
|
166
232
|
# @param [Symbol] resource The underlying resource name
|
167
233
|
# @param [Hash] opts The options to pass to the method definition.
|
168
234
|
def has_many(resource_name, class_level_opts = {})
|
169
|
-
klass = get_class(class_level_opts.delete(:class)) || get_class(resource_name.to_s
|
235
|
+
klass = get_class(class_level_opts.delete(:class)) || get_class(Inflection.singular(resource_name.to_s))
|
236
|
+
|
170
237
|
class_level_association = {
|
171
238
|
:class => klass,
|
172
239
|
:name => resource_name,
|
173
240
|
:inline => class_level_opts.delete(:inline),
|
174
|
-
:path => class_level_opts.delete(:path)
|
241
|
+
:path => class_level_opts.delete(:path),
|
242
|
+
:include => (class_level_opts.delete(:include) || klass.resource_name).to_s,
|
243
|
+
:include_key => (class_level_opts.delete(:include_key) || :id).to_s,
|
244
|
+
:singular => false
|
175
245
|
}
|
246
|
+
|
176
247
|
associations << class_level_association
|
177
248
|
|
178
249
|
id_column = "#{resource_name}_ids"
|
@@ -190,7 +261,7 @@ module ZendeskAPI
|
|
190
261
|
|
191
262
|
# find and cache association
|
192
263
|
instance_association = Association.new(class_level_association.merge(:parent => self))
|
193
|
-
singular_resource_name = resource_name.to_s
|
264
|
+
singular_resource_name = Inflection.singular(resource_name.to_s)
|
194
265
|
|
195
266
|
resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
|
196
267
|
ids.map do |id|
|
@@ -227,7 +298,7 @@ module ZendeskAPI
|
|
227
298
|
# reopened under a different superclass, an error will be thrown
|
228
299
|
def get_class(resource)
|
229
300
|
return false if resource.nil?
|
230
|
-
res = resource.to_s
|
301
|
+
res = ZendeskAPI::Helpers.modulize_string(resource.to_s)
|
231
302
|
|
232
303
|
begin
|
233
304
|
const_get(res)
|
@@ -249,7 +320,7 @@ module ZendeskAPI
|
|
249
320
|
# reopened under a different superclass, an error will be thrown
|
250
321
|
def get_class(resource)
|
251
322
|
return false if resource.nil?
|
252
|
-
res = resource.to_s.
|
323
|
+
res = ZendeskAPI::Helpers.modulize_string(resource.to_s).split("::")
|
253
324
|
|
254
325
|
begin
|
255
326
|
res[1..-1].inject(ZendeskAPI.const_get(res[0])) do |iter, k|
|
data/lib/zendesk_api/client.rb
CHANGED
@@ -3,6 +3,7 @@ require 'faraday_middleware'
|
|
3
3
|
|
4
4
|
require 'zendesk_api/version'
|
5
5
|
require 'zendesk_api/rescue'
|
6
|
+
require 'zendesk_api/sideloading'
|
6
7
|
require 'zendesk_api/configuration'
|
7
8
|
require 'zendesk_api/collection'
|
8
9
|
require 'zendesk_api/lru_cache'
|
@@ -13,6 +14,7 @@ require 'zendesk_api/middleware/response/callback'
|
|
13
14
|
require 'zendesk_api/middleware/response/deflate'
|
14
15
|
require 'zendesk_api/middleware/response/gzip'
|
15
16
|
require 'zendesk_api/middleware/response/parse_iso_dates'
|
17
|
+
require 'zendesk_api/middleware/response/logger'
|
16
18
|
|
17
19
|
module ZendeskAPI
|
18
20
|
class Client
|
@@ -30,13 +32,7 @@ module ZendeskAPI
|
|
30
32
|
method = method.to_s
|
31
33
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
32
34
|
return instance_variable_get("@#{method}") if !options.delete(:reload) && instance_variable_defined?("@#{method}")
|
33
|
-
instance_variable_set("@#{method}", ZendeskAPI::Collection.new(self, ZendeskAPI.get_class(
|
34
|
-
end
|
35
|
-
|
36
|
-
# Plays a view playlist.
|
37
|
-
# @param [String/Number] id View id or 'incoming'
|
38
|
-
def play(id)
|
39
|
-
ZendeskAPI::Playlist.new(self, id)
|
35
|
+
instance_variable_set("@#{method}", ZendeskAPI::Collection.new(self, ZendeskAPI.get_class(Inflection.singular(method)), options))
|
40
36
|
end
|
41
37
|
|
42
38
|
# Returns the current user (aka me)
|
@@ -135,7 +131,7 @@ module ZendeskAPI
|
|
135
131
|
builder.use Faraday::Request::BasicAuthentication, config.username, config.password
|
136
132
|
builder.use Faraday::Response::RaiseError
|
137
133
|
builder.use ZendeskAPI::Middleware::Response::Callback, self
|
138
|
-
builder.use
|
134
|
+
builder.use ZendeskAPI::Middleware::Response::Logger, config.logger if config.logger
|
139
135
|
builder.use ZendeskAPI::Middleware::Response::ParseIsoDates
|
140
136
|
builder.response :json, :content_type => 'application/json'
|
141
137
|
builder.use ZendeskAPI::Middleware::Response::Gzip
|
@@ -2,19 +2,23 @@ require 'zendesk_api/resource'
|
|
2
2
|
require 'zendesk_api/resources/misc'
|
3
3
|
require 'zendesk_api/resources/ticket'
|
4
4
|
require 'zendesk_api/resources/user'
|
5
|
-
require 'zendesk_api/resources/playlist'
|
6
5
|
|
7
6
|
module ZendeskAPI
|
8
7
|
# Represents a collection of resources. Lazily loaded, resources aren't
|
9
8
|
# actually fetched until explicitly needed (e.g. #each, {#fetch}).
|
10
9
|
class Collection
|
11
|
-
|
10
|
+
include ZendeskAPI::Sideloading
|
11
|
+
|
12
|
+
SPECIALLY_JOINED_PARAMS = [:ids, :only]
|
12
13
|
|
13
14
|
include Rescue
|
14
15
|
|
15
16
|
# @return [ZendeskAPI::Association] The class association
|
16
17
|
attr_reader :association
|
17
18
|
|
19
|
+
# @return [Faraday::Response] The last response
|
20
|
+
attr_reader :response
|
21
|
+
|
18
22
|
# Creates a new Collection instance. Does not fetch resources.
|
19
23
|
# Additional options are: verb (default: GET), path (default: resource param), page, per_page.
|
20
24
|
# @param [Client] client The {Client} to use.
|
@@ -41,6 +45,7 @@ module ZendeskAPI
|
|
41
45
|
@collection_path ||= [@resource]
|
42
46
|
@resource_class = resource
|
43
47
|
@fetchable = true
|
48
|
+
@includes = Array(@options.delete(:include))
|
44
49
|
|
45
50
|
# Used for Attachments, TicketComment
|
46
51
|
if @resource_class.superclass == ZendeskAPI::Data
|
@@ -112,6 +117,10 @@ module ZendeskAPI
|
|
112
117
|
self
|
113
118
|
end
|
114
119
|
|
120
|
+
def include(*sideloads)
|
121
|
+
self.tap { @includes.concat(sideloads.map(&:to_s)) }
|
122
|
+
end
|
123
|
+
|
115
124
|
def <<(item)
|
116
125
|
fetch
|
117
126
|
if item.is_a?(Resource)
|
@@ -134,6 +143,7 @@ module ZendeskAPI
|
|
134
143
|
# @param [Boolean] reload Whether to disregard cache
|
135
144
|
def fetch(reload = false)
|
136
145
|
return @resources if @resources && (!@fetchable || !reload)
|
146
|
+
|
137
147
|
if association && association.options.parent && association.options.parent.new_record?
|
138
148
|
return @resources = []
|
139
149
|
end
|
@@ -145,9 +155,11 @@ module ZendeskAPI
|
|
145
155
|
path = self.path
|
146
156
|
end
|
147
157
|
|
148
|
-
response = @client.connection.send(@verb || "get", path) do |req|
|
158
|
+
@response = @client.connection.send(@verb || "get", path) do |req|
|
149
159
|
opts = @options.delete_if {|k, v| v.nil?}
|
150
160
|
|
161
|
+
req.params.merge!(:include => @includes.join(",")) if @includes.any?
|
162
|
+
|
151
163
|
if %w{put post}.include?(@verb.to_s)
|
152
164
|
req.body = opts
|
153
165
|
else
|
@@ -155,21 +167,29 @@ module ZendeskAPI
|
|
155
167
|
end
|
156
168
|
end
|
157
169
|
|
158
|
-
|
159
|
-
|
170
|
+
body = @response.body.dup
|
171
|
+
|
172
|
+
results = body.delete(@resource_class.model_key) || body.delete("results")
|
173
|
+
@resources = results.map {|res| @resource_class.new(@client, res)}
|
160
174
|
|
161
|
-
|
162
|
-
@
|
175
|
+
set_page_and_count(body)
|
176
|
+
set_includes(@resources, @includes, body)
|
177
|
+
|
178
|
+
@resources
|
179
|
+
end
|
180
|
+
|
181
|
+
def set_page_and_count(body)
|
182
|
+
@count = (body["count"] || @resources.size).to_i
|
183
|
+
@next_page, @prev_page = body["next_page"], body["previous_page"]
|
163
184
|
|
164
185
|
if @next_page =~ /page=(\d+)/
|
165
186
|
@options["page"] = $1.to_i - 1
|
166
187
|
elsif @prev_page =~ /page=(\d+)/
|
167
188
|
@options["page"] = $1.to_i + 1
|
168
189
|
end
|
169
|
-
|
170
|
-
@resources
|
171
190
|
end
|
172
191
|
|
192
|
+
|
173
193
|
rescue_client_error :fetch, :with => lambda { Array.new }
|
174
194
|
|
175
195
|
# Alias for fetch(false)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
module Helpers
|
3
|
+
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
|
4
|
+
def self.modulize_string(string)
|
5
|
+
#gsub('__','/'). # why was this ever here?
|
6
|
+
string.gsub(/__(.?)/){ "::#{$1.upcase}" }.
|
7
|
+
gsub(/\/(.?)/){ "::#{$1.upcase}" }.
|
8
|
+
gsub(/(?:_+|-+)([a-z])/){ $1.upcase }.
|
9
|
+
gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
|
10
|
+
end
|
11
|
+
|
12
|
+
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb
|
13
|
+
def self.snakecase_string(string)
|
14
|
+
#gsub(/::/, '/').
|
15
|
+
string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
16
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
17
|
+
tr('-', '_').
|
18
|
+
gsub(/\s/, '_').
|
19
|
+
gsub(/__+/, '_').
|
20
|
+
downcase
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'faraday_middleware/response_middleware'
|
2
|
+
|
3
|
+
module ZendeskAPI
|
4
|
+
module Middleware
|
5
|
+
module Response
|
6
|
+
# Faraday middleware to handle logging
|
7
|
+
class Logger < Faraday::Response::Middleware
|
8
|
+
def initialize(app, logger = nil)
|
9
|
+
super(app)
|
10
|
+
@logger = logger || begin
|
11
|
+
require 'logger'
|
12
|
+
::Logger.new(STDOUT)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@logger.info "#{env[:method]} #{env[:url].to_s}"
|
18
|
+
@logger.debug dump_debug(env, :request_headers)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_complete(env)
|
23
|
+
@logger.info("Status #{env[:status].to_s}")
|
24
|
+
@logger.debug dump_debug(env, :response_headers)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def dump_debug(env, headers_key)
|
30
|
+
info = env[headers_key].map { |k, v| " #{k}: #{v.inspect}" }.join("\n")
|
31
|
+
unless env[:body].nil?
|
32
|
+
info.concat("\n")
|
33
|
+
info.concat(env[:body].inspect)
|
34
|
+
end
|
35
|
+
info
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/zendesk_api/resource.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'zendesk_api/helpers'
|
1
2
|
require 'zendesk_api/trackie'
|
2
3
|
require 'zendesk_api/actions'
|
3
4
|
require 'zendesk_api/association'
|
@@ -12,12 +13,12 @@ module ZendeskAPI
|
|
12
13
|
class << self
|
13
14
|
# The singular resource name taken from the class name (e.g. ZendeskAPI::Ticket -> ticket)
|
14
15
|
def singular_resource_name
|
15
|
-
@singular_resource_name ||= to_s.split("::").last
|
16
|
+
@singular_resource_name ||= ZendeskAPI::Helpers.snakecase_string(to_s.split("::").last)
|
16
17
|
end
|
17
18
|
|
18
19
|
# The resource name taken from the class name (e.g. ZendeskAPI::Ticket -> tickets)
|
19
20
|
def resource_name
|
20
|
-
@resource_name ||=
|
21
|
+
@resource_name ||= Inflection.plural(singular_resource_name)
|
21
22
|
end
|
22
23
|
|
23
24
|
alias :model_key :resource_name
|
@@ -71,6 +72,13 @@ module ZendeskAPI
|
|
71
72
|
id.nil?
|
72
73
|
end
|
73
74
|
|
75
|
+
def loaded_associations
|
76
|
+
self.class.associations.select do |association|
|
77
|
+
loaded = @attributes.method_missing(association[:name])
|
78
|
+
loaded && !(loaded.respond_to?(:empty?) && loaded.empty?)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
74
82
|
# Returns the path to the resource
|
75
83
|
def path(*args)
|
76
84
|
@association.generate_path(self, *args)
|
@@ -54,7 +54,20 @@ module ZendeskAPI
|
|
54
54
|
class Bookmark < Resource; end
|
55
55
|
class Macro < DataResource; end
|
56
56
|
|
57
|
-
|
57
|
+
module Search
|
58
|
+
class Result < Data; end
|
59
|
+
|
60
|
+
def self.new(client, attributes)
|
61
|
+
result_type = attributes["result_type"]
|
62
|
+
|
63
|
+
if result_type
|
64
|
+
result_type = ZendeskAPI::Helpers.modulize_string(result_type)
|
65
|
+
klass = ZendeskAPI.const_get(result_type) rescue nil
|
66
|
+
end
|
67
|
+
|
68
|
+
(klass || Result).new(client, attributes)
|
69
|
+
end
|
70
|
+
|
58
71
|
def self.resource_name
|
59
72
|
"search"
|
60
73
|
end
|
@@ -14,6 +14,7 @@ module ZendeskAPI
|
|
14
14
|
include Save
|
15
15
|
|
16
16
|
has_many :uploads, :class => :attachment, :inline => true
|
17
|
+
has :author, :class => :user
|
17
18
|
|
18
19
|
def save
|
19
20
|
save_associations
|
@@ -40,6 +41,7 @@ module ZendeskAPI
|
|
40
41
|
has :organization
|
41
42
|
|
42
43
|
has :comment, :class => :ticket_comment, :inline => true
|
44
|
+
has :last_comment, :class => :ticket_comment, :inline => true
|
43
45
|
|
44
46
|
# Gets a incremental export of tickets from the start_time until now.
|
45
47
|
# @param [Client] client The {Client} object to be used
|
@@ -17,8 +17,19 @@ module ZendeskAPI
|
|
17
17
|
put :request_verification
|
18
18
|
end
|
19
19
|
|
20
|
+
def initialize(*)
|
21
|
+
super
|
22
|
+
|
23
|
+
# Needed for side-loading to work
|
24
|
+
self.role_id = role.id if self.key?(:role)
|
25
|
+
end
|
26
|
+
|
20
27
|
has :organization
|
21
|
-
|
28
|
+
|
29
|
+
has :custom_role, :include => :roles
|
30
|
+
has :role, :inline => true, :include_key => :name
|
31
|
+
has :ability, :inline => true
|
32
|
+
|
22
33
|
has_many :identities
|
23
34
|
|
24
35
|
has_many :requests
|
@@ -39,7 +50,9 @@ module ZendeskAPI
|
|
39
50
|
end
|
40
51
|
|
41
52
|
class Organization < Resource
|
53
|
+
has :ability, :inline => true
|
42
54
|
has :group
|
55
|
+
|
43
56
|
has_many :tickets
|
44
57
|
has_many :users
|
45
58
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ZendeskAPI
|
2
|
+
module Sideloading
|
3
|
+
def self.included(klass)
|
4
|
+
klass.send(:attr_reader, :included)
|
5
|
+
end
|
6
|
+
|
7
|
+
def set_includes(resource_or_resources, includes, body)
|
8
|
+
@included = {}
|
9
|
+
|
10
|
+
includes.each do |side_load|
|
11
|
+
unless body.key?(side_load.to_s)
|
12
|
+
@client.config.logger.warn "Missing #{side_load} key in response -- cannot side load"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
resources = [resource_or_resources].flatten.compact
|
17
|
+
resource_class = resources.first.class
|
18
|
+
|
19
|
+
return if resources.empty?
|
20
|
+
|
21
|
+
body.keys.each do |name|
|
22
|
+
@included[name] = body[name]
|
23
|
+
_side_load(name, resource_class, resources)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Traverses the resource looking for associations
|
31
|
+
# then descends into those associations and checks for applicable
|
32
|
+
# resources to side load
|
33
|
+
def _side_load(name, klass, resources)
|
34
|
+
associations = klass.associated_with(name)
|
35
|
+
|
36
|
+
associations.each do |association|
|
37
|
+
association.side_load(resources, @included[name])
|
38
|
+
end
|
39
|
+
|
40
|
+
resources.each do |resource|
|
41
|
+
loaded_associations = resource.loaded_associations
|
42
|
+
loaded_associations.each do |association|
|
43
|
+
loaded = resource.send(association[:name])
|
44
|
+
next unless loaded
|
45
|
+
_side_load(name, association[:class], [loaded].flatten)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/zendesk_api/version.rb
CHANGED
data/live/group_spec.rb
CHANGED
data/live/ticket_spec.rb
CHANGED
@@ -24,13 +24,13 @@ describe ZendeskAPI::Ticket do
|
|
24
24
|
context "recent tickets" do
|
25
25
|
before(:each) do
|
26
26
|
VCR.use_cassette("visit_recent_ticket") do
|
27
|
-
client.connection.get("/tickets
|
27
|
+
client.connection.get("/tickets/1") do |req|
|
28
28
|
req.headers[:Accept] = "*/*"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
it_should_be_readable :tickets, :recent
|
33
|
+
it_should_be_readable :tickets, :recent
|
34
34
|
end
|
35
35
|
|
36
36
|
describe ".incremental_export" do
|
data/spec/client_spec.rb
CHANGED
@@ -87,7 +87,7 @@ describe ZendeskAPI::Client do
|
|
87
87
|
subject { true }
|
88
88
|
|
89
89
|
it "should log in faraday" do
|
90
|
-
@client.connection.builder.handlers.should include(
|
90
|
+
@client.connection.builder.handlers.should include(ZendeskAPI::Middleware::Response::Logger)
|
91
91
|
end
|
92
92
|
|
93
93
|
context "with a request" do
|
@@ -102,7 +102,7 @@ describe ZendeskAPI::Client do
|
|
102
102
|
subject { false }
|
103
103
|
|
104
104
|
it "should not log" do
|
105
|
-
@client.connection.builder.handlers.should_not include(
|
105
|
+
@client.connection.builder.handlers.should_not include(ZendeskAPI::Middleware::Response::Logger)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -110,7 +110,7 @@ describe ZendeskAPI::Client do
|
|
110
110
|
subject { nil }
|
111
111
|
|
112
112
|
it "should log" do
|
113
|
-
@client.connection.builder.handlers.should include(
|
113
|
+
@client.connection.builder.handlers.should include(ZendeskAPI::Middleware::Response::Logger)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -119,7 +119,7 @@ describe ZendeskAPI::Client do
|
|
119
119
|
subject { Logger.new(out) }
|
120
120
|
|
121
121
|
it "should log" do
|
122
|
-
@client.connection.builder.handlers.should include(
|
122
|
+
@client.connection.builder.handlers.should include(ZendeskAPI::Middleware::Response::Logger)
|
123
123
|
end
|
124
124
|
|
125
125
|
context "with a request" do
|
@@ -159,19 +159,6 @@ describe ZendeskAPI::Client do
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
-
context "#play" do
|
163
|
-
# TODO may be able to be replaced by VCR
|
164
|
-
before(:each) do
|
165
|
-
stub_request(:get, %r{play}).to_return do
|
166
|
-
{ :status => 302 }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should return an instance of ZendeskAPI::Playlist" do
|
171
|
-
subject.play(1).should be_instance_of(ZendeskAPI::Playlist)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
162
|
it "can be subclassed" do
|
176
163
|
client = SimpleClient.new do |config|
|
177
164
|
config.allow_http = true
|
data/spec/collection_spec.rb
CHANGED
@@ -401,6 +401,149 @@ describe ZendeskAPI::Collection do
|
|
401
401
|
end
|
402
402
|
end
|
403
403
|
|
404
|
+
context "side loading" do
|
405
|
+
before(:each) do
|
406
|
+
subject.include(:nil_resources)
|
407
|
+
end
|
408
|
+
|
409
|
+
context "singular id on resource" do
|
410
|
+
before(:each) do
|
411
|
+
ZendeskAPI::TestResource.has :nil_resource
|
412
|
+
|
413
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
414
|
+
:test_resources => [{ :id => 1, :nil_resource_id => 4 }],
|
415
|
+
:nil_resources => [{ :id => 1, :name => :bye }, { :id => 4, :name => :hi }]
|
416
|
+
))
|
417
|
+
|
418
|
+
subject.fetch(true)
|
419
|
+
|
420
|
+
@resource = subject.detect {|res| res.id == 1}
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should side load nil_resources" do
|
424
|
+
@resource.nil_resource.should_not be_nil
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should side load the correct nil_resource" do
|
428
|
+
@resource.nil_resource.name.should == "hi"
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
context "plural ids on resource" do
|
433
|
+
before(:each) do
|
434
|
+
ZendeskAPI::TestResource.has_many :nil_resources
|
435
|
+
|
436
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
437
|
+
:test_resources => [{ :id => 1, :nil_resource_ids => [1, 4] }],
|
438
|
+
:nil_resources => [{ :id => 1, :name => :hi }, { :id => 4, :name => :hello }, { :id => 5, :name => :goodbye }]
|
439
|
+
))
|
440
|
+
|
441
|
+
subject.fetch(true)
|
442
|
+
|
443
|
+
@resource = subject.detect {|res| res.id == 1}
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should side load nil_resources" do
|
447
|
+
@resource.nil_resources.should_not be_empty
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should side load the correct nil_resources" do
|
451
|
+
@resource.nil_resources.map(&:name).should == %w{hi hello}
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
context "ids in side load" do
|
456
|
+
before(:each) do
|
457
|
+
ZendeskAPI::TestResource.has_many :nil_resources
|
458
|
+
|
459
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
460
|
+
:test_resources => [{ :id => 1 }],
|
461
|
+
:nil_resources => [{ :id => 1, :test_resource_id => 2 }, { :id => 2, :test_resource_id => 1 }, { :id => 4, :test_resource_id => 1 }]
|
462
|
+
))
|
463
|
+
|
464
|
+
subject.fetch(true)
|
465
|
+
@resource = subject.detect {|res| res.id == 1}
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should side load nil_resources" do
|
469
|
+
@resource.nil_resources.should_not be_empty
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should side load the correct nil_resources" do
|
473
|
+
@resource.nil_resources.map(&:id).should == [2, 4]
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
context "id in side load" do
|
478
|
+
before(:each) do
|
479
|
+
ZendeskAPI::TestResource.has :nil_resource
|
480
|
+
|
481
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
482
|
+
:test_resources => [{ :id => 1 }],
|
483
|
+
:nil_resources => [{ :id => 1, :test_resource_id => 2 }, { :id => 2, :test_resource_id => 1 }]
|
484
|
+
))
|
485
|
+
|
486
|
+
subject.fetch(true)
|
487
|
+
@resource = subject.detect {|res| res.id == 1}
|
488
|
+
end
|
489
|
+
|
490
|
+
it "should side load nil_resources" do
|
491
|
+
@resource.nil_resource.should_not be_nil
|
492
|
+
end
|
493
|
+
|
494
|
+
it "should side load the correct nil_resources" do
|
495
|
+
@resource.nil_resource.id.should == 2
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
context "with name as key" do
|
500
|
+
before(:each) do
|
501
|
+
ZendeskAPI::TestResource.has :nil_resource, :include_key => :name
|
502
|
+
|
503
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
504
|
+
:test_resources => [{ :id => 1, :nil_resource_id => 4 }],
|
505
|
+
:nil_resources => [{ :name => 1 }, { :name => 4 }]
|
506
|
+
))
|
507
|
+
|
508
|
+
subject.fetch(true)
|
509
|
+
|
510
|
+
@resource = subject.detect {|res| res.id == 1}
|
511
|
+
end
|
512
|
+
|
513
|
+
it "should side load nil_resources" do
|
514
|
+
@resource.nil_resource.should_not be_nil
|
515
|
+
end
|
516
|
+
|
517
|
+
it "should side load the correct nil_resource" do
|
518
|
+
@resource.nil_resource.name.should == 4
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
context "sub-loading" do
|
523
|
+
before(:each) do
|
524
|
+
ZendeskAPI::TestResource.has :test_child
|
525
|
+
ZendeskAPI::TestResource::TestChild.has :nil_resource
|
526
|
+
|
527
|
+
stub_json_request(:get, %r{test_resources\?include=nil_resources}, json(
|
528
|
+
:test_resources => [{ :id => 1, :test_child => { :nil_resource_id => 4 } }],
|
529
|
+
:nil_resources => [{ :id => 1 }, { :id => 4 }]
|
530
|
+
))
|
531
|
+
|
532
|
+
subject.fetch(true)
|
533
|
+
|
534
|
+
@resource = subject.detect {|res| res.id == 1}.test_child
|
535
|
+
end
|
536
|
+
|
537
|
+
it "should side load nil_resources" do
|
538
|
+
@resource.nil_resource.should_not be_nil
|
539
|
+
end
|
540
|
+
|
541
|
+
it "should side load the correct nil_resource" do
|
542
|
+
@resource.nil_resource.id.should == 4
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
404
547
|
context "method missing" do
|
405
548
|
before(:each) { subject.stub(:fetch).and_return([1, 2, nil, 3]) }
|
406
549
|
|
data/spec/read_resource_spec.rb
CHANGED
@@ -5,12 +5,14 @@ describe ZendeskAPI::ReadResource do
|
|
5
5
|
let(:id) { 1 }
|
6
6
|
subject { ZendeskAPI::TestResource }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
context "normal request" do
|
9
|
+
before(:each) do
|
10
|
+
stub_json_request(:get, %r{test_resources/#{id}}, json("test_resource" => {}))
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
it "should return instance of resource" do
|
14
|
+
subject.find(client, :id => id).should be_instance_of(subject)
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
18
|
it "should blow up without an id which would build an invalid url" do
|
@@ -19,6 +21,22 @@ describe ZendeskAPI::ReadResource do
|
|
19
21
|
}.to raise_error("No :id given")
|
20
22
|
end
|
21
23
|
|
24
|
+
context "with side loads" do
|
25
|
+
before(:each) do
|
26
|
+
stub_json_request(:get, %r{test_resources/#{id}\?include=nil_resource}, json(
|
27
|
+
"test_resource" => { :id => 1, :nil_resource_id => 2 },
|
28
|
+
"nil_resources" => [{ :id => 1, :name => :bye }, { :id => 2, :name => :hi }]
|
29
|
+
))
|
30
|
+
|
31
|
+
subject.has :nil_resource
|
32
|
+
@resource = subject.find(client, :id => id, :include => :nil_resource)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should side load nil resource" do
|
36
|
+
@resource.nil_resource.name.should == "hi"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
context "with client error" do
|
23
41
|
it "should handle 500 properly" do
|
24
42
|
stub_request(:get, %r{test_resources/#{id}}).to_return(:status => 500)
|
data/spec/search_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ZendeskAPI::Search do
|
4
|
+
context ".new" do
|
5
|
+
context "when given an existing class" do
|
6
|
+
it "should return the correct class" do
|
7
|
+
ZendeskAPI::Search.new(nil, { "result_type" => "user" }).should be_instance_of(ZendeskAPI::User)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when given a nonexistant class" do
|
12
|
+
it "should return an object of the type Search::Result" do
|
13
|
+
ZendeskAPI::Search.new(nil, { "result_type" => "blah" }).should be_instance_of(ZendeskAPI::Search::Result)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when not given anything" do
|
18
|
+
it "should return an object of the type Search::Result" do
|
19
|
+
ZendeskAPI::Search.new(nil, {}).should be_instance_of(ZendeskAPI::Search::Result)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zendesk_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-10-
|
13
|
+
date: 2012-10-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -228,8 +228,7 @@ files:
|
|
228
228
|
- lib/zendesk_api/collection.rb
|
229
229
|
- lib/zendesk_api/configuration.rb
|
230
230
|
- lib/zendesk_api/core_ext/inflection.rb
|
231
|
-
- lib/zendesk_api/
|
232
|
-
- lib/zendesk_api/core_ext/snakecase.rb
|
231
|
+
- lib/zendesk_api/helpers.rb
|
233
232
|
- lib/zendesk_api/lru_cache.rb
|
234
233
|
- lib/zendesk_api/middleware/request/etag_cache.rb
|
235
234
|
- lib/zendesk_api/middleware/request/retry.rb
|
@@ -237,14 +236,15 @@ files:
|
|
237
236
|
- lib/zendesk_api/middleware/response/callback.rb
|
238
237
|
- lib/zendesk_api/middleware/response/deflate.rb
|
239
238
|
- lib/zendesk_api/middleware/response/gzip.rb
|
239
|
+
- lib/zendesk_api/middleware/response/logger.rb
|
240
240
|
- lib/zendesk_api/middleware/response/parse_iso_dates.rb
|
241
241
|
- lib/zendesk_api/rescue.rb
|
242
242
|
- lib/zendesk_api/resource.rb
|
243
243
|
- lib/zendesk_api/resources/forum.rb
|
244
244
|
- lib/zendesk_api/resources/misc.rb
|
245
|
-
- lib/zendesk_api/resources/playlist.rb
|
246
245
|
- lib/zendesk_api/resources/ticket.rb
|
247
246
|
- lib/zendesk_api/resources/user.rb
|
247
|
+
- lib/zendesk_api/sideloading.rb
|
248
248
|
- lib/zendesk_api/track_changes.rb
|
249
249
|
- lib/zendesk_api/trackie.rb
|
250
250
|
- lib/zendesk_api/verbs.rb
|
@@ -291,6 +291,7 @@ files:
|
|
291
291
|
- spec/fixtures/credentials.yml.example
|
292
292
|
- spec/fixtures/test_resources.rb
|
293
293
|
- spec/fixtures/zendesk.rb
|
294
|
+
- spec/inflection_spec.rb
|
294
295
|
- spec/lru_cache_spec.rb
|
295
296
|
- spec/macros/resource_macros.rb
|
296
297
|
- spec/middleware/request/etag_cache_spec.rb
|
@@ -301,12 +302,11 @@ files:
|
|
301
302
|
- spec/middleware/response/deflate_spec.rb
|
302
303
|
- spec/middleware/response/gzip_spec.rb
|
303
304
|
- spec/middleware/response/parse_iso_dates_spec.rb
|
304
|
-
- spec/playlist_spec.rb
|
305
305
|
- spec/read_resource_spec.rb
|
306
306
|
- spec/rescue_spec.rb
|
307
307
|
- spec/resource_spec.rb
|
308
|
+
- spec/search_spec.rb
|
308
309
|
- spec/spec_helper.rb
|
309
|
-
- spec/string_spec.rb
|
310
310
|
- spec/trackie_spec.rb
|
311
311
|
- zendesk_api.gemspec
|
312
312
|
homepage: http://developer.zendesk.com
|
@@ -346,6 +346,7 @@ test_files:
|
|
346
346
|
- spec/fixtures/credentials.yml.example
|
347
347
|
- spec/fixtures/test_resources.rb
|
348
348
|
- spec/fixtures/zendesk.rb
|
349
|
+
- spec/inflection_spec.rb
|
349
350
|
- spec/lru_cache_spec.rb
|
350
351
|
- spec/macros/resource_macros.rb
|
351
352
|
- spec/middleware/request/etag_cache_spec.rb
|
@@ -356,11 +357,10 @@ test_files:
|
|
356
357
|
- spec/middleware/response/deflate_spec.rb
|
357
358
|
- spec/middleware/response/gzip_spec.rb
|
358
359
|
- spec/middleware/response/parse_iso_dates_spec.rb
|
359
|
-
- spec/playlist_spec.rb
|
360
360
|
- spec/read_resource_spec.rb
|
361
361
|
- spec/rescue_spec.rb
|
362
362
|
- spec/resource_spec.rb
|
363
|
+
- spec/search_spec.rb
|
363
364
|
- spec/spec_helper.rb
|
364
|
-
- spec/string_spec.rb
|
365
365
|
- spec/trackie_spec.rb
|
366
366
|
has_rdoc:
|
@@ -1,10 +0,0 @@
|
|
1
|
-
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/modulize.rb
|
2
|
-
class String
|
3
|
-
def modulize
|
4
|
-
#gsub('__','/'). # why was this ever here?
|
5
|
-
gsub(/__(.?)/){ "::#{$1.upcase}" }.
|
6
|
-
gsub(/\/(.?)/){ "::#{$1.upcase}" }.
|
7
|
-
gsub(/(?:_+|-+)([a-z])/){ $1.upcase }.
|
8
|
-
gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
|
9
|
-
end
|
10
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# From https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb
|
2
|
-
class String
|
3
|
-
def snakecase
|
4
|
-
#gsub(/::/, '/').
|
5
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
6
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
7
|
-
tr('-', '_').
|
8
|
-
gsub(/\s/, '_').
|
9
|
-
gsub(/__+/, '_').
|
10
|
-
downcase
|
11
|
-
end
|
12
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module ZendeskAPI
|
2
|
-
class Playlist
|
3
|
-
include Rescue
|
4
|
-
|
5
|
-
attr_reader :ticket
|
6
|
-
attr_accessor :id
|
7
|
-
|
8
|
-
def initialize(client, id)
|
9
|
-
@client, @id = client, id
|
10
|
-
@ticket = nil
|
11
|
-
|
12
|
-
@initialized = false
|
13
|
-
@destroyed = false
|
14
|
-
|
15
|
-
init_playlist
|
16
|
-
end
|
17
|
-
|
18
|
-
def each
|
19
|
-
init_playlist unless initialized?
|
20
|
-
|
21
|
-
while initialized? && !destroyed? && (n = self.next)
|
22
|
-
yield n
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def next
|
27
|
-
init_playlist unless initialized?
|
28
|
-
return false if !initialized? || destroyed?
|
29
|
-
|
30
|
-
response = @client.connection.get("play/next")
|
31
|
-
|
32
|
-
if response.status == 200
|
33
|
-
@ticket = Ticket.new(@client, response.body["ticket"])
|
34
|
-
@ticket
|
35
|
-
else
|
36
|
-
@destroyed = (response.status == 204)
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def destroy
|
42
|
-
response = @client.connection.delete("play")
|
43
|
-
@destroyed = response.status == 204
|
44
|
-
end
|
45
|
-
|
46
|
-
def destroyed?
|
47
|
-
@destroyed
|
48
|
-
end
|
49
|
-
|
50
|
-
def initialized?
|
51
|
-
@initialized
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def init_playlist
|
57
|
-
response = @client.connection.get("views/#{id}/play")
|
58
|
-
@initialized = response.status == 302
|
59
|
-
end
|
60
|
-
|
61
|
-
rescue_client_error :next, :init_playlist
|
62
|
-
rescue_client_error :destroy, :with => false
|
63
|
-
end
|
64
|
-
end
|
data/spec/playlist_spec.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ZendeskAPI::Playlist do
|
4
|
-
subject { ZendeskAPI::Playlist }
|
5
|
-
|
6
|
-
before(:each) do
|
7
|
-
stub_request(:get, %r{views/\d+/play}).to_return(:status => 302, :body => "You are being redirected...")
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should begin playing the playlist on initialization" do
|
11
|
-
subject.new(client, 1)
|
12
|
-
end
|
13
|
-
|
14
|
-
context "#next" do
|
15
|
-
subject { ZendeskAPI::Playlist.new(client, 1) }
|
16
|
-
|
17
|
-
before(:each) do
|
18
|
-
stub_json_request(:get, %r{play/next}, json("ticket" => {}))
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should return ticket" do
|
22
|
-
subject.next.should be_instance_of(ZendeskAPI::Ticket)
|
23
|
-
end
|
24
|
-
|
25
|
-
context "with client error", :silence_logger do
|
26
|
-
before(:each) do
|
27
|
-
stub_request(:get, %r{play/next}).to_return(:status => 500)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should be properly handled" do
|
31
|
-
expect { subject.next.should be_nil }.to_not raise_error
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "with end of playlist" do
|
36
|
-
before(:each) do
|
37
|
-
stub_request(:get, %r{play/next}).to_return(:status => 204)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should be properly handled" do
|
41
|
-
subject.next.should be_nil
|
42
|
-
subject.destroyed?.should be_true
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context "#destroy" do
|
48
|
-
subject { ZendeskAPI::Playlist.new(client, 1) }
|
49
|
-
|
50
|
-
before(:each) do
|
51
|
-
stub_request(:delete, %r{play}).to_return(:status => 204)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should be destroyed" do
|
55
|
-
subject.destroy.should be_true
|
56
|
-
subject.destroyed?.should be_true
|
57
|
-
end
|
58
|
-
|
59
|
-
context "with client error", :silence_logger do
|
60
|
-
before(:each) do
|
61
|
-
stub_request(:delete, %r{play}).to_return(:status => 500)
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should be properly handled" do
|
65
|
-
expect { subject.destroy.should be_false }.to_not raise_error
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context "initialization" do
|
71
|
-
context "with client error", :silence_logger do
|
72
|
-
before(:each) do
|
73
|
-
stub_request(:get, %r{views/\d+/play}).to_return(:status => 500).to_return(:status => 302)
|
74
|
-
stub_request(:get, %r{play/next}).to_return(:body => json)
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should be able to be created" do
|
78
|
-
new_playlist = subject.new(client, 1)
|
79
|
-
new_playlist.should_not be_nil
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should retry initialization on #next" do
|
83
|
-
new_playlist = subject.new(client, 1)
|
84
|
-
new_playlist.should_receive(:init_playlist).and_return(:true)
|
85
|
-
new_playlist.next
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should retry initialization on #each" do
|
89
|
-
new_playlist = subject.new(client, 1)
|
90
|
-
new_playlist.should_receive(:next).and_return(Object.new, nil)
|
91
|
-
new_playlist.each {|arg| :block }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|