zendesk_api 0.1.5 → 0.1.6
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.
- 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
|