xero_gateway 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@ class AccountTest < Test::Unit::TestCase
4
4
  # Tests that an account can be converted into XML that Xero can understand, and then converted back to an account
5
5
  def test_build_and_parse_xml
6
6
  account = create_test_account
7
-
7
+
8
8
  # Generate the XML message
9
9
  account_as_xml = account.to_xml
10
10
 
@@ -13,30 +13,34 @@ class AccountTest < Test::Unit::TestCase
13
13
 
14
14
  # Build a new account from the XML
15
15
  result_account = XeroGateway::Account.from_xml(account_element)
16
-
16
+
17
17
  # Check the account details
18
18
  assert_equal account, result_account
19
19
  end
20
-
20
+
21
21
  def test_build_and_parse_xml_for_bank_accounts
22
- account = create_test_account(:type => 'BANK', :currency_code => 'NZD')
22
+ account = create_test_account(:type => 'BANK', :status => 'ACTIVE', :account_class => 'ASSET', :currency_code => 'NZD')
23
23
  account_as_xml = account.to_xml
24
24
  assert_match 'CurrencyCode', account_as_xml.to_s
25
25
 
26
26
  account_element = REXML::XPath.first(REXML::Document.new(account_as_xml), "/Account")
27
27
  result_account = XeroGateway::Account.from_xml(account_element)
28
28
  assert_equal 'BANK', result_account.type
29
+ assert_equal 'ACTIVE', result_account.status
30
+ assert_equal 'ASSET', result_account.account_class
29
31
  assert_equal 'NZD', result_account.currency_code
30
32
  assert_equal account, result_account
31
33
  end
32
-
34
+
33
35
  private
34
-
36
+
35
37
  def create_test_account(options={})
36
38
  account = XeroGateway::Account.new(:account_id => "57cedda9")
37
39
  account.code = "200"
38
40
  account.name = "Sales"
39
41
  account.type = options[:type] || "REVENUE"
42
+ account.status = options[:status] || "ACTIVE"
43
+ account.account_class = options[:account_class] || "REVENUE"
40
44
  account.tax_type = "OUTPUT"
41
45
  account.description = "Income from any normal business activity"
42
46
  account.enable_payments_to_account = false
@@ -37,6 +37,15 @@ class BankTransactionTest < Test::Unit::TestCase
37
37
  should "allow overriding transaction defaults" do
38
38
  assert_equal 'SPEND', create_test_bank_transaction(:type => 'SPEND').type
39
39
  end
40
+
41
+ should "support another currency" do
42
+ usd_code = "USD"
43
+ usd_rate = 1.402
44
+ bank_transaction = create_test_bank_transaction(:currency_code => usd_code,
45
+ :currency_rate => usd_rate)
46
+ assert_equal usd_code, bank_transaction.currency_code
47
+ assert_equal usd_rate, bank_transaction.currency_rate
48
+ end
40
49
  end
41
50
 
42
51
  context "adding line items" do
@@ -124,9 +133,9 @@ class BankTransactionTest < Test::Unit::TestCase
124
133
  private
125
134
 
126
135
  def assert_xml_field(xml, field_name, options={})
