zendesk_api 0.0.9 → 0.1.1

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/.gitignore CHANGED
@@ -5,3 +5,4 @@ spec/fixtures/cassettes
5
5
  spec/fixtures/credentials.yml
6
6
  coverage
7
7
  .yardoc
8
+ example.rb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zendesk_api (0.0.9)
4
+ zendesk_api (0.1.0)
5
5
  faraday (>= 0.8.0)
6
6
  faraday_middleware (>= 0.8.7)
7
7
  hashie
@@ -18,11 +18,11 @@ GEM
18
18
  diff-lcs (1.1.3)
19
19
  faraday (0.8.1)
20
20
  multipart-post (~> 1.1)
21
- faraday_middleware (0.8.7)
21
+ faraday_middleware (0.8.8)
22
22
  faraday (>= 0.7.4, < 0.9)
23
23
  hashie (1.2.0)
24
24
  inflection (1.0.0)
25
- json (1.7.3)
25
+ json (1.7.4)
26
26
  mime-types (1.19)
27
27
  multi_json (1.3.6)
28
28
  multipart-post (1.1.5)
@@ -39,9 +39,9 @@ GEM
39
39
  multi_json (~> 1.0)
40
40
  simplecov-html (~> 0.5.3)
41
41
  simplecov-html (0.5.3)
42
- vcr (2.2.2)
43
- webmock (1.8.7)
44
- addressable (>= 2.2.7)
42
+ vcr (2.2.4)
43
+ webmock (1.8.8)
44
+ addressable (~> 2.2.8)
45
45
  crack (>= 0.1.7)
46
46
  yard (0.8.2.1)
47
47
 
@@ -51,7 +51,7 @@ PLATFORMS
51
51
  DEPENDENCIES
52
52
  jruby-openssl
53
53
  rake
54
- rspec (>= 2.0.0)
54
+ rspec (~> 2.10.0)
55
55
  simplecov
56
56
  vcr
57
57
  webmock
data/Readme.md CHANGED
@@ -10,31 +10,37 @@ Version 0.0.5 brings with it a change to the top-level namespace. All references
10
10
 
11
11
  ## Installation
12
12
 
13
- Currently
13
+ The Zendesk API client can be installed using Rubygems or Bundler.
14
14
 
15
- gem install zendesk_api
15
+ ### Rubygems
16
16
 
17
- will not install this version of the API client. To install this client, either clone this repository and run
17
+ ```sh
18
+ gem install zendesk_api
19
+ ```
20
+
21
+ ### Bundler
18
22
 
19
- rake install
23
+ Add it to your Gemfile
20
24
 
21
- or add it to a Gemfile like so:
25
+ gem "zendesk_api"
22
26
 
