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.
- 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
|