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,7 @@
1
+ pkg
2
+ doc
3
+ *swp
4
+ spec/fixtures/cassettes
5
+ spec/fixtures/credentials.yml
6
+ coverage
7
+ .yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - ree
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby
@@ -0,0 +1 @@
1
+ --no-private --protected lib/**/*.rb - Readme.md
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "simplecov", :platforms => :ruby_19, :group => :development
4
+ gem "jruby-openssl", :platforms => :jruby
5
+
6
+ gemspec
@@ -0,0 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ zendesk_api (0.0.9)
5
+ faraday (>= 0.8.0)
6
+ faraday_middleware (>= 0.8.7)
7
+ hashie
8
+ inflection
9
+ json
10
+ mime-types
11
+ multipart-post
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ addressable (2.2.8)
17
+ crack (0.3.1)
18
+ diff-lcs (1.1.3)
19
+ faraday (0.8.1)
20
+ multipart-post (~> 1.1)
21
+ faraday_middleware (0.8.7)
22
+ faraday (>= 0.7.4, < 0.9)
23
+ hashie (1.2.0)
24
+ inflection (1.0.0)
25
+ json (1.7.3)
26
+ mime-types (1.19)
27
+ multi_json (1.3.6)
28
+ multipart-post (1.1.5)
29
+ rake (0.9.2.2)
30
+ rspec (2.10.0)
31
+ rspec-core (~> 2.10.0)
32
+ rspec-expectations (~> 2.10.0)
33
+ rspec-mocks (~> 2.10.0)
34
+ rspec-core (2.10.1)
35
+ rspec-expectations (2.10.0)
36
+ diff-lcs (~> 1.1.3)
37
+ rspec-mocks (2.10.1)
38
+ simplecov (0.6.4)
39
+ multi_json (~> 1.0)
40
+ simplecov-html (~> 0.5.3)
41
+ simplecov-html (0.5.3)
42
+ vcr (2.2.2)
43
+ webmock (1.8.7)
44
+ addressable (>= 2.2.7)
45
+ crack (>= 0.1.7)
46
+ yard (0.8.2.1)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ jruby-openssl
53
+ rake
54
+ rspec (>= 2.0.0)
55
+ simplecov
56
+ vcr
57
+ webmock
58
+ yard
59
+ zendesk_api!
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012 Zendesk
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ require 'rake/testtask'
2
+ require 'bundler/gem_tasks'
3
+
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+ rescue LoadError
7
+ end
8
+
9
+ if defined?(RSpec)
10
+ desc "Run specs"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ desc "Run live specs"
14
+ RSpec::Core::RakeTask.new("spec:live") do |t|
15
+ t.pattern = "live/*_spec.rb"
16
+ end
17
+
18
+ task :clean_live do
19
+ sh "rm -rf spec/fixtures/cassettes"
20
+ end
21
+
22
+ if RUBY_VERSION =~ /1.9/
23
+ desc "Find coverage"
24
+ task "spec:coverage" do
25
+ ENV["COVERAGE"] = "yes"
26
+ Rake::Task["spec"].invoke
27
+ end
28
+ end
29
+
30
+ desc 'Default: run specs.'
31
+ task :default => :spec
32
+ end
33
+
34
+ # extracted from https://github.com/grosser/project_template
35
+ rule /^version:bump:.*/ do |t|
36
+ sh "git status | grep 'nothing to commit'" # ensure we are not dirty
37
+ index = ['major', 'minor','patch'].index(t.name.split(':').last)
38
+ file = 'lib/zendesk_api/version.rb'
39
+
40
+ version_file = File.read(file)
41
+ old_version, *version_parts = version_file.match(/(\d+)\.(\d+)\.(\d+)/).to_a
42
+ version_parts[index] = version_parts[index].to_i + 1
43
+ version_parts[2] = 0 if index < 2 # remove patch for minor
44
+ version_parts[1] = 0 if index < 1 # remove minor for major
45
+ new_version = version_parts * '.'
46
+ File.open(file,'w'){|f| f.write(version_file.sub(old_version, new_version)) }
47
+
48
+ sh "bundle && git add #{file} Gemfile.lock && git commit -m 'bump version to #{new_version}'"
49
+ end
@@ -0,0 +1,178 @@
1
+ # Zendesk API Client
2
+
3
+ ## API version support
4
+
5
+ This client **only** supports Zendesk's v2 API. Please see our [API documentation](http://developer.zendesk.com) for more information.
6
+
7
+ ## Important Notice
8
+
9
+ Version 0.0.5 brings with it a change to the top-level namespace. All references to Zendesk should now use ZendeskAPI.
10
+
11
+ ## Installation
12
+
13
+ Currently
14
+
15
+ gem install zendesk_api
16
+
17
+ will not install this version of the API client. To install this client, either clone this repository and run
18
+
19
+ rake install
20
+
21
+ or add it to a Gemfile like so:
22
+
23
+ gem "zendesk_api", :git => "git://github.com/zendesk/zendesk_api_client_rb.git" #, :tag => "vX.X.X"
24
+
25
+ ## Configuration
26
+
27
+ Configuration is done through a block returning an instance of ZendeskAPI::Client.
28
+ The block is mandatory and if not passed, an ArgumentError will be thrown.
29
+
30
+ ```
31
+ ZendeskAPI::Client.new do |config|
32
+ # Mandatory:
33
+
34
+ config.url = "https://mydesk.zendesk.com/api/v2"
35
+
36
+ config.username = "test.user"
37
+ config.password = "test.password"
38
+
39
+ # Optional:
40
+
41
+ # Retry uses middleware to notify the user
42
+ # when hitting the rate limit, sleep automatically,
43
+ # then retry the request.
44
+ config.retry = true
45
+
46
+ # Logger prints to STDERR by default, to e.g. print to stdout:
47
+ require 'logger'
48
+ config.logger = Logger.new(STDOUT)
49
+
50
+ # Changes Faraday adapter
51
+ config.adapter = :patron
52
+
53
+ # Merged with the default client options hash
54
+ config.client_options = { :ssl => false }
55
+
56
+ # When getting the error 'hostname does not match the server certificate'
57
+ # use the API at https://yoursubdomain.zendesk.com/api/v2
58
+ end
59
+ ```
60
+
61
+ Note: This ZendeskAPI API client only supports basic authentication at the moment.
62
+
63
+ ## Usage
64
+
65
+ The result of configuration is an instance of ZendeskAPI::Client which can then be used in two different methods.
66
+
67
+ One way to use the client is to pass it in as an argument to individual classes.
68
+
69
+ ```
70
+ ZendeskAPI::Ticket.new(client, :id => 1, :priority => "urgent") # doesn't actually send a request, must explicitly call #save
71
+ ZendeskAPI::Ticket.create(client, :subject => "Test Ticket", :description => "This is a test", :submitter_id => client.current_user.id, :priority => "urgent")
72
+ ZendeskAPI::Ticket.find(client, :id => 1)
73
+ ZendeskAPI::Ticket.delete(client, :id => 1)
74
+ ```
75
+
76
+ Another way is to use the instance methods under client.
77
+
78
+ ```
79
+ client.tickets.first
80
+ client.tickets.find(:id => 1)
81
+ client.tickets.create(:subject => "Test Ticket", :description => "This is a test", :submitter_id => client.current_user.id, :priority => "urgent")
82
+ client.tickets.delete(:id => 1)
83
+ ```
84
+
85
+ The methods under ZendeskAPI::Client (such as .tickets) return an instance of ZendeskAPI::Collection a lazy-loaded list of that resource.
86
+ Actual requests may not be sent until an explicit ZendeskAPI::Collection#fetch, ZendeskAPI::Collection#to_a, or an applicable methods such
87
+ as #each.
88
+
89
+ ### Pagination
90
+
91
+ ZendeskAPI::Collections can be paginated:
92
+
93
+ ```
94
+ tickets = client.tickets.page(2).per_page(3)
95
+ next_page = tickets.next
96
+ previous_page = tickets.prev
97
+ ```
98
+
99
+ ### Callbacks
100
+
101
+ Callbacks can be added to the ZendeskAPI::Client instance and will be called (with the response env) after all response middleware on a successful request.
102
+
103
+ ```
104
+ client.insert_callback do |env|
105
+ puts env[:response_headers]
106
+ end
107
+ ```
108
+
109
+ ### Resource management
110
+
111
+ Individual resources can be created, modified, saved, and destroyed.
112
+
113
+ ```
114
+ ticket = client.tickets[0] # ZendeskAPI::Ticket.find(client, :id => 1)
115
+ ticket.priority = "urgent"
116
+ ticket.attributes # => { "priority" => "urgent" }
117
+ ticket.save # Will PUT => true
118
+ ticket.destroy # => true
119
+
120
+ ZendeskAPI::Ticket.new(client, { :priority => "urgent" })
121
+ ticket.new_record? # => true
122
+ ticket.save # Will POST
123
+ ```
124
+
125
+ ### Special case: Custom resources paths
126
+
127
+ API endpoints such as tickets/recent or topics/show_many can be accessed through chaining.
128
+ They will too return an instance of ZendeskAPI::Collection.
129
+
130
+ ```
131
+ client.tickets.recent
132
+ client.topics.show_many(:verb => :post, :ids => [1, 2, 3])
133
+ ```
134
+
135
+ ### Special Case: Current user
136
+
137
+ Use either of the following to obtain the current user instance:
138
+
139
+ ```
140
+ client.users.find(:id => 'me')
141
+ client.current_user
142
+ ```
143
+
144
+ ### Attaching files
145
+
146
+ Files can be attached to tickets using either a path or the File class and will
147
+ be automatically uploaded and attached.
148
+
149
+ ```
150
+ ticket = Ticket.new(...)
151
+ ticket.uploads << "img.jpg"
152
+ ticket.uploads << File.new("img.jpg")
153
+ ticket.save
154
+ ```
155
+
156
+ ## TODO
157
+
158
+ * Search class detection
159
+ * Live Testing
160
+
161
+ ## Note on Patches/Pull Requests
162
+ 1. Fork the project.
163
+ 2. Make your feature addition or bug fix.
164
+ 3. Add tests for it. This is important so I don't break it in a future version
165
+ unintentionally.
166
+ 4. Commit, do not mess with rakefile, version, or history. (if you want to have
167
+ your own version, that is fine but bump version in a commit by itself I can
168
+ ignore when I pull)
169
+ 5. Send me a pull request. Bonus points for topic branches.
170
+
171
+ ## Supported Ruby Versions
172
+
173
+ Tested with Ruby 1.8.7 and 1.9.3
174
+ [![Build Status](https://secure.travis-ci.org/zendesk/zendesk_api_client_rb.png)](http://travis-ci.org/zendesk/zendesk_api_client_rb)
175
+
176
+ ## Copyright
177
+
178
+ See [LICENSE](https://github.com/zendesk/zendesk_api_client_rb/blob/master/LICENSE)
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require 'zendesk_api/core_ext/modulize'
5
+ require 'zendesk_api/core_ext/snakecase'
6
+ require 'zendesk_api/core_ext/inflection'
7
+ require 'zendesk_api/client'
8
+
9
+ module ZendeskAPI
10
+ end
@@ -0,0 +1,176 @@
1
+ module ZendeskAPI
2
+ module Save
3
+ # If this resource hasn't been deleted, then create or save it.
4
+ # Executes a POST if it is a {#new_record?}, otherwise a PUT.
5
+ # Merges returned attributes on success.
6
+ # @return [Boolean] Success?
7
+ def save(options={})
8
+ return false if respond_to?(:destroyed?) && destroyed?
9
+
10
+ if new_record?
11
+ method = :post
12
+ req_path = path
13
+ else
14
+ method = :put
15
+ req_path = url || path
16
+ end
17
+
18
+ req_path = options[:path] if options[:path]
19
+
20
+ save_associations
21
+
22
+ response = @client.connection.send(method, req_path) do |req|
23
+ req.body = if self.class.unnested_params
24
+ attributes.changes
25
+ else
26
+ {self.class.singular_resource_name.to_sym => attributes.changes}
27
+ end
28
+ end
29
+
30
+ @attributes.replace @attributes.deep_merge(response.body[self.class.singular_resource_name] || {})
31
+ @attributes.clear_changes
32
+ true
33
+ end
34
+
35
+ def save!(options={})
36
+ save(options) || raise("Save failed")
37
+ end
38
+
39
+ def save_associations
40
+ self.class.associations.each do |association_data|
41
+ association_name = association_data[:name]
42
+ next unless send("#{association_name}_used?") && association = send(association_name)
43
+
44
+ if association.respond_to?(:save) && (association.is_a?(Collection) || !association.changes.empty?)
45
+ association.save
46
+ self.send("#{association_name}=", association) # set id/ids columns
47
+ end
48
+
49
+ if association_data[:inline]
50
+ attributes[association_name] = (association.is_a?(Collection) ? association.map(&:to_param) : association.to_param)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ module Read
57
+ include Rescue
58
+
59
+ # Finds a resource by an id and any options passed in.
60
+ # A custom path to search at can be passed into opts. It defaults to the {DataResource.resource_name} of the class.
61
+ # @param [Client] client The {Client} object to be used
62
+ # @param [Hash] options Any additional GET parameters to be added
63
+ def find(client, options = {})
64
+ @client = client # so we can use client.logger in rescue
65
+
66
+ raise "No :id given" unless options[:id] || options["id"]
67
+ association = options.delete(:association) || Association.new(:class => self)
68
+
69
+ response = client.connection.get(association.generate_path(options)) do |req|
70
+ req.params = options
71
+ end
72
+
73
+ new(client, response.body[singular_resource_name])
74
+ end
75
+
76
+ rescue_client_error :find
77
+ end
78
+
79
+ module Create
80
+ include Save
81
+
82
+ def self.included(base)
83
+ base.extend(ClassMethods)
84
+ end
85
+
86
+ module ClassMethods
87
+ include Rescue
88
+
89
+ # Create a resource given the attributes passed in.
90
+ # @param [Client] client The {Client} object to be used
91
+ # @param [Hash] attributes The attributes to create.
92
+ def create(client, attributes = {})
93
+ ZendeskAPI::Client.check_deprecated_namespace_usage attributes, singular_resource_name
94
+ resource = new(client, attributes)
95
+ return unless resource.save
96
+ resource
97
+ end
98
+
99
+ def create!(client, attributes={})
100
+ c = create(client, attributes)
101
+ c || raise("Create failed #{self} #{attributes}")
102
+ end
103
+
104
+ rescue_client_error :create
105
+ end
106
+ end
107
+
108
+ module Destroy
109
+ include Rescue
110
+
111
+ def self.included(klass)
112
+ klass.extend(ClassMethod)
113
+ end
114
+
115
+ # Has this object been deleted?
116
+ def destroyed?
117
+ @destroyed ||= false
118
+ end
119
+
120
+ # If this resource hasn't already been deleted, then do so.
121
+ # @return [Boolean] Successful?
122
+ def destroy
123
+ return false if destroyed? || new_record?
124
+ @client.connection.delete(url || path)
125
+ @destroyed = true
126
+ end
127
+
128
+ rescue_client_error :destroy, :with => false
129
+
130
+ module ClassMethod
131
+ include Rescue
132
+
133
+ # Deletes a resource given the id passed in.
134
+ # @param [Client] client The {Client} object to be used
135
+ # @param [Hash] opts The optional parameters to pass. Defaults to {}
136
+ def destroy(client, opts = {})
137
+ @client = client # so we can use client.logger in rescue
138
+ association = opts.delete(:association) || Association.new(:class => self)
139
+
140
+ client.connection.delete(association.generate_path(opts)) do |req|
141
+ req.params = opts
142
+ end
143
+
144
+ true
145
+ end
146
+
147
+ rescue_client_error :destroy, :with => false
148
+ end
149
+ end
150
+
151
+ module Update
152
+ include Rescue
153
+ include Save
154
+
155
+ def self.included(klass)
156
+ klass.extend(ClassMethod)
157
+ end
158
+
159
+ rescue_client_error :save, :with => false
160
+
161
+ module ClassMethod
162
+ include Rescue
163
+
164
+ # Updates a resource given the id passed in.
165
+ # @param [Client] client The {Client} object to be used
166
+ # @param [Hash] attributes The attributes to update. Default to {}
167
+ def update(client, attributes = {})
168
+ ZendeskAPI::Client.check_deprecated_namespace_usage attributes, singular_resource_name
169
+ resource = new(client, attributes)
170
+ resource.save
171
+ end
172
+
173
+ rescue_client_error :update, :with => false
174
+ end
175
+ end
176
+ end