zoho_invoice 0.1.1 → 0.2.0

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.
@@ -3,6 +3,8 @@ require 'faraday_middleware'
3
3
  require 'nokogiri'
4
4
  require 'multi_xml'
5
5
 
6
+ require 'zoho_invoice/core_ext/string'
7
+
6
8
  require 'zoho_invoice/configurable'
7
9
  require 'zoho_invoice/auth_token'
8
10
  require 'zoho_invoice/defaults'
@@ -27,6 +27,27 @@ module ZohoInvoice
27
27
  self.new(client, options).save
28
28
  end
29
29
 
30
+ # TODO need to build a class that is something like ActiveRecord::Relation
31
+ # TODO need to be able to handle associations when hydrating objects
32
+ #
33
+ def self.search(client, input_text, options = {})
34
+ result_hash = client.get("/api/view/search/#{self.to_s.split('::').last.downcase}s", :searchtext => input_text).body
35
+ objects_to_hydrate = result_hash['Response']["#{self.to_s.split('::').last}s"]["#{self.to_s.split('::').last}"]
36
+ if objects_to_hydrate.nil?
37
+ return []
38
+ else
39
+ objects_to_hydrate.map do |result|
40
+ new_hash = {}
41
+ result.each do |key, value|
42
+ new_hash[key.to_underscore.to_sym] = value if !value.is_a?(Hash) && !value.is_a?(Array)
43
+ end
44
+ self.new(client, new_hash)
45
+ end
46
+ end
47
+ rescue Faraday::Error::ClientError => e
48
+ return []
49
+ end
50
+
30
51
  def initialize(client, options = {})
31
52
  @client = client
32
53
 
@@ -37,11 +37,12 @@ module ZohoInvoice
37
37
  def connection
38
38
  @connection ||= Faraday.new(@client_options) do |c|
39
39
  c.use Faraday::Response::RaiseError
40
- c.response :xml, :content_type => 'application/xml'
41
40
 
42
41
  c.request :multipart
43
42
  c.request :url_encoded
44
43
 
44
+ c.response :xml, :content_type => /\bxml$/
45
+
45
46
  c.adapter Faraday.default_adapter
46
47
  end
47
48
  end
@@ -0,0 +1,18 @@
1
+ module ZohoInvoiceStringExt
2
+ def camelcase
3
+ return self if self !~ /_/ && self =~ /[A-Z]+.*/
4
+ split('_').map{|e| e.capitalize}.join
5
+ end
6
+
7
+ def to_underscore!
8
+ g = gsub!(/(.)([A-Z])/,'\1_\2'); d = downcase!
9
+ g || d
10
+ end
11
+
12
+ def to_underscore
13
+ dup.tap { |s| s.to_underscore! }
14
+ end
15
+ end
16
+ class String
17
+ include ZohoInvoiceStringExt
18
+ end
@@ -21,8 +21,5 @@ module ZohoInvoice
21
21
 
22
22
  has_many :contacts
23
23
 
24
- def self.search(client, input_text)
25
- end
26
-
27
24
  end
28
25
  end
@@ -1,3 +1,3 @@
1
1
  module ZohoInvoice
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,7 +14,6 @@ require 'zoho_invoice'
14
14
  require 'webmock/rspec'
15
15
  require 'pry'
16
16
 
17
- Coveralls.wear!
18
17
  WebMock.disable_net_connect!
19
18
 
20
19
  RSpec.configure do |config|
@@ -95,7 +95,7 @@ describe ZohoInvoice::Base do
95
95
  end
96
96
  end
97
97
 
98
- describe "saving an object" do
98
+ describe "interactions" do
99
99
  before do
100
100
  class Something < ZohoInvoice::Base
101
101
  define_object_attrs :something_id, :blah
@@ -103,54 +103,106 @@ describe ZohoInvoice::Base do
103
103
  @test_obj = Something.new(@client)
104
104
  end
105
105
 