23
- gem "zendesk_api", :git => "git://github.com/zendesk/zendesk_api_client_rb.git" #, :tag => "vX.X.X"
27
+ and follow normal [Bundler](http://gembundler.com/) installation and execution procedures.
24
28
 
25
29
  ## Configuration
26
30
 
27
31
  Configuration is done through a block returning an instance of ZendeskAPI::Client.
28
32
  The block is mandatory and if not passed, an ArgumentError will be thrown.
29
33
 
30
- ```
31
- ZendeskAPI::Client.new do |config|
34
+ ```ruby
35
+ require 'zendesk_api'
36
+
37
+ client = ZendeskAPI::Client.new do |config|
32
38
  # Mandatory:
33
39
 
34
- config.url = "https://mydesk.zendesk.com/api/v2"
40
+ config.url = "<- your-zendesk-url ->" # e.g. https://mydesk.zendesk.com/api/v2
35
41
 
36
- config.username = "test.user"
37
- config.password = "test.password"
42
+ config.username = "login.email@zendesk.com"
43
+ config.password = "your zendesk password or token"
38
44
 
39
45
  # Optional:
40
46
 
@@ -48,12 +54,12 @@ ZendeskAPI::Client.new do |config|
48
54
  config.logger = Logger.new(STDOUT)
49
55
 
50
56
  # Changes Faraday adapter
51
- config.adapter = :patron
57
+ # config.adapter = :patron
52
58
 
53
59
  # Merged with the default client options hash
54
- config.client_options = { :ssl => false }
60
+ # config.client_options = { :ssl => false }
55
61
 
56
- # When getting the error 'hostname does not match the server certificate'
62
+ # When getting the error 'hostname does not match the server certificate'
57
63
  # use the API at https://yoursubdomain.zendesk.com/api/v2
58
64
  end
59
65
  ```
@@ -66,19 +72,19 @@ The result of configuration is an instance of ZendeskAPI::Client which can then
66
72
 
67
73
  One way to use the client is to pass it in as an argument to individual classes.
68
74
 
69
- ```
75
+ ```ruby
70
76
  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")
77
+ ZendeskAPI::Ticket.create(client, :subject => "Test Ticket", :comment => { :value => "This is a test" }, :submitter_id => client.current_user.id, :priority => "urgent")
72
78
  ZendeskAPI::Ticket.find(client, :id => 1)
73
79
  ZendeskAPI::Ticket.delete(client, :id => 1)
74
80
  ```
75
81
 
76
82
  Another way is to use the instance methods under client.
77
83
 
78
- ```
84
+ ```ruby
79
85
  client.tickets.first
80
86
  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")
87
+ client.tickets.create(:subject => "Test Ticket", :comment => { :value => "This is a test" }, :submitter_id => client.current_user.id, :priority => "urgent")
82
88
  client.tickets.delete(:id => 1)
83
89
  ```
84
90
 
@@ -90,7 +96,7 @@ as #each.
90
96
 
91
97
  ZendeskAPI::Collections can be paginated:
92
98
 
93
- ```
99
+ ```ruby
94
100
  tickets = client.tickets.page(2).per_page(3)
95
101
  next_page = tickets.next
96
102
  previous_page = tickets.prev
@@ -100,7 +106,7 @@ previous_page = tickets.prev
100
106
 
101
107
  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
108
 
103
- ```
109
+ ```ruby
104
110
  client.insert_callback do |env|
105
111
  puts env[:response_headers]
106
112
  end
@@ -110,7 +116,7 @@ end
110
116
 
111
117
  Individual resources can be created, modified, saved, and destroyed.
112
118
 
113
- ```
119
+ ```ruby
114
120
  ticket = client.tickets[0] # ZendeskAPI::Ticket.find(client, :id => 1)
115
121
  ticket.priority = "urgent"
116
122
  ticket.attributes # => { "priority" => "urgent" }
@@ -127,7 +133,7 @@ ticket.save # Will POST
127
133
  API endpoints such as tickets/recent or topics/show_many can be accessed through chaining.
128
134
  They will too return an instance of ZendeskAPI::Collection.
129
135
 
130
- ```
136
+ ```ruby
131
137
  client.tickets.recent
132
138
  client.topics.show_many(:verb => :post, :ids => [1, 2, 3])
133
139
  ```
@@ -136,20 +142,20 @@ client.topics.show_many(:verb => :post, :ids => [1, 2, 3])
136
142
 
137
143
  Use either of the following to obtain the current user instance:
138
144
 
139
- ```
145
+ ```ruby
140
146
  client.users.find(:id => 'me')
141
147
  client.current_user
142
148
  ```
143
149
 
144
150
  ### Attaching files
145
151
 
146
- Files can be attached to tickets using either a path or the File class and will
152
+ Files can be attached to ticket comments using either a path or the File class and will
147
153
  be automatically uploaded and attached.
148
154
 
149
- ```
150
- ticket = Ticket.new(...)
151
- ticket.uploads << "img.jpg"
152
- ticket.uploads << File.new("img.jpg")
155
+ ```ruby
156
+ ticket = ZendeskAPI::Ticket.new(client, :comment => { :value => "attachments" })
157
+ ticket.comment.uploads << "img.jpg"
158
+ ticket.comment.uploads << File.new("img.jpg")
153
159
  ticket.save
154
160
  ```
155
161
 
@@ -239,9 +239,9 @@ module ZendeskAPI
239
239
  end
240
240
 
241
241
  class << self
242
- # Revert Rails' overwrite of const_missing
243
- if method_defined?(:const_missing_without_dependencies)
244
- alias :const_missing :const_missing_without_dependencies
242
+ # Make sure Rails' overwriting of const_missing doesn't cause trouble
243
+ def const_missing(*args)
244
+ Object.const_missing(*args)
245
245
  end
246
246
 
247
247
  # Allows using has and has_many without having class defined yet
@@ -212,7 +212,11 @@ module ZendeskAPI
212
212
 
213
213
  # Sends methods to underlying array of resources.
214
214
  def method_missing(name, *args, &block)
215
- if Array.new.respond_to?(name)
215
+ methods = @resource_class.singleton_methods(false).map(&:to_sym)
216
+
217
+ if methods.include?(name)
218
+ @resource_class.send(name, @client, *args, &block)
219
+ elsif Array.new.respond_to?(name)
216
220
  to_a.send(name, *args, &block)
217
221
  else
218
222
  opts = args.last.is_a?(Hash) ? args.last : {}
@@ -6,25 +6,64 @@ module ZendeskAPI
6
6
  module Request
7
7
  class Upload < Faraday::Middleware
8
8
  def call(env)
9
- if env[:body] && env[:body][:file]
10
- file = env[:body].delete(:file)
11
- case file
12
- when File
13
- path = file.path
14
- when String
15
- path = file
16
- else
17
- warn "WARNING: Passed invalid filename #{file} of type #{file.class} to upload"
18
- end
9
+ if env[:body]
10
+ set_file(env[:body], :file, true)
11
+ traverse_hash(env[:body])
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+
17
+ private
18
+
19
+ # Sets the proper file parameters :uploaded_data and :filename
20
+ # If top_level, then it removes key and and sets the parameters directly on hash,
21
+ # otherwise it adds the parameters to hash[key]
22
+ def set_file(hash, key, top_level)
23
+ return unless hash.key?(key)
24
+
25
+ file = if hash[key].is_a?(Hash) && hash[key].key?(:file)
26
+ hash[key].delete(:file)
27
+ else
28
+ hash.delete(key)
29
+ end
19
30
 
20
- if path
21
- env[:body][:filename] ||= File.basename(path)
22
- mime_type = MIME::Types.type_for(path).first || "application/octet-stream"
23
- env[:body][:uploaded_data] = Faraday::UploadIO.new(path, mime_type)
31
+ case file
32
+ when File
33
+ path = file.path
34
+ when String
35
+ path = file
36
+ else
37
+ warn "WARNING: Passed invalid filename #{file} of type #{file.class} to upload"
38
+ end
39
+
40
+ if path
41
+ if !top_level
42
+ hash[key] ||= {}
43
+ hash = hash[key]
24
44
  end
45
+
46
+ mime_type = MIME::Types.type_for(path).first || "application/octet-stream"
47
+
48
+ hash[:filename] ||= File.basename(path)
49
+ hash[:uploaded_data] = Faraday::UploadIO.new(path, mime_type)
25
50
  end
51
+ end
26
52
 
27
- @app.call(env)
53
+ # Calls #set_file on File instances or Hashes
54
+ # of the format { :file => File (, :filename => ...) }
55
+ def traverse_hash(hash)
56
+ hash.keys.each do |key|
57
+ if hash[key].is_a?(File)
58
+ set_file(hash, key, false)
59
+ elsif hash[key].is_a?(Hash)
60
+ if hash[key].key?(:file)
61
+ set_file(hash, key, false)
62
+ else
63
+ traverse_hash(hash[key])
64
+ end
65
+ end
66
+ end
28
67
  end
29
68
  end
30
69
  end
@@ -125,7 +125,7 @@ module ZendeskAPI
125
125
  extend Read
126
126
  include Create
127
127
 
128
- include Update
128
+ include Update
129
129
  include Destroy
130
130
  end
131
131
 
@@ -23,7 +23,7 @@ module ZendeskAPI
23
23
  has :ticket
24
24
  has :group
25
25
  end
26
-
26
+
27
27
  class Attachment < Data
28
28
  def initialize(client, attributes)
29
29
  if attributes.is_a?(Hash)
@@ -34,7 +34,7 @@ module ZendeskAPI
34
34
  end
35
35
 
36
36
  def save
37
- upload = Upload.create!(client, :file => file)
37
+ upload = Upload.create!(@client, :file => file)
38
38
  self.token = upload.token
39
39
  end
40
40
 
@@ -1,6 +1,19 @@
1
1
  module ZendeskAPI
2
2
  class TicketField < Resource; end
3
- class TicketComment < Data; end
3
+
4
+ class TicketComment < Data
5
+ include Save
6
+
7
+ has_many :uploads, :class => :attachment, :inline => true
8
+
9
+ def save
10
+ save_associations
11
+ true
12
+ end
13
+
14
+ alias :save! :save
15
+ end
16
+
4
17
  class TicketMetric < ReadResource; end
5
18
 
6
19
  class Ticket < Resource
@@ -17,7 +30,6 @@ module ZendeskAPI
17
30
  has :forum_topic, :class => :topic
18
31
  has :organization
19
32
 
20
- has_many :uploads, :class => :attachment, :inline => true
21
33
  has :comment, :class => :ticket_comment, :inline => true
22
34
 
23
35
  # Gets a incremental export of tickets from the start_time until now.
@@ -71,6 +83,4 @@ module ZendeskAPI
71
83
  Zendesk::Collection.new(client, ViewRow, options.merge(:path => "views/preview"))
72
84
  end
73
85
  end
74
-
75
-
76
86
  end
@@ -1,3 +1,3 @@
1
1
  module ZendeskAPI
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.1"
3
3
  end
data/live/ticket_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe ZendeskAPI::Ticket do
5
5
  {
6
6
  :type => "question",
7
7
  :subject => "This is a question?",
8
- :description => "Indeed it is!",
8
+ :comment => { :value => "Indeed it is!" },
9
9
  :priority => "normal",
10
10
  :requester_id => user.id,
11
11
  :submitter_id => user.id
@@ -66,12 +66,12 @@ describe ZendeskAPI::Ticket do
66
66
  it "can upload while creating" do
67
67
  VCR.use_cassette("ticket_inline_uploads") do
68
68
  ticket = ZendeskAPI::Ticket.new(client, valid_attributes.merge(default_options))
69
- ticket.uploads << "spec/fixtures/Argentina.gif"
70
- #ticket.uploads << File.new("spec/fixtures/Argentina.gif") # TODO ZendeskAPI bug: you can only upload 1 picture at a time
69
+ ticket.comment.uploads << "spec/fixtures/Argentina.gif"
70
+ ticket.comment.uploads << File.new("spec/fixtures/Argentina.gif")
71
71
 
72
72
  ticket.save!
73
- ticket.changes.should == {} # uploads where set before save
74
- ticket.attributes[:uploads].map(&:class).should == [String] # upload was sent as tokens
73
+ ticket.changes.should == {} # uploads were set before save
74
+ ticket.comment.attributes[:uploads].map(&:class).should == [String, String] # upload was sent as tokens
75
75
  end
76
76
  end
77
77
 
data/live/user_spec.rb CHANGED
@@ -10,4 +10,10 @@ describe ZendeskAPI::User, :delete_after do
10
10
  it_should_be_deletable :find => [:active?, false]
11
11
  it_should_be_readable :users
12
12
  it_should_be_readable organization, :users
13
+
14
+ it "should be able to find by email" do
15
+ VCR.use_cassette("user_find_by_email") do
16
+ client.users.search(:query => current_user.email).to_a.should == [current_user]
17
+ end
18
+ end
13
19
  end
@@ -266,6 +266,12 @@ describe ZendeskAPI::Collection do
266
266
  context "method missing" do
267
267
  before(:each) { subject.stub(:fetch).and_return([1, 2, nil, 3]) }
268
268
 
269
+ context "with an class method on the resource class" do
270
+ it "should pass methods to class if defined" do
271
+ subject.test.should == "hi"
272
+ end
273
+ end
274
+
269
275
  it "should pass all methods not defined to resources" do
270
276
  subject.compact.should == [1, 2, 3]
271
277
  end
@@ -1,4 +1,8 @@
1
1
  class ZendeskAPI::TestResource < ZendeskAPI::Resource
2
+ def self.test(client)
3
+ "hi"
4
+ end
5
+
2
6
  class TestChild < ZendeskAPI::Resource
3
7
  end
4
8
  end
@@ -45,29 +45,61 @@ describe ZendeskAPI::Middleware::Request::Upload do
45
45
  end
46
46
 
47
47
  context "with file instance" do
48
- before(:each) do
49
- @env = subject.call(:body => { :file => File.new(filename) })
50
- end
48
+ context "top-level" do
49
+ before(:each) do
50
+ @env = subject.call(:body => { :file => File.new(filename) })
51
+ end
51
52
 
52
- it "should convert file string to UploadIO" do
53
- @env[:body][:uploaded_data].should be_instance_of(Faraday::UploadIO)
54
- end
53
+ it "should convert file string to UploadIO" do
54
+ @env[:body][:uploaded_data].should be_instance_of(Faraday::UploadIO)
55
+ end
55
56
 
56
- it "should remove file string" do
57
- @env[:body][:file].should be_nil
58
- end
57
+ it "should remove file string" do
58
+ @env[:body][:file].should be_nil
59
+ end
59
60
 
60
- it "should add filename if none exist" do
61
- @env[:body][:filename].should == "test.jpg"
61
+ it "should add filename if none exist" do
62
+ @env[:body][:filename].should == "test.jpg"
63
+ end
64
+
65
+ context "with filename" do
66
+ before(:each) do
67
+ @env = subject.call(:body => { :file => File.new(filename), :filename => "test" })
68
+ end
69
+
70
+ it "should not change filename" do
71
+ @env[:body][:filename].should_not == "test.jpg"
72
+ end
73
+ end
62
74
  end
63
75
 
64
- context "with filename" do
65
- before(:each) do
66
- @env = subject.call(:body => { :file => File.new(filename), :filename => "test" })
76
+ context "underneath a key" do
77
+ context "only a file" do
78
+ before(:each) do
79
+ @env = subject.call(:body => { :user => { :photo => File.new(filename) } })
80
+ end
81
+
82
+ it "should convert file string to UploadIO" do
83
+ @env[:body][:user][:photo][:uploaded_data].should be_instance_of(Faraday::UploadIO)
84
+ end
85
+
86
+ it "should add filename if none exist" do
87
+ @env[:body][:user][:photo][:filename].should == "test.jpg"
88
+ end
67
89
  end
68
90
 
69
- it "should not change filename" do
70
- @env[:body][:filename].should_not == "test.jpg"
91
+ context "with filename" do
92
+ before(:each) do
93
+ @env = subject.call(:body => { :user => { :photo => { :file => File.new(filename), :filename => "test" } } })
94
+ end
95
+
96
+ it "should convert file string to UploadIO" do
97
+ @env[:body][:user][:photo][:uploaded_data].should be_instance_of(Faraday::UploadIO)
98
+ end
99
+
100
+ it "should not change filename" do
101
+ @env[:body][:user][:photo][:filename].should_not == "test.jpg"
102
+ end
71
103
  end
72
104
  end
73
105
  end
data/zendesk_api.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.required_ruby_version = ">= 1.8.7"
19
19
  s.required_rubygems_version = ">= 1.3.6"
20
20
 
21
- s.add_development_dependency "rspec", ">= 2.0.0"
21
+ s.add_development_dependency "rspec", "~> 2.10.0"
22
22
  s.add_development_dependency "vcr"
23
23
  s.add_development_dependency "webmock"
24
24
  s.add_development_dependency "rake"
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.0.9
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-29 00:00:00.000000000 Z
12
+ date: 2012-08-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.0.0
21
+ version: 2.10.0
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 2.0.0
29
+ version: 2.10.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: vcr
32
32
  requirement: !ruby/object:Gem::Requirement