127
- assert_match /#{field_name}/, xml.to_s, "Didn't find the field #{field_name} in the XML document!"
136
+ assert_match(/#{field_name}/, xml.to_s, "Didn't find the field #{field_name} in the XML document!")
128
137
  if options[:value]
129
- assert_match /#{field_name}.*#{options[:value]}.*#{field_name}/, xml.to_s, "The field #{field_name} was expected to be '#{options[:value]}'!"
138
+ assert_match(/#{field_name}.*#{options[:value]}.*#{field_name}/, xml.to_s, "The field #{field_name} was expected to be '#{options[:value]}'!")
130
139
  end
131
140
  end
132
141
 
@@ -32,6 +32,68 @@ class ContactTest < Test::Unit::TestCase
32
32
  assert_equal contact, result_contact
33
33
  end
34
34
 
35
+ # this allows you to remove addresses from Xero
36
+ test "explicity passing an empty array for addresses should include an empty element" do
37
+ contact = create_test_contact
38
+ contact.addresses = nil
39
+
40
+ parsed = REXML::XPath.first(REXML::Document.new(contact.to_xml), "/Contact")
41
+ assert !parsed.children.map(&:name).include?("Addresses")
42
+
43
+ contact.addresses = []
44
+ parsed = REXML::XPath.first(REXML::Document.new(contact.to_xml), "/Contact")
45
+ assert parsed.children.map(&:name).include?("Addresses")
46
+ end
47
+
48
+ test "should be able to set addresses as part of initialize" do
49
+ contact = XeroGateway::Contact.new(contact_id: "abcdef-3abe", name: "Test", addresses: [])
50
+
51
+ parsed = REXML::XPath.first(REXML::Document.new(contact.to_xml), "/Contact")
52
+ assert parsed.children.map(&:name).include?("Addresses")
53
+ end
54
+
55
+ test "parsing from XML" do
56
+ test_xml = <<-TESTING.strip_heredoc.chomp
57
+ <Contact>
58
+ <ContactID>f1d403d1-7d30-46c2-a2be-fc2bb29bd295</ContactID>
59
+ <ContactStatus>ACTIVE</ContactStatus>
60
+ <Name>24 Locks</Name>
61
+ <Addresses>
62
+ <Address>
63
+ <AddressType>POBOX</AddressType>
64
+ </Address>
65
+ <Address>
66
+ <AddressType>STREET</AddressType>
67
+ </Address>
68
+ </Addresses>
69
+ <Phones>
70
+ <Phone>
71
+ <PhoneType>DDI</PhoneType>
72
+ </Phone>
73
+ <Phone>
74
+ <PhoneType>DEFAULT</PhoneType>
75
+ </Phone>
76
+ <Phone>
77
+ <PhoneType>FAX</PhoneType>
78
+ </Phone>
79
+ <Phone>
80
+ <PhoneType>MOBILE</PhoneType>
81
+ </Phone>
82
+ </Phones>
83
+ <UpdatedDateUTC>2016-08-31T04:55:39.217</UpdatedDateUTC>
84
+ <IsSupplier>false</IsSupplier>
85
+ <IsCustomer>false</IsCustomer>
86
+ <HasAttachments>false</HasAttachments>
87
+ </Contact>
88
+ TESTING
89
+
90
+ contact_element = REXML::XPath.first(REXML::Document.new(test_xml.gsub(/\s/, "")), "/Contact")
91
+ contact = XeroGateway::Contact.from_xml(contact_element)
92
+
93
+ assert_equal Time.new(2016, 8, 31, 04, 55, 39), contact.updated_at.utc
94
+
95
+ end
96
+
35
97
  # Test Contact#add_address helper creates a valid XeroGateway::Contact object with the passed in values
36
98
  # and appends it to the Contact#addresses attribute.
37
99
  def test_add_address_helper
@@ -1,11 +1,11 @@
1
1
  require File.join(File.dirname(__FILE__), '../test_helper.rb')
2
2
 
3
3
  class CreditNoteTest < Test::Unit::TestCase
4
-
4
+
5
5
  # Tests that a credit note can be converted into XML that Xero can understand, and then converted back to a credit note
6
6
  def test_build_and_parse_xml
7
7
  credit_note = create_test_credit_note
8
-
8
+
9
9
  # Generate the XML message
10
10
  credit_note_as_xml = credit_note.to_xml
11
11
 
@@ -17,46 +17,38 @@ class CreditNoteTest < Test::Unit::TestCase
17
17
 
18
18
  assert_equal(credit_note, result_credit_note)
19
19
  end
20
-
20
+
21
21
  # Tests the sub_total calculation and that setting it manually doesn't modify the data.
22
22
  def test_credit_note_sub_total_calculation
23
23
  credit_note = create_test_credit_note
24
24
  line_item = credit_note.line_items.first
25
-
25
+
26
26
  # Make sure that everything adds up to begin with.
27
- expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
28
- assert_equal(expected_sub_total, credit_note.sub_total)
29
-
30
- # Change the sub_total and check that it doesn't modify anything.
31
- credit_note.sub_total = expected_sub_total * 10
27
+ expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, l | l.line_amount }
32
28
  assert_equal(expected_sub_total, credit_note.sub_total)
33
-
34
- # Change the amount of the first line item and make sure that
29
+
30
+ # Change the amount of the first line item and make sure that
35
31
  # everything still continues to add up.
36
32
  line_item.unit_amount = line_item.unit_amount + 10
37
33
  assert_not_equal(expected_sub_total, credit_note.sub_total)
38
- expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
34
+ expected_sub_total = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, l | l.line_amount }
39
35
  assert_equal(expected_sub_total, credit_note.sub_total)