106
- it "calls the create path if its a new record" do
107
- @test_obj.something_id = nil
108
- body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
109
- stub_post('/api/somethings/create').
110
- with(:body => body_params).
111
- to_return(:status => 200, :body => successful_something_response('5555'), :headers => {:content_type => 'application/xml'})
112
- @test_obj.save
113
- expect(a_post('/api/somethings/create').with(:body => body_params)).to have_been_made
114
- end
115
-
116
- it "calls the update path if its a dirty record" do
117
- @test_obj.something_id = '123456'
118
- body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
119
- stub_post('/api/somethings/update').
120
- with(:body => body_params).
121
- to_return(:status => 200, :body => successful_something_response('123456'), :headers => {:content_type => 'application/xml'})
122
- @test_obj.save
123
- expect(a_post('/api/somethings/update').with(:body => body_params)).to have_been_made
124
- end
125
-
126
- it "can happen via .create" do
127
- @test_obj.blah = '1234'
128
- body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
129
- stub_post('/api/somethings/create').
130
- with(:body => body_params).
131
- to_return(:status => 200, :body => successful_something_response("1234"), :headers => { :content_type => 'application/xml' })
132
- test_obj = Something.create(@client, :blah => '1234')
133
- expect(a_post('/api/somethings/create').with(:body => body_params)).to have_been_made
134
- expect(test_obj.something_id).to eq('1')
135
- end
136
-
137
- it "returns the object and has an error method" do
138
- @test_obj.blah = '1234'
139
- body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
140
- stub_post('/api/somethings/create').with(:body => body_params).to_return(:status => 500, :body => fixture('500_internal_server_error'), :headers => { :content_type => 'application/xml' })
141
- test_obj = Something.create(@client, :blah => '1234')
142
- expect(test_obj.something_id).to be_nil
143
- expect(test_obj.errors.length).to eq(1)
144
- error = test_obj.errors.first
145
- expect(error.message).to eq("Invalid value passed for XMLString")
146
- expect(error.code).to eq('2')
147
- expect(error.status).to eq('0')
148
- expect(error.http_status).to eq(500)
106
+ describe "saving" do
107
+ it "calls the create path if its a new record" do
108
+ @test_obj.something_id = nil
109
+ body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
110
+ stub_post('/api/somethings/create').
111
+ with(:body => body_params).
112
+ to_return(:status => 200, :body => successful_something_response('5555'), :headers => {:content_type => 'application/xml'})
113
+ @test_obj.save
114
+ expect(a_post('/api/somethings/create').with(:body => body_params)).to have_been_made
115
+ end
116
+
117
+ it "calls the update path if its a dirty record" do
118
+ @test_obj.something_id = '123456'
119
+ body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
120
+ stub_post('/api/somethings/update').
121
+ with(:body => body_params).
122
+ to_return(:status => 200, :body => successful_something_response('123456'), :headers => {:content_type => 'application/xml'})
123
+ @test_obj.save
124
+ expect(a_post('/api/somethings/update').with(:body => body_params)).to have_been_made
125
+ end
126
+
127
+ it "can happen via .create" do
128
+ @test_obj.blah = '1234'
129
+ body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
130
+ stub_post('/api/somethings/create').
131
+ with(:body => body_params).
132
+ to_return(:status => 200, :body => successful_something_response("1234"), :headers => { :content_type => 'application/xml' })
133
+ test_obj = Something.create(@client, :blah => '1234')
134
+ expect(a_post('/api/somethings/create').with(:body => body_params)).to have_been_made
135
+ expect(test_obj.something_id).to eq('1')
136
+ end
137
+
138
+ it "returns the object and has an error method" do
139
+ @test_obj.blah = '1234'
140
+ body_params = default_credentials.merge(:XMLString => @test_obj.to_xml)
141
+ stub_post('/api/somethings/create').with(:body => body_params).to_return(:status => 500, :body => fixture('500_internal_server_error'), :headers => { :content_type => 'application/xml' })
142
+ test_obj = Something.create(@client, :blah => '1234')
143
+ expect(test_obj.something_id).to be_nil
144
+ expect(test_obj.errors.length).to eq(1)
145
+ error = test_obj.errors.first
146
+ expect(error.message).to eq("Invalid value passed for XMLString")
147
+ expect(error.code).to eq('2')
148
+ expect(error.status).to eq('0')
149
+ expect(error.http_status).to eq(500)
150
+ end
151
+ end
152
+
153
+ describe "searching" do
154
+ it "returns an array if it can find anything" do
155
+ body_params = default_credentials.merge(:searchtext => '1234')
156
+ stub_get('/api/view/search/somethings').
157
+ with(:query => body_params).
158
+ to_return(:status => 200, :body => successful_multiple_record_response('1234'), :headers => {:content_type => 'application/xml'})
159
+ result = Something.search(@client, '1234')
160
+ expect(a_get('/api/view/search/somethings').with(query: body_params)).to have_been_made
161
+ expect(result.class).to eq(Array)
162
+ expect(result.length).to eq(2)
163
+ result.each_with_index do |r, i|
164
+ expect(r.class).to eq(Something)
165
+ expect(r.something_id).to eq((i+1).to_s)
166
+ expect(r.blah).to eq('1234')
167
+ end
168
+ end
169
+
170
+ it "returns an empty array if it cant find anything" do
171
+ body_params = default_credentials.merge(:searchtext => '1234')
172
+ stub_get('/api/view/search/somethings').
173
+ with(:query => body_params).
174
+ to_return(:status => 200, :body => successful_empty_response, :headers => {:content_type => 'application/xml'})
175
+ result = Something.search(@client, '1234')
176
+ expect(a_get('/api/view/search/somethings').with(query: body_params)).to have_been_made
177
+ expect(result.class).to eq(Array)
178
+ expect(result.length).to eq(0)
179
+ end
180
+
181
+ # TODO Needs to change because you'll have no idea an error happened
182
+ #
183
+ it "should return an empty array if theres an error" do
184
+ body_params = default_credentials.merge(:searchtext => '1234')
185
+ stub_get('/api/view/search/somethings').
186
+ with(:query => body_params).
187
+ to_return(:status => 500)
188
+ result = Something.search(@client, '1234')
189
+ expect(a_get('/api/view/search/somethings').with(query: body_params)).to have_been_made
190
+ expect(result.class).to eq(Array)
191
+ expect(result.length).to eq(0)
192
+ end
149
193
  end
