zendesk_api 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +59 -0
  7. data/LICENSE +19 -0
  8. data/Rakefile +49 -0
  9. data/Readme.md +178 -0
  10. data/lib/zendesk_api.rb +10 -0
  11. data/lib/zendesk_api/actions.rb +176 -0
  12. data/lib/zendesk_api/association.rb +267 -0
  13. data/lib/zendesk_api/client.rb +150 -0
  14. data/lib/zendesk_api/collection.rb +233 -0
  15. data/lib/zendesk_api/configuration.rb +52 -0
  16. data/lib/zendesk_api/core_ext/inflection.rb +13 -0
  17. data/lib/zendesk_api/core_ext/modulize.rb +10 -0
  18. data/lib/zendesk_api/core_ext/snakecase.rb +12 -0
  19. data/lib/zendesk_api/lru_cache.rb +38 -0
  20. data/lib/zendesk_api/middleware/request/etag_cache.rb +38 -0
  21. data/lib/zendesk_api/middleware/request/retry.rb +39 -0
  22. data/lib/zendesk_api/middleware/request/upload.rb +32 -0
  23. data/lib/zendesk_api/middleware/response/callback.rb +19 -0
  24. data/lib/zendesk_api/middleware/response/deflate.rb +18 -0
  25. data/lib/zendesk_api/middleware/response/gzip.rb +18 -0
  26. data/lib/zendesk_api/middleware/response/parse_iso_dates.rb +29 -0
  27. data/lib/zendesk_api/rescue.rb +44 -0
  28. data/lib/zendesk_api/resource.rb +133 -0
  29. data/lib/zendesk_api/resources/forum.rb +51 -0
  30. data/lib/zendesk_api/resources/misc.rb +66 -0
  31. data/lib/zendesk_api/resources/playlist.rb +64 -0
  32. data/lib/zendesk_api/resources/ticket.rb +76 -0
  33. data/lib/zendesk_api/resources/user.rb +44 -0
  34. data/lib/zendesk_api/track_changes.rb +72 -0
  35. data/lib/zendesk_api/trackie.rb +8 -0
  36. data/lib/zendesk_api/verbs.rb +43 -0
  37. data/lib/zendesk_api/version.rb +3 -0
  38. data/live/Readme.md +4 -0
  39. data/live/activity_spec.rb +5 -0
  40. data/live/audit_spec.rb +5 -0
  41. data/live/bookmark_spec.rb +11 -0
  42. data/live/category_spec.rb +12 -0
  43. data/live/collection_spec.rb +68 -0
  44. data/live/crm_spec.rb +11 -0
  45. data/live/custom_role_spec.rb +5 -0
  46. data/live/forum_spec.rb +14 -0
  47. data/live/forum_subscription_spec.rb +12 -0
  48. data/live/group_membership_spec.rb +18 -0
  49. data/live/group_spec.rb +14 -0
  50. data/live/identity_spec.rb +14 -0
  51. data/live/locale_spec.rb +11 -0
  52. data/live/macro_spec.rb +5 -0
  53. data/live/mobile_device_spec.rb +11 -0
  54. data/live/organization_spec.rb +12 -0
  55. data/live/satisfaction_rating_spec.rb +6 -0
  56. data/live/setting_spec.rb +5 -0
  57. data/live/suspended_ticket_spec.rb +8 -0
  58. data/live/ticket_field_spec.rb +12 -0
  59. data/live/ticket_metrics_spec.rb +6 -0
  60. data/live/ticket_spec.rb +88 -0
  61. data/live/topic_comment_spec.rb +13 -0
  62. data/live/topic_spec.rb +18 -0
  63. data/live/topic_subscription_spec.rb +12 -0
  64. data/live/topic_vote_spec.rb +13 -0
  65. data/live/upload_spec.rb +9 -0
  66. data/live/user_spec.rb +13 -0
  67. data/live/view_spec.rb +6 -0
  68. data/spec/association_spec.rb +210 -0
  69. data/spec/client_spec.rb +149 -0
  70. data/spec/collection_spec.rb +302 -0
  71. data/spec/configuration_spec.rb +24 -0
  72. data/spec/create_resource_spec.rb +39 -0
  73. data/spec/data_resource_spec.rb +229 -0
  74. data/spec/fixtures/Argentina.gif +0 -0
  75. data/spec/fixtures/Argentina2.gif +0 -0
  76. data/spec/fixtures/credentials.yml.example +3 -0
  77. data/spec/fixtures/test_resources.rb +8 -0
  78. data/spec/fixtures/zendesk.rb +88 -0
  79. data/spec/lru_cache_spec.rb +26 -0
  80. data/spec/macros/resource_macros.rb +157 -0
  81. data/spec/middleware/request/etag_cache_spec.rb +17 -0
  82. data/spec/middleware/request/retry_spec.rb +47 -0
  83. data/spec/middleware/request/test.jpg +0 -0
  84. data/spec/middleware/request/upload_spec.rb +74 -0
  85. data/spec/middleware/response/callback_spec.rb +17 -0
  86. data/spec/middleware/response/deflate_spec.rb +15 -0
  87. data/spec/middleware/response/gzip_spec.rb +19 -0
  88. data/spec/middleware/response/parse_iso_dates_spec.rb +44 -0
  89. data/spec/playlist_spec.rb +95 -0
  90. data/spec/read_resource_spec.rb +37 -0
  91. data/spec/rescue_spec.rb +94 -0
  92. data/spec/resource_spec.rb +332 -0
  93. data/spec/spec_helper.rb +120 -0
  94. data/spec/string_spec.rb +7 -0
  95. data/spec/trackie_spec.rb +39 -0
  96. data/zendesk_api.gemspec +38 -0
  97. metadata +364 -0
