zoho_invoice 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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