150
194
 
151
195
  def successful_something_response(blah_payload)
152
196
  "<Something><SomethingID>1</SomethingID><Blah>#{blah_payload}</Blah></Something>"
153
197
  end
198
+
199
+ def successful_multiple_record_response(payload)
200
+ "<Response><Somethings uri='/api/views/search/somethings'><Something><SomethingID>1</SomethingID><Blah>#{payload}</Blah></Something><Something><SomethingID>2</SomethingID><Blah>#{payload}</Blah></Something></Somethings></Response>"
201
+ end
202
+
203
+ def successful_empty_response
204
+ "<Response><Somethings uri='/api/views/search/somethings'></Somethings></Response>"
205
+ end
154
206
  end
155
207
 
156
208
  describe "nested associations" do
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+
5
+ it "should make a snake case string into camel case" do
6
+ expect("something_else".camelcase).to eq("SomethingElse")
7
+ end
8
+
9
+ it "should make a single word camelcase" do
10
+ expect("something".camelcase).to eq("Something")
11
+ end
12
+
13
+ it "should handle a string thats already camelcase" do
14
+ expect("Something".camelcase).to eq("Something")
15
+ expect("SomethingElse".camelcase).to eq("SomethingElse")
16
+ end
17
+
18
+ it "should convert a class name to underscore" do
19
+ expect(String.to_s.to_underscore).to eq('string')
20
+ end
21
+
22
+ it "should convert a string to underscore not creating copy" do
23
+ str = "SomethingElse"
24
+ id = str.object_id
25
+ rst = str.to_underscore!
26
+ expect(rst).to eq("something_else")
27
+ expect(id).to eq(rst.object_id)
28
+ end
29
+
30
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zoho_invoice
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-10 00:00:00.000000000 Z
12
+ date: 2013-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -113,6 +113,7 @@ files:
113
113
  - lib/zoho_invoice/collection.rb
114
114
  - lib/zoho_invoice/configurable.rb
115
115
  - lib/zoho_invoice/contact.rb
116
+ - lib/zoho_invoice/core_ext/string.rb
116
117
  - lib/zoho_invoice/customer.rb
117
118
  - lib/zoho_invoice/defaults.rb
118
119
  - lib/zoho_invoice/error.rb
@@ -134,6 +135,7 @@ files:
134
135
  - spec/zoho_invoice/client_spec.rb
135
136
  - spec/zoho_invoice/collection_spec.rb
136
137
  - spec/zoho_invoice/contact_spec.rb
138
+ - spec/zoho_invoice/string_spec.rb
137
139
  - spec/zoho_invoice_spec.rb
138
140
  - zoho_invoice.gemspec
139
141
  homepage: https://github.com/neovintage/zoho_invoice
@@ -175,4 +177,5 @@ test_files:
175
177
  - spec/zoho_invoice/client_spec.rb
176
178
  - spec/zoho_invoice/collection_spec.rb
177
179
  - spec/zoho_invoice/contact_spec.rb
180
+ - spec/zoho_invoice/string_spec.rb
178
181
  - spec/zoho_invoice_spec.rb