40
36
  end
41
-
37
+
42
38
  # Tests the total_tax calculation and that setting it manually doesn't modify the data.
43
39
  def test_credit_note_sub_total_calculation2
44
40
  credit_note = create_test_credit_note
45
41
  line_item = credit_note.line_items.first
46
-
42
+
47
43
  # Make sure that everything adds up to begin with.
48
- expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
49
- assert_equal(expected_total_tax, credit_note.total_tax)
50
-
51
- # Change the total_tax and check that it doesn't modify anything.
52
- credit_note.total_tax = expected_total_tax * 10
44
+ expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, l | l.tax_amount }
53
45
  assert_equal(expected_total_tax, credit_note.total_tax)
54
-
55
- # Change the tax_amount of the first line item and make sure that
46
+
47
+ # Change the tax_amount of the first line item and make sure that
56
48
  # everything still continues to add up.
57
49
  line_item.tax_amount = line_item.tax_amount + 10
58
50
  assert_not_equal(expected_total_tax, credit_note.total_tax)
59
- expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
51
+ expected_total_tax = credit_note.line_items.inject(BigDecimal.new('0')) { | sum, l | l.tax_amount }
60
52
  assert_equal(expected_total_tax, credit_note.total_tax)
61
53
  end
62
54
 
@@ -64,16 +56,12 @@ class CreditNoteTest < Test::Unit::TestCase
64
56
  def test_credit_note_sub_total_calculation3
65
57
  credit_note = create_test_credit_note
66
58
  line_item = credit_note.line_items.first
67
-
59
+
68
60
  # Make sure that everything adds up to begin with.
69
61
  expected_total = credit_note.sub_total + credit_note.total_tax
70
62
  assert_equal(expected_total, credit_note.total)
71
-
72
- # Change the total and check that it doesn't modify anything.
73
- credit_note.total = expected_total * 10
74
- assert_equal(expected_total, credit_note.total)
75
-
76
- # Change the quantity of the first line item and make sure that
63
+
64
+ # Change the quantity of the first line item and make sure that
77
65
  # everything still continues to add up.
78
66
  line_item.quantity = line_item.quantity + 5
79
67
  assert_not_equal(expected_total, credit_note.total)
@@ -85,72 +73,72 @@ class CreditNoteTest < Test::Unit::TestCase
85
73
  def test_line_amount_calculation
86
74
  credit_note = create_test_credit_note
87
75
  line_item = credit_note.line_items.first
88
-
76
+
89
77
  # Make sure that everything adds up to begin with.
90
78
  expected_amount = line_item.quantity * line_item.unit_amount
91
79
  assert_equal(expected_amount, line_item.line_amount)
92
-
80
+
93
81
  # Change the line_amount and check that it doesn't modify anything.
94
82
  line_item.line_amount = expected_amount * 10
95
83
  assert_equal(expected_amount, line_item.line_amount)
96
-
84
+
97
85
  # Change the quantity and check that the line_amount has been updated.
