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.
- data/lib/zoho_invoice.rb +2 -0
- data/lib/zoho_invoice/base.rb +21 -0
- data/lib/zoho_invoice/client.rb +2 -1
- data/lib/zoho_invoice/core_ext/string.rb +18 -0
- data/lib/zoho_invoice/customer.rb +0 -3
- data/lib/zoho_invoice/version.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- data/spec/zoho_invoice/base_spec.rb +96 -44
- data/spec/zoho_invoice/string_spec.rb +30 -0
- metadata +5 -2
data/lib/zoho_invoice.rb
CHANGED
data/lib/zoho_invoice/base.rb
CHANGED
@@ -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
|
|
data/lib/zoho_invoice/client.rb
CHANGED
@@ -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
|
data/lib/zoho_invoice/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -95,7 +95,7 @@ describe ZohoInvoice::Base do
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
describe "
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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.
|
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-
|
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
|