zendesk_api 0.0.9

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.
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