98
86
  quantity = line_item.quantity + 2
99
87
  line_item.quantity = quantity
100
88
  assert_not_equal(expected_amount, line_item.line_amount)
101
89
  assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
102
90
  end
103
-
91
+
104
92
  # Ensure that the totalling methods don't raise exceptions, even when
105
93
  # credit_note.line_items is empty.
106
94
  def test_totalling_methods_when_line_items_empty
107
95
  credit_note = create_test_credit_note
108
96
  credit_note.line_items = []
109
-
97
+
110
98
  assert_nothing_raised(Exception) {
111
99
  assert_equal(BigDecimal.new('0'), credit_note.sub_total)
112
100
  assert_equal(BigDecimal.new('0'), credit_note.total_tax)
113
101
  assert_equal(BigDecimal.new('0'), credit_note.total)
114
102
  }
115
103
  end
116
-
104
+
117
105
  def test_type_helper_methods
118
106
  # Test accounts receivable credit_notes.
119
107
  credit_note = create_test_credit_note({:type => 'ACCRECCREDIT'})
120
108
  assert_equal(true, credit_note.accounts_receivable?, "Accounts RECEIVABLE credit_note doesn't think it is.")
121
109
  assert_equal(false, credit_note.accounts_payable?, "Accounts RECEIVABLE credit_note thinks it's payable.")
122
-
110
+
123
111
  # Test accounts payable credit_notes.
124
112
  credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
125
113
  assert_equal(false, credit_note.accounts_receivable?, "Accounts PAYABLE credit_note doesn't think it is.")
126
114
  assert_equal(true, credit_note.accounts_payable?, "Accounts PAYABLE credit_note thinks it's receivable.")
127
115
  end
128
-
129
-
116
+
117
+
130
118
  # Make sure that the create_test_credit_note method is working correctly
131
119
  # with all the defaults and overrides.
132
120
  def test_create_test_credit_note_defaults_working
133
121
  credit_note = create_test_credit_note
134
-
122
+
135
123
  # Test credit_note defaults.
136
124
  assert_equal('ACCRECCREDIT', credit_note.type)
137
125
  assert_kind_of(Date, credit_note.date)
138
126
  assert_equal('12345', credit_note.credit_note_number)
139
127
  assert_equal('MY REFERENCE FOR THIS CREDIT NOTE', credit_note.reference)
140
128
  assert_equal("Exclusive", credit_note.line_amount_types)
141
-
129
+
142
130
  # Test the contact defaults.
143
131
  assert_equal('00000000-0000-0000-0000-000000000000', credit_note.contact.contact_id)
144
132
  assert_equal('CONTACT NAME', credit_note.contact.name)
145
-
133
+
146
134
  # Test address defaults.
147
135
  assert_equal('DEFAULT', credit_note.contact.address.address_type)
148
136
  assert_equal('LINE 1 OF THE ADDRESS', credit_note.contact.address.line_1)
149
-
137
+
150
138
  # Test phone defaults.
151
139
  assert_equal('DEFAULT', credit_note.contact.phone.phone_type)
152
140
  assert_equal('12345678', credit_note.contact.phone.number)
153
-
141
+
154
142
  # Test the line_item defaults.
155
143
  assert_equal('A LINE ITEM', credit_note.line_items.first.description)
156
144
  assert_equal('200', credit_note.line_items.first.account_code)
@@ -160,19 +148,19 @@ class CreditNoteTest < Test::Unit::TestCase
160
148
  # Test overriding an credit_note parameter (assume works for all).
161
149
  credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
162
150
  assert_equal('ACCPAYCREDIT', credit_note.type)
163
-
151
+
164
152
  # Test overriding a contact/address/phone parameter (assume works for all).
