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,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Request::EtagCache do
4
+ it "caches" do
5
+ client.config.cache.size = 1
6
+
7
+ stub_json_request(:get, %r{blergh}, '{"x":1}', :headers => {"Etag" => "x"})
8
+ response = client.connection.get("blergh")
9
+ response.status.should == 200
10
+ response.body.should == {"x"=>1}
11
+
12
+ stub_request(:get, %r{blergh}).to_return(:status => 304, :headers => {"Etag" => "x"})
13
+ response = client.connection.get("blergh")
14
+ response.status.should == 304
15
+ response.body.should == {"x"=>1}
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Request::Retry do
4
+ def runtime
5
+ start = Time.now.to_f
6
+ yield
7
+ Time.now.to_f - start
8
+ end
9
+
10
+ [429, 503].each do |error_code|
11
+ it "should wait requisite seconds and then retry request on #{error_code}" do
12
+ stub_request(:get, %r{blergh}).
13
+ to_return(:status => 429, :headers => { :retry_after => 1 }).
14
+ to_return(:status => 200)
15
+
16
+ runtime do
17
+ client.connection.get("blergh").status.should == 200
18
+ end.should be_within(0.2).of(1)
19
+ end
20
+ end
21
+
22
+ context "with failing request", :prevent_logger_changes do
23
+ before do
24
+ stub_request(:get, %r{blergh}).
25
+ to_return(:status => 503).
26
+ to_return(:status => 200)
27
+
28
+ ZendeskAPI::Middleware::Request::Retry.any_instance.should_receive(:sleep).exactly(10).times.with(1)
29
+ end
30
+
31
+ it "should wait default timeout seconds and then retry request on error" do
32
+ runtime do
33
+ client.connection.get("blergh").status.should == 200
34
+ end.should <= 0.5
35
+ end
36
+
37
+ it "should print to logger" do
38
+ client.config.logger.should_receive(:warn).at_least(:once)
39
+ client.connection.get("blergh")
40
+ end
41
+
42
+ it "should not fail without a logger" do
43
+ client.config.logger = false
44
+ client.connection.get("blergh")
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Request::Upload do
4
+ subject { ZendeskAPI::Middleware::Request::Upload.new(lambda {|env| env}) }
5
+ let(:filename) { File.join(File.dirname(__FILE__), "test.jpg") }
6
+
7
+ it "should handle no body" do
8
+ subject.call({}).should == {}
9
+ end
10
+
11
+ it "should handle body with no file" do
12
+ subject.call(:body => {})[:body].should == {}
13
+ end
14
+
15
+ it "should handle invalid types" do
16
+ subject.call(:body => { :file => :invalid })[:body].should == {}
17
+ end
18
+
19
+ context "with file string" do
20
+ before(:each) do
21
+ @env = subject.call(:body => { :file => filename })
22
+ end
23
+
24
+ it "should convert file string to UploadIO" do
25
+ @env[:body][:uploaded_data].should be_instance_of(Faraday::UploadIO)
26
+ end
27
+
28
+ it "should remove file string" do
29
+ @env[:body][:file].should be_nil
30
+ end
31
+
32
+ it "should add filename if none exist" do
33
+ @env[:body][:filename].should == "test.jpg"
34
+ end
35
+
36
+ context "with filename" do
37
+ before(:each) do
38
+ @env = subject.call(:body => { :file => filename, :filename => "test" })
39
+ end
40
+
41
+ it "should not change filename" do
42
+ @env[:body][:filename].should_not == "test.jpg"
43
+ end
44
+ end
45
+ end
46
+
47
+ context "with file instance" do
48
+ before(:each) do
49
+ @env = subject.call(:body => { :file => File.new(filename) })
50
+ end
51
+
52
+ it "should convert file string to UploadIO" do
53
+ @env[:body][:uploaded_data].should be_instance_of(Faraday::UploadIO)
54
+ end
55
+
56
+ it "should remove file string" do
57
+ @env[:body][:file].should be_nil
58
+ end
59
+
60
+ it "should add filename if none exist" do
61
+ @env[:body][:filename].should == "test.jpg"
62
+ end
63
+
64
+ context "with filename" do
65
+ before(:each) do
66
+ @env = subject.call(:body => { :file => File.new(filename), :filename => "test" })
67
+ end
68
+
69
+ it "should not change filename" do
70
+ @env[:body][:filename].should_not == "test.jpg"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Response::Callback do
4
+ let(:response) { "TEST" }
5
+
6
+ before(:each) do
7
+ client.insert_callback do |env|
8
+ env[:body] = response
9
+ end
10
+
11
+ stub_request(:get, %r{test_endpoint}).to_return(:body => JSON.dump({ "ABC" => "DEF" }))
12
+ end
13
+
14
+ it "should call callbacks " do
15
+ client.connection.get("test_endpoint").body.should == response
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Response::Deflate do
4
+ context "with content-encoding = 'deflate'" do
5
+ subject { '{ "TESTDATA": true }' }
6
+
7
+ before(:each) do
8
+ stub_request(:get, %r{blergh}).to_return(:headers => { :content_encoding => "deflate" }, :body => Zlib::Deflate.deflate(subject))
9
+ end
10
+
11
+ it "should inflate returned body" do
12
+ client.connection.get("blergh").body['TESTDATA'].should be_true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Response::Gzip do
4
+ context "with content-encoding = 'gzip'" do
5
+ subject { '{ "TESTDATA": true }' }
6
+ before(:each) do
7
+ encoded_data = StringIO.new
8
+ gz = Zlib::GzipWriter.new(encoded_data)
9
+ gz.write(subject)
10
+ gz.close
11
+
12
+ stub_request(:get, %r{blergh}).to_return(:headers => { :content_encoding => "gzip" }, :body => encoded_data.string)
13
+ end
14
+
15
+ it "should inflate returned body" do
16
+ client.connection.get("blergh").body['TESTDATA'].should be_true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Middleware::Response::ParseIsoDates do
4
+ def fake_response(data)
5
+ stub_json_request(:get, %r{blergh}, data)
6
+ response = client.connection.get("blergh")
7
+ response.status.should == 200
8
+ response
9
+ end
10
+
11
+ let(:parsed){
12
+ if RUBY_VERSION > "1.9"
13
+ "2012-02-01 13:14:15 UTC"
14
+ else
15
+ "Wed Feb 01 13:14:15 UTC 2012"
16
+ end
17
+ }
18
+
19
+ it "should parse dates" do
20
+ fake_response('{"x":"2012-02-01T13:14:15Z"}').body["x"].to_s.should == parsed
21
+ end
22
+
23
+ it "should parse nested dates in hash" do
24
+ fake_response('{"x":{"y":"2012-02-01T13:14:15Z"}}').body["x"]["y"].to_s.should == parsed
25
+ end
26
+
27
+ it "should parse nested dates in arrays" do
28
+ fake_response('{"x":[{"y":"2012-02-01T13:14:15Z"}]}').body["x"][0]["y"].to_s.should == parsed
29
+ end
30
+
31
+ it "should not blow up on empty body" do
32
+ fake_response('').body.should == nil
33
+ end
34
+
35
+ it "should leave arrays with ids alone" do
36
+ fake_response('{"x":[1,2,3]}').body.should == {"x" => [1,2,3]}
37
+ end
38
+
39
+ it "should not parse date-like things" do
40
+ fake_response('{"x":"2012-02-01T13:14:15Z bla"}').body["x"].to_s.should == "2012-02-01T13:14:15Z bla"
41
+ fake_response('{"x":"12012-02-01T13:14:15Z"}').body["x"].to_s.should == "12012-02-01T13:14:15Z"
42
+ fake_response(%Q{{"x":"2012-02-01T13:14:15Z\\nfoo"}}).body["x"].to_s.should == "2012-02-01T13:14:15Z\nfoo"
43
+ end
44
+ end
@@ -0,0 +1,95 @@
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
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::ReadResource do
4
+ context "find" do
5
+ let(:id) { 1 }
6
+ subject { ZendeskAPI::TestResource }
7
+
8
+ before(:each) do
9
+ stub_json_request(:get, %r{test_resources/#{id}}, json("test_resource" => {}))
10
+ end
11
+
12
+ it "should return instance of resource" do
13
+ subject.find(client, :id => id).should be_instance_of(subject)
14
+ end
15
+
16
+ it "should blow up without an id which would build an invalid url" do
17
+ expect{
18
+ ZendeskAPI::User.find(client, :foo => :bar)
19
+ }.to raise_error("No :id given")
20
+ end
21
+
22
+ context "with client error" do
23
+ it "should handle 500 properly" do
24
+ stub_request(:get, %r{test_resources/#{id}}).to_return(:status => 500)
25
+ client.config.logger.should_receive(:warn).at_least(:once)
26
+ subject.find(client, :id => id).should == nil
27
+ end
28
+
29
+ it "should handle 404 properly" do
30
+ stub_request(:get, %r{test_resources/#{id}}).to_return(:status => 404)
31
+ client.config.logger.should_receive(:warn).at_least(:once)
32
+ subject.find(client, :id => id).should == nil
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZendeskAPI::Rescue do
4
+ include ZendeskAPI::Rescue
5
+
6
+ class Boom
7
+ include ZendeskAPI::Rescue
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ end
13
+
14
+ def puff(error)
15
+ raise error, "Puff"
16
+ end
17
+
18
+ def boom(error)
19
+ raise error, "Boom"
20
+ end
21
+
22
+ rescue_client_error :puff
23
+ end
24
+
25
+ it "rescues from client errors", :silence_logger do
26
+ Boom.new(client).puff(Faraday::Error::ClientError)
27
+ end
28
+
29
+ it "does not protect other actions" do
30
+ expect{
31
+ Boom.new(client).boom(RuntimeError)
32
+ }.to raise_error RuntimeError
33
+ end
34
+
35
+ it "raises everything else" do
36
+ expect{
37
+ Boom.new(client).puff(RuntimeError)
38
+ }.to raise_error RuntimeError
39
+ end
40
+
41
+ it "logs to logger" do
42
+ out = StringIO.new
43
+ client = ZendeskAPI::Client.new do |config|
44
+ config.logger = Logger.new(out)
45
+ config.url = "https://idontcare.com"
46
+ end
47
+ out.should_receive(:write).at_least(:twice)
48
+ Boom.new(client).puff(Faraday::Error::ClientError)
49
+ end
50
+
51
+ it "does crash without logger" do
52
+ client = ZendeskAPI::Client.new do |config|
53
+ config.logger = false
54
+ config.url = "https://idontcare.com"
55
+ end
56
+ Boom.new(client).puff(Faraday::Error::ClientError)
57
+ end
58
+
59
+ context "passing a block" do
60
+ it "rescues from client errors", :silence_logger do
61
+ rescue_client_error do
62
+ raise Faraday::Error::ClientError, "error"
63
+ end
64
+ end
65
+
66
+ it "raises everything else" do
67
+ expect{
68
+ rescue_client_error { raise RuntimeError, "error" }
69
+ }.to raise_error RuntimeError
70
+ end
71
+
72
+ it "logs to logger" do
73
+ out = StringIO.new
74
+ @client = ZendeskAPI::Client.new do |config|
75
+ config.logger = Logger.new(out)
76
+ config.url = "https://idontcare.com"
77
+ end
78
+ out.should_receive(:write).at_least(:twice)
79
+ rescue_client_error do
80
+ raise Faraday::Error::ClientError, "error"
81
+ end
82
+ end
83
+
84
+ it "does crash without logger" do
85
+ @client = ZendeskAPI::Client.new do |config|
86
+ config.logger = false
87
+ config.url = "https://idontcare.com"
88
+ end
89
+ rescue_client_error do
90
+ raise Faraday::Error::ClientError, "error"
91
+ end
92
+ end
93
+ end
94
+ end