xero_gateway 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.textile +51 -0
- data/LICENSE +14 -0
- data/README.textile +289 -0
- data/Rakefile +14 -0
- data/examples/oauth.rb +25 -0
- data/init.rb +1 -0
- data/lib/xero_gateway/account.rb +78 -0
- data/lib/xero_gateway/accounts_list.rb +77 -0
- data/lib/xero_gateway/address.rb +97 -0
- data/lib/xero_gateway/ca-certificates.crt +2560 -0
- data/lib/xero_gateway/contact.rb +206 -0
- data/lib/xero_gateway/currency.rb +56 -0
- data/lib/xero_gateway/dates.rb +25 -0
- data/lib/xero_gateway/error.rb +18 -0
- data/lib/xero_gateway/exceptions.rb +41 -0
- data/lib/xero_gateway/gateway.rb +363 -0
- data/lib/xero_gateway/http.rb +128 -0
- data/lib/xero_gateway/http_encoding_helper.rb +49 -0
- data/lib/xero_gateway/invoice.rb +278 -0
- data/lib/xero_gateway/line_item.rb +123 -0
- data/lib/xero_gateway/money.rb +16 -0
- data/lib/xero_gateway/oauth.rb +56 -0
- data/lib/xero_gateway/organisation.rb +61 -0
- data/lib/xero_gateway/payment.rb +40 -0
- data/lib/xero_gateway/phone.rb +77 -0
- data/lib/xero_gateway/private_app.rb +17 -0
- data/lib/xero_gateway/response.rb +37 -0
- data/lib/xero_gateway/tax_rate.rb +63 -0
- data/lib/xero_gateway/tracking_category.rb +62 -0
- data/lib/xero_gateway.rb +33 -0
- data/test/integration/accounts_list_test.rb +109 -0
- data/test/integration/create_contact_test.rb +66 -0
- data/test/integration/create_invoice_test.rb +49 -0
- data/test/integration/get_accounts_test.rb +23 -0
- data/test/integration/get_contact_test.rb +28 -0
- data/test/integration/get_contacts_test.rb +40 -0
- data/test/integration/get_currencies_test.rb +25 -0
- data/test/integration/get_invoice_test.rb +48 -0
- data/test/integration/get_invoices_test.rb +90 -0
- data/test/integration/get_organisation_test.rb +24 -0
- data/test/integration/get_tax_rates_test.rb +25 -0
- data/test/integration/get_tracking_categories_test.rb +26 -0
- data/test/integration/update_contact_test.rb +31 -0
- data/test/stub_responses/accounts.xml +1 -0
- data/test/stub_responses/api_exception.xml +153 -0
- data/test/stub_responses/contact.xml +1 -0
- data/test/stub_responses/contacts.xml +2189 -0
- data/test/stub_responses/create_invoice.xml +64 -0
- data/test/stub_responses/currencies.xml +16 -0
- data/test/stub_responses/invalid_api_key_error.xml +1 -0
- data/test/stub_responses/invalid_consumer_key +1 -0
- data/test/stub_responses/invalid_request_token +1 -0
- data/test/stub_responses/invoice.xml +1 -0
- data/test/stub_responses/invoice_not_found_error.xml +1 -0
- data/test/stub_responses/invoices.xml +1 -0
- data/test/stub_responses/organisation.xml +14 -0
- data/test/stub_responses/tax_rates.xml +52 -0
- data/test/stub_responses/token_expired +1 -0
- data/test/stub_responses/tracking_categories.xml +1 -0
- data/test/stub_responses/unknown_error.xml +1 -0
- data/test/test_helper.rb +81 -0
- data/test/unit/account_test.rb +34 -0
- data/test/unit/contact_test.rb +97 -0
- data/test/unit/currency_test.rb +31 -0
- data/test/unit/gateway_test.rb +79 -0
- data/test/unit/invoice_test.rb +302 -0
- data/test/unit/oauth_test.rb +110 -0
- data/test/unit/organisation_test.rb +34 -0
- data/test/unit/tax_rate_test.rb +38 -0
- data/test/unit/tracking_category_test.rb +30 -0
- data/test/xsd/README +2 -0
- data/test/xsd/create_contact.xsd +61 -0
- data/test/xsd/create_invoice.xsd +107 -0
- data/xero_gateway.gemspec +87 -0
- metadata +172 -0
@@ -0,0 +1,302 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class InvoiceTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
# @schema = LibXML::XML::Schema.document(LibXML::XML::Document.file(File.join(File.dirname(__FILE__), '../xsd/create_invoice.xsd')))
|
7
|
+
end
|
8
|
+
|
9
|
+
# NB: Xero no longer appears to provide XSDs for their api, check http://blog.xero.com/developer/api/invoices/
|
10
|
+
#
|
11
|
+
# Tests that the XML generated from an invoice object validates against the Xero XSD
|
12
|
+
# def test_build_xml
|
13
|
+
# invoice = create_test_invoice
|
14
|
+
#
|
15
|
+
# message = invoice.to_xml
|
16
|
+
#
|
17
|
+
# # Check that the document matches the XSD
|
18
|
+
# assert LibXML::XML::Parser.string(message).parse.validate_schema(@schema), "The XML document generated did not validate against the XSD"
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Tests that an invoice can be converted into XML that Xero can understand, and then converted back to an invoice
|
22
|
+
def test_build_and_parse_xml
|
23
|
+
invoice = create_test_invoice
|
24
|
+
|
25
|
+
# Generate the XML message
|
26
|
+
invoice_as_xml = invoice.to_xml
|
27
|
+
|
28
|
+
# Parse the XML message and retrieve the invoice element
|
29
|
+
invoice_element = REXML::XPath.first(REXML::Document.new(invoice_as_xml), "/Invoice")
|
30
|
+
|
31
|
+
# Build a new invoice from the XML
|
32
|
+
result_invoice = XeroGateway::Invoice.from_xml(invoice_element)
|
33
|
+
|
34
|
+
assert_equal(invoice, result_invoice)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Tests the sub_total calculation and that setting it manually doesn't modify the data.
|
38
|
+
def test_invoice_sub_total_calculation
|
39
|
+
invoice = create_test_invoice
|
40
|
+
line_item = invoice.line_items.first
|
41
|
+
|
42
|
+
# Make sure that everything adds up to begin with.
|
43
|
+
expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
|
44
|
+
assert_equal(expected_sub_total, invoice.sub_total)
|
45
|
+
|
46
|
+
# Change the sub_total and check that it doesn't modify anything.
|
47
|
+
invoice.sub_total = expected_sub_total * 10
|
48
|
+
assert_equal(expected_sub_total, invoice.sub_total)
|
49
|
+
|
50
|
+
# Change the amount of the first line item and make sure that
|
51
|
+
# everything still continues to add up.
|
52
|
+
line_item.unit_amount = line_item.unit_amount + 10
|
53
|
+
assert_not_equal(expected_sub_total, invoice.sub_total)
|
54
|
+
expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
|
55
|
+
assert_equal(expected_sub_total, invoice.sub_total)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Tests the total_tax calculation and that setting it manually doesn't modify the data.
|
59
|
+
def test_invoice_sub_total_calculation
|
60
|
+
invoice = create_test_invoice
|
61
|
+
line_item = invoice.line_items.first
|
62
|
+
|
63
|
+
# Make sure that everything adds up to begin with.
|
64
|
+
expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
|
65
|
+
assert_equal(expected_total_tax, invoice.total_tax)
|
66
|
+
|
67
|
+
# Change the total_tax and check that it doesn't modify anything.
|
68
|
+
invoice.total_tax = expected_total_tax * 10
|
69
|
+
assert_equal(expected_total_tax, invoice.total_tax)
|
70
|
+
|
71
|
+
# Change the tax_amount of the first line item and make sure that
|
72
|
+
# everything still continues to add up.
|
73
|
+
line_item.tax_amount = line_item.tax_amount + 10
|
74
|
+
assert_not_equal(expected_total_tax, invoice.total_tax)
|
75
|
+
expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
|
76
|
+
assert_equal(expected_total_tax, invoice.total_tax)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Tests the total calculation and that setting it manually doesn't modify the data.
|
80
|
+
def test_invoice_sub_total_calculation
|
81
|
+
invoice = create_test_invoice
|
82
|
+
line_item = invoice.line_items.first
|
83
|
+
|
84
|
+
# Make sure that everything adds up to begin with.
|
85
|
+
expected_total = invoice.sub_total + invoice.total_tax
|
86
|
+
assert_equal(expected_total, invoice.total)
|
87
|
+
|
88
|
+
# Change the total and check that it doesn't modify anything.
|
89
|
+
invoice.total = expected_total * 10
|
90
|
+
assert_equal(expected_total, invoice.total)
|
91
|
+
|
92
|
+
# Change the quantity of the first line item and make sure that
|
93
|
+
# everything still continues to add up.
|
94
|
+
line_item.quantity = line_item.quantity + 5
|
95
|
+
assert_not_equal(expected_total, invoice.total)
|
96
|
+
expected_total = invoice.sub_total + invoice.total_tax
|
97
|
+
assert_equal(expected_total, invoice.total)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Tests that the LineItem#line_amount calculation is working correctly.
|
101
|
+
def test_line_amount_calculation
|
102
|
+
invoice = create_test_invoice
|
103
|
+
line_item = invoice.line_items.first
|
104
|
+
|
105
|
+
# Make sure that everything adds up to begin with.
|
106
|
+
expected_amount = line_item.quantity * line_item.unit_amount
|
107
|
+
assert_equal(expected_amount, line_item.line_amount)
|
108
|
+
|
109
|
+
# Change the line_amount and check that it doesn't modify anything.
|
110
|
+
line_item.line_amount = expected_amount * 10
|
111
|
+
assert_equal(expected_amount, line_item.line_amount)
|
112
|
+
|
113
|
+
# Change the quantity and check that the line_amount has been updated.
|
114
|
+
quantity = line_item.quantity + 2
|
115
|
+
line_item.quantity = quantity
|
116
|
+
assert_not_equal(expected_amount, line_item.line_amount)
|
117
|
+
assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Ensure that the totalling methods don't raise exceptions, even when
|
121
|
+
# invoice.line_items is empty.
|
122
|
+
def test_totalling_methods_when_line_items_empty
|
123
|
+
invoice = create_test_invoice
|
124
|
+
invoice.line_items = []
|
125
|
+
|
126
|
+
assert_nothing_raised(Exception) {
|
127
|
+
assert_equal(BigDecimal.new('0'), invoice.sub_total)
|
128
|
+
assert_equal(BigDecimal.new('0'), invoice.total_tax)
|
129
|
+
assert_equal(BigDecimal.new('0'), invoice.total)
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_invoice_type_helper_methods
|
134
|
+
# Test accounts receivable invoices.
|
135
|
+
invoice = create_test_invoice({:invoice_type => 'ACCREC'})
|
136
|
+
assert_equal(true, invoice.accounts_receivable?, "Accounts RECEIVABLE invoice doesn't think it is.")
|
137
|
+
assert_equal(false, invoice.accounts_payable?, "Accounts RECEIVABLE invoice thinks it's payable.")
|
138
|
+
|
139
|
+
# Test accounts payable invoices.
|
140
|
+
invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
|
141
|
+
assert_equal(false, invoice.accounts_receivable?, "Accounts PAYABLE invoice doesn't think it is.")
|
142
|
+
assert_equal(true, invoice.accounts_payable?, "Accounts PAYABLE invoice thinks it's receivable.")
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
# Make sure that the create_test_invoice method is working correctly
|
147
|
+
# with all the defaults and overrides.
|
148
|
+
def test_create_test_invoice_defaults_working
|
149
|
+
invoice = create_test_invoice
|
150
|
+
|
151
|
+
# Test invoice defaults.
|
152
|
+
assert_equal('ACCREC', invoice.invoice_type)
|
153
|
+
assert_kind_of(Date, invoice.date)
|
154
|
+
assert_kind_of(Date, invoice.due_date)
|
155
|
+
assert_equal('12345', invoice.invoice_number)
|
156
|
+
assert_equal('MY REFERENCE FOR THIS INVOICE', invoice.reference)
|
157
|
+
assert_equal("Exclusive", invoice.line_amount_types)
|
158
|
+
|
159
|
+
# Test the contact defaults.
|
160
|
+
assert_equal('00000000-0000-0000-0000-000000000000', invoice.contact.contact_id)
|
161
|
+
assert_equal('CONTACT NAME', invoice.contact.name)
|
162
|
+
|
163
|
+
# Test address defaults.
|
164
|
+
assert_equal('DEFAULT', invoice.contact.address.address_type)
|
165
|
+
assert_equal('LINE 1 OF THE ADDRESS', invoice.contact.address.line_1)
|
166
|
+
|
167
|
+
# Test phone defaults.
|
168
|
+
assert_equal('DEFAULT', invoice.contact.phone.phone_type)
|
169
|
+
assert_equal('12345678', invoice.contact.phone.number)
|
170
|
+
|
171
|
+
# Test the line_item defaults.
|
172
|
+
assert_equal('A LINE ITEM', invoice.line_items.first.description)
|
173
|
+
assert_equal('200', invoice.line_items.first.account_code)
|
174
|
+
assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
|
175
|
+
assert_equal(BigDecimal.new('12.5'), invoice.line_items.first.tax_amount)
|
176
|
+
|
177
|
+
# Test overriding an invoice parameter (assume works for all).
|
178
|
+
invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
|
179
|
+
assert_equal('ACCPAY', invoice.invoice_type)
|
180
|
+
|
181
|
+
# Test overriding a contact/address/phone parameter (assume works for all).
|
182
|
+
invoice = create_test_invoice({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
|
183
|
+
assert_equal('OVERRIDDEN NAME', invoice.contact.name)
|
184
|
+
assert_equal('OVERRIDDEN LINE 1', invoice.contact.address.line_1)
|
185
|
+
assert_equal('999', invoice.contact.phone.number)
|
186
|
+
|
187
|
+
# Test overriding line_items with hash.
|
188
|
+
invoice = create_test_invoice({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
|
189
|
+
assert_equal(1, invoice.line_items.size)
|
190
|
+
assert_equal('OVERRIDDEN LINE ITEM', invoice.line_items.first.description)
|
191
|
+
assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
|
192
|
+
|
193
|
+
# Test overriding line_items with array of 2 line_items.
|
194
|
+
invoice = create_test_invoice({}, {}, [
|
195
|
+
{:description => 'OVERRIDDEN ITEM 1'},
|
196
|
+
{:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal.new('200'), :tax_amount => '25.0'}
|
197
|
+
])
|
198
|
+
assert_equal(2, invoice.line_items.size)
|
199
|
+
assert_equal('OVERRIDDEN ITEM 1', invoice.line_items[0].description)
|
200
|
+
assert_equal(BigDecimal.new('100'), invoice.line_items[0].unit_amount)
|
201
|
+
assert_equal('OVERRIDDEN ITEM 2', invoice.line_items[1].description)
|
202
|
+
assert_equal(BigDecimal.new('200'), invoice.line_items[1].unit_amount)
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_auto_creation_of_associated_contact
|
206
|
+
invoice = create_test_invoice({}, nil) # no contact
|
207
|
+
assert_nil(invoice.instance_variable_get("@contact"))
|
208
|
+
|
209
|
+
new_contact = invoice.contact
|
210
|
+
assert_kind_of(XeroGateway::Contact, new_contact)
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_add_line_item
|
214
|
+
invoice = create_test_invoice({}, {}, nil) # no line_items
|
215
|
+
assert_equal(0, invoice.line_items.size)
|
216
|
+
|
217
|
+
line_item_params = {:description => "Test Item 1", :unit_amount => 100}
|
218
|
+
|
219
|
+
# Test adding line item by hash
|
220
|
+
line_item = invoice.add_line_item(line_item_params)
|
221
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
222
|
+
assert_equal(line_item_params[:description], line_item.description)
|
223
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
224
|
+
assert_equal(1, invoice.line_items.size)
|
225
|
+
|
226
|
+
# Test adding line item by XeroGateway::LineItem
|
227
|
+
line_item = invoice.add_line_item(line_item_params)
|
228
|
+
assert_kind_of(XeroGateway::LineItem, line_item)
|
229
|
+
assert_equal(line_item_params[:description], line_item.description)
|
230
|
+
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
|
231
|
+
assert_equal(2, invoice.line_items.size)
|
232
|
+
|
233
|
+
# Test that pushing anything else into add_line_item fails.
|
234
|
+
["invalid", 100, nil, []].each do | invalid_object |
|
235
|
+
assert_raise(XeroGateway::Invoice::InvalidLineItemError) { invoice.add_line_item(invalid_object) }
|
236
|
+
assert_equal(2, invoice.line_items.size)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def create_test_invoice(invoice_params = {}, contact_params = {}, line_item_params = [])
|
243
|
+
unless invoice_params.nil?
|
244
|
+
invoice_params = {
|
245
|
+
:invoice_type => 'ACCREC',
|
246
|
+
:date => Date.today,
|
247
|
+
:due_date => Date.today + 10, # 10 days in the future
|
248
|
+
:invoice_number => '12345',
|
249
|
+
:reference => "MY REFERENCE FOR THIS INVOICE",
|
250
|
+
:line_amount_types => "Exclusive"
|
251
|
+
}.merge(invoice_params)
|
252
|
+
end
|
253
|
+
invoice = XeroGateway::Invoice.new(invoice_params || {})
|
254
|
+
|
255
|
+
unless contact_params.nil?
|
256
|
+
# Strip out :address key from contact_params to use as the default address.
|
257
|
+
stripped_address = {
|
258
|
+
:address_type => 'DEFAULT',
|
259
|
+
:line_1 => 'LINE 1 OF THE ADDRESS'
|
260
|
+
}.merge(contact_params.delete(:address) || {})
|
261
|
+
|
262
|
+
# Strip out :phone key from contact_params to use at the default phone.
|
263
|
+
stripped_phone = {
|
264
|
+
:phone_type => 'DEFAULT',
|
265
|
+
:number => '12345678'
|
266
|
+
}.merge(contact_params.delete(:phone) || {})
|
267
|
+
|
268
|
+
contact_params = {
|
269
|
+
:contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
|
270
|
+
:name => "CONTACT NAME",
|
271
|
+
:first_name => "Bob",
|
272
|
+
:last_name => "Builder"
|
273
|
+
}.merge(contact_params)
|
274
|
+
|
275
|
+
# Create invoice.contact from contact_params.
|
276
|
+
invoice.contact = XeroGateway::Contact.new(contact_params)
|
277
|
+
invoice.contact.address = XeroGateway::Address.new(stripped_address)
|
278
|
+
invoice.contact.phone = XeroGateway::Phone.new(stripped_phone)
|
279
|
+
end
|
280
|
+
|
281
|
+
unless line_item_params.nil?
|
282
|
+
line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
|
283
|
+
|
284
|
+
# At least one line item, make first have some defaults.
|
285
|
+
line_item_params << {} if line_item_params.size == 0
|
286
|
+
line_item_params[0] = {
|
287
|
+
:description => "A LINE ITEM",
|
288
|
+
:account_code => "200",
|
289
|
+
:unit_amount => BigDecimal.new("100"),
|
290
|
+
:tax_amount => BigDecimal.new("12.5"),
|
291
|
+
:tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
|
292
|
+
}.merge(line_item_params[0])
|
293
|
+
|
294
|
+
# Create invoice.line_items from line_item_params
|
295
|
+
line_item_params.each do | line_item |
|
296
|
+
invoice.add_line_item(line_item)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
invoice
|
301
|
+
end
|
302
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Shamelessly based on the xero Gem's OAuth implementation by John Nunemaker
|
2
|
+
# Thanks!
|
3
|
+
#
|
4
|
+
# http://xero.rubyforge.org/
|
5
|
+
# http://github.com/jnunemaker/xero/
|
6
|
+
|
7
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
8
|
+
|
9
|
+
class OAuthTest < Test::Unit::TestCase
|
10
|
+
should "initialize with consumer token and secret" do
|
11
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
12
|
+
|
13
|
+
assert_equal 'token', xero.ctoken
|
14
|
+
assert_equal 'secret', xero.csecret
|
15
|
+
end
|
16
|
+
|
17
|
+
should "set autorization path to '/oauth/authorize' by default" do
|
18
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
19
|
+
assert_equal '/oauth/Authorize', xero.consumer.options[:authorize_path]
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have a consumer" do
|
23
|
+
consumer = mock('oauth consumer')
|
24
|
+
OAuth::Consumer.expects(:new).with('token', 'secret', XeroGateway::OAuth::XERO_CONSUMER_OPTIONS).returns(consumer)
|
25
|
+
|
26
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
27
|
+
|
28
|
+
assert_equal consumer, xero.consumer
|
29
|
+
end
|
30
|
+
|
31
|
+
should "have a request token from the consumer" do
|
32
|
+
consumer = mock('oauth consumer')
|
33
|
+
request_token = mock('request token')
|
34
|
+
consumer.expects(:get_request_token).returns(request_token)
|
35
|
+
OAuth::Consumer.expects(:new).with('token', 'secret', XeroGateway::OAuth::XERO_CONSUMER_OPTIONS).returns(consumer)
|
36
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
37
|
+
|
38
|
+
assert_equal request_token, xero.request_token
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be able to create access token from request token and secret" do
|
42
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
43
|
+
consumer = OAuth::Consumer.new('token', 'secret')
|
44
|
+
xero.stubs(:consumer).returns(consumer)
|
45
|
+
|
46
|
+
access_token = mock('access token', :token => 'atoken', :secret => 'asecret')
|
47
|
+
request_token = mock('request token')
|
48
|
+
request_token.expects(:get_access_token).returns(access_token)
|
49
|
+
OAuth::RequestToken.expects(:new).with(consumer, 'rtoken', 'rsecret').returns(request_token)
|
50
|
+
|
51
|
+
xero.authorize_from_request('rtoken', 'rsecret')
|
52
|
+
assert xero.access_token.is_a? OAuth::AccessToken
|
53
|
+
assert_equal "atoken", xero.access_token.token
|
54
|
+
assert_equal "asecret", xero.access_token.secret
|
55
|
+
end
|
56
|
+
|
57
|
+
should "be able to create access token from access token and secret" do
|
58
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
59
|
+
consumer = OAuth::Consumer.new('token', 'secret')
|
60
|
+
xero.stubs(:consumer).returns(consumer)
|
61
|
+
|
62
|
+
xero.authorize_from_access('atoken', 'asecret')
|
63
|
+
assert xero.access_token.is_a? OAuth::AccessToken
|
64
|
+
assert_equal "atoken", xero.access_token.token
|
65
|
+
assert_equal "asecret", xero.access_token.secret
|
66
|
+
end
|
67
|
+
|
68
|
+
# Xero doesn't support OAuth Callbacks, not that this calls to Xero anyway :)
|
69
|
+
# See: http://blog.xero.com/developer/api-overview/
|
70
|
+
#
|
71
|
+
# should "be able to create request token with callback url" do
|
72
|
+
# xero = XeroGateway::OAuth.new('token', 'secret')
|
73
|
+
# consumer = OAuth::Consumer.new('token', 'secret')
|
74
|
+
# xero.stubs(:consumer).returns(consumer)
|
75
|
+
#
|
76
|
+
# request_token = mock('request token')
|
77
|
+
# consumer.expects(:get_request_token).with(:oauth_callback => "http://callback.com").returns(request_token)
|
78
|
+
#
|
79
|
+
# xero.request_token(:oauth_callback => "http://callback.com")
|
80
|
+
# end
|
81
|
+
|
82
|
+
should "be able to create access token with oauth verifier" do
|
83
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
84
|
+
consumer = OAuth::Consumer.new('token', 'secret')
|
85
|
+
xero.stubs(:consumer).returns(consumer)
|
86
|
+
|
87
|
+
access_token = mock('access token', :token => 'atoken', :secret => 'asecret')
|
88
|
+
request_token = mock('request token')
|
89
|
+
request_token.expects(:get_access_token).with(:oauth_verifier => "verifier").returns(access_token)
|
90
|
+
OAuth::RequestToken.expects(:new).with(consumer, 'rtoken', 'rsecret').returns(request_token)
|
91
|
+
|
92
|
+
xero.authorize_from_request('rtoken', 'rsecret', :oauth_verifier => "verifier")
|
93
|
+
end
|
94
|
+
|
95
|
+
should "delegate get to access token" do
|
96
|
+
access_token = mock('access token')
|
97
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
98
|
+
xero.stubs(:access_token).returns(access_token)
|
99
|
+
access_token.expects(:get).returns(nil)
|
100
|
+
xero.get('/foo')
|
101
|
+
end
|
102
|
+
|
103
|
+
should "delegate post to access token" do
|
104
|
+
access_token = mock('access token')
|
105
|
+
xero = XeroGateway::OAuth.new('token', 'secret')
|
106
|
+
xero.stubs(:access_token).returns(access_token)
|
107
|
+
access_token.expects(:post).returns(nil)
|
108
|
+
xero.post('/foo')
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class OrganisationTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Tests that an organisation can be converted into XML that Xero can understand, and then converted back to an organisation
|
6
|
+
def test_build_and_parse_xml
|
7
|
+
org = create_test_organisation
|
8
|
+
|
9
|
+
# Generate the XML message
|
10
|
+
org_as_xml = org.to_xml
|
11
|
+
|
12
|
+
# Parse the XML message and retrieve the account element
|
13
|
+
org_element = REXML::XPath.first(REXML::Document.new(org_as_xml), "/Organisation")
|
14
|
+
|
15
|
+
# Build a new account from the XML
|
16
|
+
result_org = XeroGateway::Organisation.from_xml(org_element)
|
17
|
+
|
18
|
+
# Check the account details
|
19
|
+
assert_equal org, result_org
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_test_organisation
|
26
|
+
XeroGateway::Organisation.new.tap do |org|
|
27
|
+
org.name = "Demo Company (NZ)"
|
28
|
+
org.legal_name = "Demo Company (NZ)"
|
29
|
+
org.pays_tax = true
|
30
|
+
org.version = "NZ"
|
31
|
+
org.base_currency = "NZD"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper.rb')
|
2
|
+
|
3
|
+
class TaxRateTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Tests that a tax rate can be converted into XML that Xero can understand, and then converted back to a tax rate
|
6
|
+
def test_build_and_parse_xml
|
7
|
+
tax_rate = create_test_tax_rate
|
8
|
+
|
9
|
+
# Generate the XML message
|
10
|
+
tax_rate_as_xml = tax_rate.to_xml
|
11
|
+
|
12
|
+
# Parse the XML message and retrieve the account element
|
13
|
+
tax_rate_element = REXML::XPath.first(REXML::Document.new(tax_rate_as_xml), "/TaxRate")
|
14
|
+
|
15
|
+
# Build a new account from the XML
|
16
|
+
result_tax_rate = XeroGateway::TaxRate.from_xml(tax_rate_element)
|
17
|
+
|
18
|
+
# Check the account details
|
19
|
+
assert_equal tax_rate, result_tax_rate
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_test_tax_rate
|
26
|
+
XeroGateway::TaxRate.new.tap do |tax_rate|
|
27
|
+
tax_rate.name = "GST on Expenses"
|
28
|
+
tax_rate.tax_type = "INPUT"
|
29
|
+
tax_rate.can_apply_to_assets = true
|
30
|
+
tax_rate.can_apply_to_equity = true
|
31
|
+
tax_rate.can_apply_to_expenses = true
|
32
|
+
tax_rate.can_apply_to_liabilities = true
|
33
|
+
tax_rate.can_apply_to_revenue = false
|
34
|
+
tax_rate.display_tax_rate = 12.500
|
35
|
+
tax_rate.effective_rate = 12.500
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|