165
153
  credit_note = create_test_credit_note({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
166
154
  assert_equal('OVERRIDDEN NAME', credit_note.contact.name)
167
155
  assert_equal('OVERRIDDEN LINE 1', credit_note.contact.address.line_1)
168
156
  assert_equal('999', credit_note.contact.phone.number)
169
-
157
+
170
158
  # Test overriding line_items with hash.
171
159
  credit_note = create_test_credit_note({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
172
160
  assert_equal(1, credit_note.line_items.size)
173
161
  assert_equal('OVERRIDDEN LINE ITEM', credit_note.line_items.first.description)
174
162
  assert_equal(BigDecimal.new('100'), credit_note.line_items.first.unit_amount)
175
-
163
+
176
164
  # Test overriding line_items with array of 2 line_items.
177
165
  credit_note = create_test_credit_note({}, {}, [
178
166
  {:description => 'OVERRIDDEN ITEM 1'},
@@ -184,28 +172,28 @@ class CreditNoteTest < Test::Unit::TestCase
184
172
  assert_equal('OVERRIDDEN ITEM 2', credit_note.line_items[1].description)
185
173
  assert_equal(BigDecimal.new('200'), credit_note.line_items[1].unit_amount)
186
174
  end
187
-
175
+
188
176
  def test_auto_creation_of_associated_contact
189
177
  credit_note = create_test_credit_note({}, nil) # no contact
190
- assert_nil(credit_note.instance_variable_get("@contact"))
191
-
178
+ assert(!credit_note.instance_variable_defined?("@contact"))
179
+
192
180
  new_contact = credit_note.contact
193
181
  assert_kind_of(XeroGateway::Contact, new_contact)
194
182
  end
195
-
183
+
196
184
  def test_add_line_item
197
185
  credit_note = create_test_credit_note({}, {}, nil) # no line_items
198
186
  assert_equal(0, credit_note.line_items.size)
199
-
187
+
200
188
  line_item_params = {:description => "Test Item 1", :unit_amount => 100}
201
-
189
+
202
190
  # Test adding line item by hash
203
191
  line_item = credit_note.add_line_item(line_item_params)
204
192
  assert_kind_of(XeroGateway::LineItem, line_item)
205
193
  assert_equal(line_item_params[:description], line_item.description)
206
194
  assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
207
195
  assert_equal(1, credit_note.line_items.size)
208
-
196
+
209
197
  # Test adding line item by XeroGateway::LineItem
210
198
  line_item = credit_note.add_line_item(line_item_params)
211
199
  assert_kind_of(XeroGateway::LineItem, line_item)
@@ -219,9 +207,9 @@ class CreditNoteTest < Test::Unit::TestCase
219
207
  assert_equal(2, credit_note.line_items.size)
220
208
  end
221
209
  end
222
-
210
+
223
211
  private
224
-
212
+
225
213
  def create_test_credit_note(credit_note_params = {}, contact_params = {}, line_item_params = [])
226
214
  unless credit_note_params.nil?
227
215
  credit_note_params = {
@@ -233,36 +221,36 @@ class CreditNoteTest < Test::Unit::TestCase
233
221
  }.merge(credit_note_params)
234
222
  end
235
223
  credit_note = XeroGateway::CreditNote.new(credit_note_params || {})
236
-
224
+
237
225
  unless contact_params.nil?
238
226
  # Strip out :address key from contact_params to use as the default address.
239
227
  stripped_address = {
240
228
  :address_type => 'DEFAULT',
241
229
  :line_1 => 'LINE 1 OF THE ADDRESS'
242
230
  }.merge(contact_params.delete(:address) || {})
243
-
231
+
244
232
  # Strip out :phone key from contact_params to use at the default phone.
245
233
  stripped_phone = {
246
234
  :phone_type => 'DEFAULT',
247
235
  :number => '12345678'
248
236
  }.merge(contact_params.delete(:phone) || {})
249
-
237
+
250
238
  contact_params = {
251
239
  :contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
252
240
  :name => "CONTACT NAME",
253
241
  :first_name => "Bob",
254
242
  :last_name => "Builder"
255
243
  }.merge(contact_params)
256
-
244
+
257
245
  # Create credit_note.contact from contact_params.
258
246
  credit_note.contact = XeroGateway::Contact.new(contact_params)
259
247
  credit_note.contact.address = XeroGateway::Address.new(stripped_address)
260
248
  credit_note.contact.phone = XeroGateway::Phone.new(stripped_phone)
261
249
  end
262
-
250
+
263
251
  unless line_item_params.nil?
264
252
  line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
265
-
253
+
266
254
  # At least one line item, make first have some defaults.
267
255
  line_item_params << {} if line_item_params.size == 0
268
256
  line_item_params[0] = {
@@ -272,13 +260,13 @@ class CreditNoteTest < Test::Unit::TestCase
272
260
  :tax_amount => BigDecimal.new("12.5"),
273
261
  :tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
274
262
  }.merge(line_item_params[0])
275
-
263
+
276
264
  # Create credit_note.line_items from line_item_params
277
265
  line_item_params.each do | line_item |
278
266
  credit_note.add_line_item(line_item)
279
267
  end
280
268
  end
281
-
269
+
282
270
  credit_note
283
271
  end
284
272
  end
@@ -14,6 +14,19 @@ class GatewayTest < Test::Unit::TestCase
14
14
  assert result.response_item.first.is_a? XeroGateway::Invoice
15
15
  end
16
16
 
17
+ should "get invoices by contact ids" do
18
+ contact_id = 'a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999'
19
+ stub_response = stub(:plain_body => get_file_as_string("invoices.xml"),
20
+ :code => "200")
21
+ expected_url = /.+\/Invoices\?ContactIDs=#{contact_id}/
22
+ XeroGateway::OAuth.any_instance
23
+ .stubs(:get)
24
+ .with(regexp_matches(expected_url), anything)
25
+ .returns(stub_response)
26
+ result = @gateway.get_invoices(:contact_ids => [contact_id])
27
+ assert result.response_item.first.is_a? XeroGateway::Invoice
28
+ end
29
+
17
30
  should :get_invoice do
18
31
  XeroGateway::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("invoice.xml"), :code => "200"))
19
32
  result = @gateway.get_invoice('a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999')
@@ -62,7 +75,6 @@ class GatewayTest < Test::Unit::TestCase
62
75
  assert result.response_item.first.is_a? XeroGateway::Payment
63
76
  end
64
77
 
65
-
66
78
  should :get_contacts do
67
79
  XeroGateway::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("contacts.xml"), :code => "200"))
68
80
  result = @gateway.get_contacts
@@ -84,13 +96,13 @@ class GatewayTest < Test::Unit::TestCase
84
96
  should :get_contact_groups do
85
97
  XeroGateway::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("contact_groups.xml"), :code => "200"))
86
98
  result = @gateway.get_contact_groups
87
- assert result.response_item.first.is_a? XeroGateway::ContactGroup
99
+ assert result.response_item.first.is_a? XeroGateway::ContactGroup
88
100
  end
89
101
 
90
102
  should :get_contact_group_by_id do
91
103
  XeroGateway::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("contact_group.xml"), :code => "200"))
92
104
  result = @gateway.get_contact_group_by_id('a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999')
93
- assert result.response_item.is_a? XeroGateway::ContactGroup
105
+ assert result.response_item.is_a? XeroGateway::ContactGroup
94
106
  end
95
107
 
96
108
  context :get_report do
@@ -255,7 +267,7 @@ class GatewayTest < Test::Unit::TestCase
255
267
  XeroGateway::OAuth.any_instance.stubs(:put).returns(stub(:plain_body => get_file_as_string("no_certificates_registered"), :code => 400))
256
268
 
257
269
  assert_raises RuntimeError do
258
- response = @gateway.create_invoice(XeroGateway::Invoice.new)
270
+ @gateway.create_invoice(XeroGateway::Invoice.new)
259
271
  end
260
272
  end
261
273
  end