@@ -0,0 +1,332 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Resource do
4
+ context "#update" do
5
+ context "class method" do
6
+ let(:id) { 1 }
7
+ subject { ZendeskAPI::TestResource }
8
+
9
+ before(:each) do
10
+ stub_json_request(:put, %r{test_resources/#{id}})
11
+ end
12
+
13
+ it "should return instance of resource" do
14
+ subject.update(client, :id => id).should be_true
15
+ end
16
+
17
+ context "with client error" do
18
+ before(:each) do
19
+ stub_request(:put, %r{test_resources/#{id}}).to_return(:status => 500)
20
+ end
21
+
22
+ it "should handle it properly" do
23
+ expect { silence_logger{ subject.update(client, :id => id).should be_false } }.to_not raise_error
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ context "#destroy" do
30
+ context "class method" do
31
+ let(:id) { 1 }
32
+ subject { ZendeskAPI::TestResource }
33
+
34
+ before(:each) do
35
+ stub_json_request(:delete, %r{test_resources/#{id}})
36
+ end
37
+
38
+ it "should return instance of resource" do
39
+ subject.destroy(client, :id => id).should be_true
40
+ end
41
+
42
+ context "with client error" do
43
+ before(:each) do
44
+ stub_request(:delete, %r{test_resources/#{id}}).to_return(:status => 500)
45
+ end
46
+
47
+ it "should handle it properly" do
48
+ expect { silence_logger{ subject.destroy(client, :id => id).should be_false } }.to_not raise_error
49
+ end
50
+ end
51
+ end
52
+
53
+ context "instance method" do
54
+ subject { ZendeskAPI::TestResource.new(client, :id => 1) }
55
+
56
+ before(:each) do
57
+ stub_request(:delete, %r{test_resources}).to_return(:status => 200)
58
+ end
59
+
60
+ it "should return true and set destroyed" do
61
+ subject.destroy.should be_true
62
+ subject.destroyed?.should be_true
63
+ subject.destroy.should be_false
64
+ end
65
+
66
+ context "with client error" do
67
+ before(:each) do
68
+ stub_request(:delete, %r{test_resources}).to_return(:status => 500)
69
+ end
70
+
71
+ it "should return false and not set destroyed" do
72
+ silence_logger{ subject.destroy.should be_false }
73
+ subject.destroyed?.should be_false
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ context "#save!" do
80
+ subject { ZendeskAPI::TestResource.new(client, :id => 1) }
81
+
82
+ before(:each) do
83
+ subject.should_receive(:save).and_return(false)
84
+ end
85
+
86
+ it "should raise if save fails" do
87
+ expect { subject.save! }.to raise_error
88
+ end
89
+ end
90
+
91
+ context "#save" do
92
+ let(:id) { 1 }
93
+ let(:attr) { { :param => "test" } }
94
+ subject { ZendeskAPI::TestResource.new(client, attr.merge(:id => id)) }
95
+
96
+ before :each do
97
+ stub_json_request(:put, %r{test_resources/#{id}}, json(:test_resource => { :param => "abc" }))
98
+ end
99
+
100
+ it "should not save if already destroyed" do
101
+ subject.should_receive(:destroyed?).and_return(true)
102
+ subject.save.should be_false
103
+ end
104
+
105
+ it "should not be a new record with an id" do
106
+ subject.new_record?.should be_false
107
+ end
108
+
109
+ it "should put on save" do
110
+ subject.save.should be_true
111
+ subject[:param].should == "abc"
112
+ end
113
+
114
+ context "with unused associations" do
115
+ before do
116
+ ZendeskAPI::TestResource.associations.clear
117
+ ZendeskAPI::TestResource.has :child, :class => :test_child
118
+ ZendeskAPI::TestResource.has_many :children, :class => :test_child
119
+ end
120
+
121
+ it "should not touch them" do
122
+ subject.save.should == true
123
+ end
124
+ end
125
+
126
+ context "with client error" do
127
+ before :each do
128
+ stub_request(:put, %r{test_resources/1}).to_return(:status => 500)
129
+ end
130
+
131
+ it "should be properly handled" do
132
+ expect { silence_logger { subject.save.should be_false } }.to_not raise_error
133
+ end
134
+ end
135
+
136
+ context "new record" do
137
+ subject { ZendeskAPI::TestResource.new(client, attr) }
138
+
139
+ before :each do
140
+ stub_json_request(:post, %r{test_resources}, json(:test_resource => attr.merge(:id => id)), :status => 201)
141
+ end
142
+
143
+ it "should be true without an id" do
144
+ subject.new_record?.should be_true
145
+ end
146
+
147
+ it "should be false after creating" do
148
+ subject.save.should be_true
149
+ subject.new_record?.should be_false
150
+ subject.id.should == id
151
+ end
152
+ end
153
+
154
+ context "with nested associations to save" do
155
+ context "has" do
156
+ before(:each) do
157
+ ZendeskAPI::TestResource.associations.clear
158
+ ZendeskAPI::TestResource.has :child, :class => :test_child
159
+ stub_json_request(:put, %r{test_resources})
160
+ subject.child = { :id => 2 }
161
+ end
162
+
163
+ it "should call save on the association" do
164
+ subject.child.foo = "bar"
165
+ subject.child.should_receive(:save)
166
+ subject.save
167
+ end
168
+
169
+ it "should not call save on the association if they are synced" do
170
+ subject.child.should_not_receive(:save)
171
+ subject.save
172
+ end
173
+ end
174
+
175
+ context "has_many" do
176
+ before(:each) do
177
+ ZendeskAPI::TestResource.associations.clear
178
+ ZendeskAPI::TestResource.has_many :children, :class => :test_child
179
+
180
+ stub_json_request(:put, %r{test_resources})
181
+ stub_json_request(:get, %r{children}, json(:test_children => []))
182
+ end
183
+
184
+ it "should reset children_ids on save" do
185
+ subject.children = [2, 3]
186
+ subject.children_ids = [1]
187
+ subject.save
188
+ subject.children_ids.should == [2,3]
189
+ end
190
+
191
+ it "should not save the associated objects when there are no changes" do
192
+ subject.children = [2]
193
+ subject.children.first.should_not_receive(:save)
194
+ subject.save
195
+ end
196
+
197
+ it "should save the associated objects when it is new" do
198
+ subject.children = [{:foo => "bar"}]
199
+ subject.children.first.should_receive(:save)
200
+ subject.save
201
+ end
202
+
203
+ it "should not save the associated objects when it is set via full hash" do
204
+ subject.children = [{:id => 1, :foo => "bar"}]
205
+ subject.children.first.should_not_receive(:save)
206
+ subject.save
207
+ end
208
+
209
+ it "should save the associated objects when it is changes" do
210
+ subject.children = [{:id => 1}]
211
+ subject.children.first.foo = "bar"
212
+ subject.children.first.should_receive(:save)
213
+ subject.save
214
+ end
215
+ end
216
+
217
+ context "inline" do
218
+ before(:each) do
219
+ class ZendeskAPI::NilResource
220
+ def to_param; "TESTDATA"; end
221
+ end
222
+
223
+ ZendeskAPI::TestResource.associations.clear
224
+ ZendeskAPI::TestResource.has :nil, :class => :nil_resource, :inline => true
225
+
226
+ subject.nil = { :abc => :def }
227
+ subject.save_associations
228
+ end
229
+
230
+ it "should save param data" do
231
+ subject.attributes[:nil].should == "TESTDATA"
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ %w{put post delete}.each do |verb|
238
+ context "on #{verb}" do
239
+ let(:method) { "test_#{verb}_method" }
240
+ before(:each) do
241
+ ZendeskAPI::TestResource.send(verb, method)
242
+ end
243
+
244
+ context "class method" do
245
+ subject { ZendeskAPI::TestResource }
246
+
247
+ it "should create a method of the same name" do
248
+ subject.instance_methods.map(&:to_s).should include(method)
249
+ end
250
+ end
251
+
252
+ context "instance method" do
253
+ subject { ZendeskAPI::TestResource.new(client, :id => 1) }
254
+
255
+ before(:each) do
256
+ stub_json_request(verb.to_sym, %r{test_resources/1/#{method}}, json(:test_resources => [{ :id => 1, :method => method }]))
257
+ end
258
+
259
+ it "should return true" do
260
+ subject.send(method).should be_true
261
+ end
262
+
263
+ it "should update the attributes if they exist" do
264
+ subject.send(method)
265
+ subject[:method].should == method
266
+ end
267
+
268
+ context "with client error" do
269
+ before(:each) do
270
+ stub_request(verb.to_sym, %r{test_resources/1/#{method}}).to_return(:status => 500)
271
+ end
272
+
273
+ it "should return false" do
274
+ expect { silence_logger{ subject.send(method).should be_false } }.to_not raise_error
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
280
+
281
+ context "#inspect" do
282
+ it "should display nicely" do
283
+ ZendeskAPI::User.new(client, :foo => :bar).inspect.should == "#<ZendeskAPI::User {\"foo\"=>:bar}>"
284
+ end
285
+ end
286
+
287
+ context "#==" do
288
+ it "is same when id is same" do
289
+ ZendeskAPI::TestResource.new(client, :id => 1, "bar" => "baz").should == ZendeskAPI::TestResource.new(client, :id => 1, "foo" => "bar")
290
+ end
291
+
292
+ it "is same when object_id is same" do
293
+ object = ZendeskAPI::TestResource.new(client, "bar" => "baz")
294
+ object.should == object
295
+ end
296
+
297
+ it "is different when both have no id" do
298
+ ZendeskAPI::TestResource.new(client).should_not == ZendeskAPI::TestResource.new(client)
299
+ end
300
+
301
+ it "is different when id is different" do
302
+ ZendeskAPI::TestResource.new(client, :id => 2).should_not == ZendeskAPI::TestResource.new(client, :id => 1)
303
+ end
304
+
305
+ it "is different when class is different" do
306
+ ZendeskAPI::TestResource.new(client, :id => 2).should_not == ZendeskAPI::TestResource::TestChild.new(client, :id => 2)
307
+ end
308
+
309
+ it "is different when other is no resource" do
310
+ ZendeskAPI::TestResource.new(client, :id => 2).should_not == nil
311
+ end
312
+
313
+ it "warns about weird comparissons" do
314
+ object = ZendeskAPI::TestResource.new(client, :id => 2)
315
+ object.should_receive(:warn)
316
+ object.should_not == "xxx"
317
+ end
318
+ end
319
+
320
+ context "#new" do
321
+ it "builds with hash" do
322
+ object = ZendeskAPI::TestResource.new(client, {})
323
+ object.attributes.should == {}
324
+ end
325
+
326
+ it "fails to build with nil (e.g. empty response from server)" do
327
+ expect{
328
+ ZendeskAPI::TestResource.new(client, nil)
329
+ }.to raise_error(/Expected a Hash/i)
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,120 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ $:.unshift(File.join(File.dirname(__FILE__), "macros"))
3
+
4
+ ENV['TZ'] = 'CET' # something that is not local and not utc so we find all the bugs
5
+
6
+ if RUBY_VERSION =~ /1.9/ && ENV["COVERAGE"]
7
+ require 'simplecov'
8
+ SimpleCov.start do
9
+ add_filter "spec/"
10
+ end
11
+ end
12
+
13
+ require 'zendesk_api'
14
+ require 'vcr'
15
+ require 'logger'
16
+ require 'stringio'
17
+ require 'json'
18
+
19
+ require 'resource_macros'
20
+ require 'fixtures/zendesk'
21
+ require 'fixtures/test_resources'
22
+
23
+ # tests fail when this is included in a Module (someone else also defines client)
24
+ def client
25
+ credentials = File.join(File.dirname(__FILE__), "fixtures", "credentials.yml")
26
+ @client ||= begin
27
+ client = ZendeskAPI::Client.new do |config|
28
+ if File.exist?(credentials)
29
+ data = YAML.load(File.read(credentials))
30
+ config.username = data["username"]
31
+ config.password = data["password"]
32
+ config.url = data["url"]
33
+
34
+ if data["url"].start_with?("http://")
35
+ config.allow_http = true
36
+ end
37
+ else
38
+ puts "using default credentials: live specs will fail."
39
+ puts "add your credentials to spec/fixtures/credentials.yml (see: spec/fixtures/credentials.yml.example)"
40
+ config.username = "please.change"
41
+ config.password = "me"
42
+ config.url = "https://my.zendesk.com/api/v2"
43
+ end
44
+
45
+ config.retry = true
46
+ end
47
+
48
+ client.config.logger.level = (ENV["LOG"] ? Logger::INFO : Logger::WARN)
49
+ client.config.cache.size = 0
50
+
51
+ client
52
+ end
53
+ end
54
+
55
+ module TestHelper
56
+ def silence_logger
57
+ old_level = client.config.logger.level
58
+ client.config.logger.level = 6
59
+ yield
60
+ ensure
61
+ client.config.logger.level = old_level
62
+ end
63
+
64
+ def silence_stderr
65
+ $stderr = File.new( '/dev/null', 'w' )
66
+ yield
67
+ ensure
68
+ $stderr = STDERR
69
+ end
70
+
71
+ def json(body = {})
72
+ JSON.dump(body)
73
+ end
74
+
75
+ def stub_json_request(verb, path_matcher, body = json, options = {})
76
+ stub_request(verb, path_matcher).to_return(Hashie::Mash.new(
77
+ :body => body, :headers => { :content_type => "application/json" }
78
+ ).deep_merge(options))
79
+ end
80
+ end
81
+
82
+ RSpec.configure do |c|
83
+ # so we can use `:vcr` rather than `:vcr => true`;
84
+ # in RSpec 3 this will no longer be necessary.
85
+ c.treat_symbols_as_metadata_keys_with_true_values = true
86
+
87
+ c.before(:each) do
88
+ ZendeskAPI::TestResource.associations.clear
89
+ ZendeskAPI::TestResource.has_many :children, :class => :test_child
90
+ end
91
+
92
+ c.before(:each) do
93
+ WebMock.reset!
94
+ end
95
+
96
+ c.around(:each, :silence_logger) do |example|
97
+ silence_logger{ example.call }
98
+ end
99
+
100
+ c.around(:each, :prevent_logger_changes) do |example|
101
+ begin
102
+ old_logger = client.config.logger
103
+ example.call
104
+ ensure
105
+ client.config.logger = old_logger
106
+ end
107
+ end
108
+
109
+ c.extend VCR::RSpec::Macros
110
+ c.extend ResourceMacros
111
+ c.include TestHelper
112
+ end
113
+
114
+ VCR.configure do |c|
115
+ c.cassette_library_dir = File.join(File.dirname(__FILE__), "fixtures", "cassettes")
116
+ c.default_cassette_options = { :record => :new_episodes, :decode_compressed_response => true }
117
+ c.hook_into :webmock
118
+ end
119
+
120
+ include WebMock::API