tlconnor-xero_gateway 1.0.3 → 1.0.4

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.
@@ -13,7 +13,6 @@ module XeroGateway
13
13
 
14
14
  def initialize(params = {})
15
15
  params.each do |k,v|
16
- self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
17
16
  self.send("#{k}=", v)
18
17
  end
19
18
 
@@ -29,4 +28,4 @@ module XeroGateway
29
28
  errors.blank? ? nil : errors[0]
30
29
  end
31
30
  end
32
- end
31
+ end
@@ -5,21 +5,15 @@ module XeroGateway
5
5
  def initialize(params = {})
6
6
  @options = []
7
7
  params.each do |k,v|
8
- self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
9
8
  self.send("#{k}=", v)
10
9
  end
11
10
  end
12
11
 
13
- def ==(other)
14
- [:name, :options].each do |field|
15
- return false if send(field) != other.send(field)
16
- end
17
- return true
12
+ def option
13
+ options[0] if options.size == 1
18
14
  end
19
-
20
- def to_xml
21
- b = Builder::XmlMarkup.new
22
-
15
+
16
+ def to_xml(b = Builder::XmlMarkup.new)
23
17
  b.TrackingCategory {
24
18
  b.Name self.name
25
19
  b.Options {
@@ -41,6 +35,13 @@ module XeroGateway
41
35
  end
42
36
  end
43
37
  tracking_category
44
- end
38
+ end
39
+
40
+ def ==(other)
41
+ [:name, :options].each do |field|
42
+ return false if send(field) != other.send(field)
43
+ end
44
+ return true
45
+ end
45
46
  end
46
- end
47
+ end
@@ -0,0 +1,111 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class AccountsListTest < Test::Unit::TestCase
4
+ include TestHelper
5
+
6
+ def setup
7
+ @gateway = XeroGateway::Gateway.new(
8
+ :customer_key => CUSTOMER_KEY,
9
+ :api_key => API_KEY
10
+ )
11
+
12
+ # Always stub out calls for this integration test as we need to be able to control the data.
13
+ @gateway.xero_url = "DUMMY_URL"
14
+ @gateway.stubs(:http_get).with {|url, params| url =~ /accounts$/ }.returns(get_file_as_string("accounts.xml"))
15
+ end
16
+
17
+ def test_get_accounts_list
18
+ accounts_list = @gateway.get_accounts_list
19
+ assert_not_equal(0, accounts_list.accounts.size)
20
+ end
21
+
22
+ # Make sure that the list is loaded when finding things.
23
+ def test_raise_error_on_not_loaded
24
+ accounts_list = @gateway.get_accounts_list(false)
25
+ assert_equal(false, accounts_list.loaded?)
26
+ assert_raise(XeroGateway::AccountsList::AccountsListNotLoadedError) { accounts_list[200] }
27
+ assert_raise(XeroGateway::AccountsList::AccountsListNotLoadedError) { accounts_list.find_by_code(200) }
28
+ assert_raise(XeroGateway::AccountsList::AccountsListNotLoadedError) { accounts_list.find_all_by_type('EXPENSE') }
29
+ assert_raise(XeroGateway::AccountsList::AccountsListNotLoadedError) { accounts_list.find_all_by_tax_type('OUTPUT') }
30
+ end
31
+
32
+ # Test simple lookup by account code (from cache).
33
+ def test_simple_lookup_by_account_code
34
+ accounts_list = @gateway.get_accounts_list
35
+ assert_equal(true, accounts_list.loaded?)
36
+
37
+ # Load data in the stubbed response.
38
+ expected_accounts = accounts_as_array
39
+
40
+ # Make sure that every single expected account exists in the cached lookup hash.
41
+ expected_accounts.each do | expected_account |
42
+ found_account = accounts_list.find_by_code(expected_account.code)
43
+ assert_kind_of(XeroGateway::Account, found_account)
44
+ assert(expected_account == found_account, "Found account does not match expected account.")
45
+
46
+ found_account_shortcut = accounts_list[expected_account.code]
47
+ assert_kind_of(XeroGateway::Account, found_account_shortcut)
48
+ assert(expected_account == found_account_shortcut, "Found account does not match expected account (shortcut).")
49
+ end
50
+ end
51
+
52
+ # Test finding accounts by their account type (from cache).
53
+ def test_lookup_by_account_type
54
+ accounts_list = @gateway.get_accounts_list
55
+ assert_equal(true, accounts_list.loaded?)
56
+
57
+ # Load data in the stubbed response.
58
+ expected_accounts = accounts_as_array
59
+
60
+ # Get all the unique account types present in the expected accounts data along with their counts.
61
+ unique_types = expected_accounts.inject({}) do | list, account |
62
+ list[account.type] = 0 if list[account.type].nil?
63
+ list[account.type] += 1
64
+ list
65
+ end
66
+
67
+ assert_not_equal(0, unique_types)
68
+ unique_types.each do | account_type, count |
69
+ found_accounts = accounts_list.find_all_by_type(account_type)
70
+ assert_equal(count, found_accounts.size)
71
+ found_accounts.each do | found_account |
72
+ assert_kind_of(XeroGateway::Account, found_account)
73
+ assert_equal(account_type, found_account.type)
74
+ end
75
+ end
76
+ end
77
+
78
+ # Test finding accounts by their tax type (from cache).
79
+ def test_lookup_by_tax_type
80
+ accounts_list = @gateway.get_accounts_list
81
+ assert_equal(true, accounts_list.loaded?)
82
+
83
+ # Load data in the stubbed response.
84
+ expected_accounts = accounts_as_array
85
+
86
+ # Get all the unique tax types present in the expected accounts data along with their counts.
87
+ unique_types = expected_accounts.inject({}) do | list, account |
88
+ list[account.tax_type] = 0 if list[account.tax_type].nil?
89
+ list[account.tax_type] += 1
90
+ list
91
+ end
92
+
93
+ assert_not_equal(0, unique_types)
94
+ unique_types.each do | tax_type, count |
95
+ found_accounts = accounts_list.find_all_by_tax_type(tax_type)
96
+ assert_equal(count, found_accounts.size)
97
+ found_accounts.each do | found_account |
98
+ assert_kind_of(XeroGateway::Account, found_account)
99
+ assert_equal(tax_type, found_account.tax_type)
100
+ end
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def accounts_as_array
107
+ response = @gateway.__send__(:parse_response, get_file_as_string("accounts.xml"))
108
+ response.accounts
109
+ end
110
+
111
+ end
@@ -13,17 +13,57 @@ class CreateContactTest < Test::Unit::TestCase
13
13
  @gateway.xero_url = "DUMMY_URL"
14
14
 
15
15
  @gateway.stubs(:http_put).with {|url, body, params| url =~ /contact$/ }.returns(get_file_as_string("contact.xml"))
16
+ @gateway.stubs(:http_post).with {|url, body, params| url =~ /contact$/ }.returns(get_file_as_string("contact.xml"))
16
17
  end
17
18
  end
18
19
 
19
20
  def test_create_contact
20
- example_contact = dummy_contact
21
+ example_contact = dummy_contact.dup
21
22
 
22
23
  result = @gateway.create_contact(example_contact)
23
- assert result.success?
24
- assert !result.contact.contact_id.nil?
25
- assert !result.request_xml.nil?
26
- assert !result.response_xml.nil?
27
- assert_equal result.contact.name, example_contact.name
24
+ assert_valid_contact_save_response(result, example_contact)
28
25
  end
26
+
27
+ def test_create_from_contact
28
+ example_contact = dummy_contact.dup
29
+
30
+ contact = @gateway.build_contact(example_contact)
31
+ result = contact.create
32
+ assert_valid_contact_save_response(result, example_contact)
33
+ end
34
+
35
+ def test_update_from_contact
36
+ example_contact = dummy_contact.dup
37
+
38
+ contact = @gateway.build_contact(example_contact)
39
+ contact.create # need to create first so we have a ContactID
40
+
41
+ result = contact.update
42
+ assert_valid_contact_save_response(result, example_contact)
43
+ end
44
+
45
+ def test_save_from_contact
46
+ example_contact = dummy_contact.dup
47
+
48
+ contact = @gateway.build_contact(example_contact)
49
+ result = contact.save
50
+ assert_valid_contact_save_response(result, example_contact)
51
+ end
52
+
53
+ def test_create_contact_valid
54
+ example_contact = dummy_contact.dup
55
+ assert_equal true, example_contact.valid?, "contact is invalid - errors:\n\t#{example_contact.errors.map { | error | "#{error[0]} #{error[1]}"}.join("\n\t")}"
56
+ end
57
+
58
+ private
59
+
60
+ def assert_valid_contact_save_response(result, example_contact)
61
+ assert_kind_of XeroGateway::Response, result
62
+ assert result.success?
63
+ assert !result.contact.contact_id.nil?
64
+ assert !result.request_xml.nil?
65
+ assert !result.response_xml.nil?
66
+ assert_equal result.contact.name, example_contact.name
67
+ assert example_contact.contact_id =~ GUID_REGEX
68
+ end
29
69
  end
@@ -13,17 +13,40 @@ class CreateInvoiceTest < Test::Unit::TestCase
13
13
  @gateway.xero_url = "DUMMY_URL"
14
14
 
15
15
  @gateway.stubs(:http_put).with {|url, body, params| url =~ /invoice$/ }.returns(get_file_as_string("invoice.xml"))
16
+ @gateway.stubs(:http_post).with {|url, body, params| url =~ /invoice$/ }.returns(get_file_as_string("invoice.xml"))
16
17
  end
17
18
  end
18
19
 
19
20
  def test_create_invoice
20
- example_invoice = dummy_invoice
21
+ example_invoice = dummy_invoice.dup
21
22
 
22
23
  result = @gateway.create_invoice(example_invoice)
23
- assert result.success?
24
- assert !result.request_xml.nil?
25
- assert !result.response_xml.nil?
26
- assert !result.invoice.invoice_id.nil?
27
- assert result.invoice.invoice_number == example_invoice.invoice_number
24
+ assert_valid_invoice_save_response(result, example_invoice)
28
25
  end
26
+
27
+ def test_create_from_invoice
28
+ example_invoice = dummy_invoice.dup
29
+
30
+ invoice = @gateway.build_invoice(example_invoice)
31
+ result = invoice.create
32
+ assert_valid_invoice_save_response(result, example_invoice)
33
+ end
34
+
35
+ def test_create_invoice_valid
36
+ example_invoice = dummy_invoice.dup
37
+ assert_equal true, example_invoice.valid?, "invoice is invalid - errors:\n\t#{example_invoice.errors.map { | error | "#{error[0]} #{error[1]}"}.join("\n\t")}"
38
+ end
39
+
40
+ private
41
+
42
+ def assert_valid_invoice_save_response(result, example_invoice)
43
+ assert_kind_of XeroGateway::Response, result
44
+ assert result.success?
45
+ assert !result.request_xml.nil?
46
+ assert !result.response_xml.nil?
47
+ assert !result.invoice.invoice_id.nil?
48
+ assert result.invoice.invoice_number == example_invoice.invoice_number
49
+ assert example_invoice.invoice_id =~ GUID_REGEX
50
+ end
51
+
29
52
  end
data/test/test_helper.rb CHANGED
@@ -20,6 +20,9 @@ module TestHelper
20
20
 
21
21
  API_KEY = ENV["API_KEY"] unless defined? API_KEY
22
22
  CUSTOMER_KEY = ENV["CUSTOMER_KEY"] unless defined? CUSTOMER_KEY
23
+
24
+ # Helper constant for checking regex
25
+ GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ unless defined?(GUID_REGEX)
23
26
 
24
27
 
25
28
  def dummy_invoice
@@ -28,22 +31,18 @@ module TestHelper
28
31
  :due_date => Date.today + 20,
29
32
  :invoice_number => STUB_XERO_CALLS ? "INV-0001" : "#{Time.now.to_f}",
30
33
  :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
31
- :sub_total => 1000,
32
- :total_tax => 125,
33
- :total => 1125
34
34
  })
35
35
  invoice.contact = dummy_contact
36
36
  invoice.line_items << XeroGateway::LineItem.new(
37
37
  :description => "THE DESCRIPTION OF THE LINE ITEM",
38
38
  :unit_amount => 1000,
39
39
  :tax_amount => 125,
40
- :line_amount => 1000,
41
40
  :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
42
41
  :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
43
42
  )
44
43
  invoice
45
44
  end
46
-
45
+
47
46
  def dummy_contact
48
47
  unique_id = Time.now.to_f
49
48
  contact = XeroGateway::Contact.new(:name => STUB_XERO_CALLS ? "CONTACT NAME" : "THE NAME OF THE CONTACT #{unique_id}")
@@ -32,6 +32,49 @@ class ContactTest < Test::Unit::TestCase
32
32
  assert_equal contact, result_contact
33
33
  end
34
34
 
35
+ # Test Contact#add_address helper creates a valid XeroGateway::Contact object with the passed in values
36
+ # and appends it to the Contact#addresses attribute.
37
+ def test_add_address_helper
38
+ contact = create_test_contact
39
+ assert_equal(1, contact.addresses.size)
40
+
41
+ new_values = {
42
+ :address_type => 'POBOX',
43
+ :line_1 => 'NEW LINE 1',
44
+ :line_2 => 'NEW LINE 2',
45
+ :line_3 => 'NEW LINE 3',
46
+ :line_4 => 'NEW LINE 4',
47
+ :city => 'NEW CITY',
48
+ :region => 'NEW REGION',
49
+ :post_code => '5555',
50
+ :country => 'Australia'
51
+ }
52
+ contact.add_address(new_values)
53
+
54
+ assert_equal(2, contact.addresses.size)
55
+ assert_kind_of(XeroGateway::Address, contact.addresses.last)
56
+ new_values.each { |k,v| assert_equal(v, contact.addresses.last.send("#{k}")) }
57
+ end
58
+
59
+ # Test Contact#add_phone helper creates a valid XeroGateway::Phone object with the passed in values
60
+ # and appends it to the Contact#phones attribute.
61
+ def test_add_address_helper
62
+ contact = create_test_contact
63
+ assert_equal(1, contact.phones.size)
64
+
65
+ new_values = {
66
+ :phone_type => 'MOBILE',
67
+ :country_code => '61',
68
+ :area_code => '406',
69
+ :number => '123456'
70
+ }
71
+ contact.add_phone(new_values)
72
+
73
+ assert_equal(2, contact.phones.size)
74
+ assert_kind_of(XeroGateway::Phone, contact.phones.last)
75
+ new_values.each { |k,v| assert_equal(v, contact.phones.last.send("#{k}")) }
76
+ end
77
+
35
78
 
36
79
  private
37
80
 
@@ -1,6 +1,7 @@
1
1
  require File.join(File.dirname(__FILE__), '../test_helper.rb')
2
2
 
3
3
  class InvoiceTest < Test::Unit::TestCase
4
+
4
5
  def setup
5
6
  @schema = LibXML::XML::Schema.document(LibXML::XML::Document.file(File.join(File.dirname(__FILE__), '../xsd/create_invoice.xsd')))
6
7
  end
@@ -31,33 +32,225 @@ class InvoiceTest < Test::Unit::TestCase
31
32
  assert_equal(invoice, result_invoice)
32
33
  end
33
34
 
35
+ # Tests the sub_total calculation and that setting it manually doesn't modify the data.
36
+ def test_invoice_sub_total_calculation
37
+ invoice = create_test_invoice
38
+ line_item = invoice.line_items.first
39
+
40
+ # Make sure that everything adds up to begin with.
41
+ expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
42
+ assert_equal(expected_sub_total, invoice.sub_total)
43
+
44
+ # Change the sub_total and check that it doesn't modify anything.
45
+ invoice.sub_total = expected_sub_total * 10
46
+ assert_equal(expected_sub_total, invoice.sub_total)
47
+
48
+ # Change the amount of the first line item and make sure that
49
+ # everything still continues to add up.
50
+ line_item.unit_amount = line_item.unit_amount + 10
51
+ assert_not_equal(expected_sub_total, invoice.sub_total)
52
+ expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
53
+ assert_equal(expected_sub_total, invoice.sub_total)
54
+ end
34
55
 
35
- private
56
+ # Tests the total_tax calculation and that setting it manually doesn't modify the data.
57
+ def test_invoice_sub_total_calculation
58
+ invoice = create_test_invoice
59
+ line_item = invoice.line_items.first
60
+
61
+ # Make sure that everything adds up to begin with.
62
+ expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
63
+ assert_equal(expected_total_tax, invoice.total_tax)
64
+
65
+ # Change the total_tax and check that it doesn't modify anything.
66
+ invoice.total_tax = expected_total_tax * 10
67
+ assert_equal(expected_total_tax, invoice.total_tax)
68
+
69
+ # Change the tax_amount of the first line item and make sure that
70
+ # everything still continues to add up.
71
+ line_item.tax_amount = line_item.tax_amount + 10
72
+ assert_not_equal(expected_total_tax, invoice.total_tax)
73
+ expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
74
+ assert_equal(expected_total_tax, invoice.total_tax)
75
+ end
76
+
77
+ # Tests the total calculation and that setting it manually doesn't modify the data.
78
+ def test_invoice_sub_total_calculation
79
+ invoice = create_test_invoice
80
+ line_item = invoice.line_items.first
81
+
82
+ # Make sure that everything adds up to begin with.
83
+ expected_total = invoice.sub_total + invoice.total_tax
84
+ assert_equal(expected_total, invoice.total)
85
+
86
+ # Change the total and check that it doesn't modify anything.
87
+ invoice.total = expected_total * 10
88
+ assert_equal(expected_total, invoice.total)
89
+
90
+ # Change the quantity of the first line item and make sure that
91
+ # everything still continues to add up.
92
+ line_item.quantity = line_item.quantity + 5
93
+ assert_not_equal(expected_total, invoice.total)
94
+ expected_total = invoice.sub_total + invoice.total_tax
95
+ assert_equal(expected_total, invoice.total)
96
+ end
97
+
98
+ # Tests that the LineItem#line_amount calculation is working correctly.
99
+ def test_line_amount_calculation
100
+ invoice = create_test_invoice
101
+ line_item = invoice.line_items.first
102
+
103
+ # Make sure that everything adds up to begin with.
104
+ expected_amount = line_item.quantity * line_item.unit_amount
105
+ assert_equal(expected_amount, line_item.line_amount)
106
+
107
+ # Change the line_amount and check that it doesn't modify anything.
108
+ line_item.line_amount = expected_amount * 10
109
+ assert_equal(expected_amount, line_item.line_amount)
110
+
111
+ # Change the quantity and check that the line_amount has been updated.
112
+ quantity = line_item.quantity + 2
113
+ line_item.quantity = quantity
114
+ assert_not_equal(expected_amount, line_item.line_amount)
115
+ assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
116
+ end
117
+
118
+ # Ensure that the totalling methods don't raise exceptions, even when
119
+ # invoice.line_items is empty.
120
+ def test_totalling_methods_when_line_items_empty
121
+ invoice = create_test_invoice
122
+ invoice.line_items = []
123
+
124
+ assert_nothing_raised(Exception) {
125
+ assert_equal(BigDecimal.new('0'), invoice.sub_total)
126
+ assert_equal(BigDecimal.new('0'), invoice.total_tax)
127
+ assert_equal(BigDecimal.new('0'), invoice.total)
128
+ }
129
+ end
130
+
131
+ def test_invoice_type_helper_methods
132
+ # Test accounts receivable invoices.
133
+ invoice = create_test_invoice({:invoice_type => 'ACCREC'})
134
+ assert_equal(true, invoice.accounts_receivable?, "Accounts RECEIVABLE invoice doesn't think it is.")
135
+ assert_equal(false, invoice.accounts_payable?, "Accounts RECEIVABLE invoice thinks it's payable.")
136
+
137
+ # Test accounts payable invoices.
138
+ invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
139
+ assert_equal(false, invoice.accounts_receivable?, "Accounts PAYABLE invoice doesn't think it is.")
140
+ assert_equal(true, invoice.accounts_payable?, "Accounts PAYABLE invoice thinks it's receivable.")
141
+ end
36
142
 
37
- def create_test_invoice
38
- invoice = XeroGateway::Invoice.new(:invoice_type => "THE INVOICE TYPE")
39
- invoice.date = Time.now
40
- invoice.due_date = Time.now + 10
41
- invoice.invoice_number = "12345"
42
- invoice.reference = "MY REFERENCE FOR THIS INVOICE"
43
- invoice.includes_tax = false
44
- invoice.sub_total = BigDecimal.new("1000")
45
- invoice.total_tax = BigDecimal.new("125")
46
- invoice.total = BigDecimal.new("1125")
47
-
48
- invoice.contact = XeroGateway::Contact.new(:contact_id => 55555)
49
- invoice.contact.name = "CONTACT NAME"
50
- invoice.contact.address.address_type = "THE ADDRESS TYPE FOR THE CONTACT"
51
- invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
52
- invoice.contact.phone.number = "12345"
53
-
54
- invoice.line_items << XeroGateway::LineItem.new({
143
+
144
+ # Make sure that the create_test_invoice method is working correctly
145
+ # with all the defaults and overrides.
146
+ def test_create_test_invoice_defaults_working
147
+ invoice = create_test_invoice
148
+
149
+ # Test invoice defaults.
150
+ assert_equal('ACCREC', invoice.invoice_type)
151
+ assert_kind_of(Time, invoice.date)
152
+ assert_kind_of(Time, invoice.due_date)
153
+ assert_equal('12345', invoice.invoice_number)
154
+ assert_equal('MY REFERENCE FOR THIS INVOICE', invoice.reference)
155
+ assert_equal(false, invoice.includes_tax)
156
+
157
+ # Test the contact defaults.
158
+ assert_equal('00000000-0000-0000-0000-000000000000', invoice.contact.contact_id)
159
+ assert_equal('CONTACT NAME', invoice.contact.name)
160
+
161
+ # Test address defaults.
162
+ assert_equal('DEFAULT', invoice.contact.address.address_type)
163
+ assert_equal('LINE 1 OF THE ADDRESS', invoice.contact.address.line_1)
164
+
165
+ # Test phone defaults.
166
+ assert_equal('DEFAULT', invoice.contact.phone.phone_type)
167
+ assert_equal('12345678', invoice.contact.phone.number)
168
+
169
+ # Test the line_item defaults.
170
+ assert_equal('A LINE ITEM', invoice.line_items.first.description)
171
+ assert_equal('200', invoice.line_items.first.account_code)
172
+ assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
173
+ assert_equal(BigDecimal.new('12.5'), invoice.line_items.first.tax_amount)
174
+
175
+ # Test overriding an invoice parameter (assume works for all).
176
+ invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
177
+ assert_equal('ACCPAY', invoice.invoice_type)
178
+
179
+ # Test overriding a contact/address/phone parameter (assume works for all).
180
+ invoice = create_test_invoice({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
181
+ assert_equal('OVERRIDDEN NAME', invoice.contact.name)
182
+ assert_equal('OVERRIDDEN LINE 1', invoice.contact.address.line_1)
183
+ assert_equal('999', invoice.contact.phone.number)
184
+
185
+ # Test overriding line_items with hash.
186
+ invoice = create_test_invoice({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
187
+ assert_equal(1, invoice.line_items.size)
188
+ assert_equal('OVERRIDDEN LINE ITEM', invoice.line_items.first.description)
189
+ assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
190
+
191
+ # Test overriding line_items with array of 2 line_items.
192
+ invoice = create_test_invoice({}, {}, [
193
+ {:description => 'OVERRIDDEN ITEM 1'},
194
+ {:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal.new('200'), :tax_amount => '25.0'}
195
+ ])
196
+ assert_equal(2, invoice.line_items.size)
197
+ assert_equal('OVERRIDDEN ITEM 1', invoice.line_items[0].description)
198
+ assert_equal(BigDecimal.new('100'), invoice.line_items[0].unit_amount)
199
+ assert_equal('OVERRIDDEN ITEM 2', invoice.line_items[1].description)
200
+ assert_equal(BigDecimal.new('200'), invoice.line_items[1].unit_amount)
201
+ end
202
+
203
+ private
204
+
205
+ def create_test_invoice(invoice_params = {}, contact_params = {}, line_item_params = [])
206
+ invoice_params = {
207
+ :invoice_type => 'ACCREC',
208
+ :date => Time.now,
209
+ :due_date => Time.now + (10 * 24 * 3600), # 10 days in the future
210
+ :invoice_number => '12345',
211
+ :reference => "MY REFERENCE FOR THIS INVOICE",
212
+ :includes_tax => false
213
+ }.merge(invoice_params)
214
+ invoice = XeroGateway::Invoice.new(invoice_params)
215
+
216
+ # Strip out :address key from contact_params to use as the default address.
217
+ stripped_address = {
218
+ :address_type => 'DEFAULT',
219
+ :line_1 => 'LINE 1 OF THE ADDRESS'
220
+ }.merge(contact_params.delete(:address) || {})
221
+
222
+ # Strip out :phone key from contact_params to use at the default phone.
223
+ stripped_phone = {
224
+ :phone_type => 'DEFAULT',
225
+ :number => '12345678'
226
+ }.merge(contact_params.delete(:phone) || {})
227
+
228
+ contact_params = {
229
+ :contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
230
+ :name => "CONTACT NAME"
231
+ }.merge(contact_params)
232
+
233
+ # Create invoice.contact from contact_params.
234
+ invoice.contact = XeroGateway::Contact.new(contact_params)
235
+ invoice.contact.address = XeroGateway::Address.new(stripped_address)
236
+ invoice.contact.phone = XeroGateway::Phone.new(stripped_phone)
237
+
238
+ line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
239
+
240
+ # At least one line item, make first have some defaults.
241
+ line_item_params << {} if line_item_params.size == 0
242
+ line_item_params[0] = {
55
243
  :description => "A LINE ITEM",
56
244
  :account_code => "200",
57
245
  :unit_amount => BigDecimal.new("100"),
58
- :tax_amount => BigDecimal.new("12.5"),
59
- :line_amount => BigDecimal.new("125")
60
- })
246
+ :tax_amount => BigDecimal.new("12.5")
247
+ }.merge(line_item_params[0])
248
+
249
+ # Create invoice.line_items from line_item_params
250
+ line_item_params.each do | line_item |
251
+ invoice.line_items << XeroGateway::LineItem.new(line_item)
252
+ end
253
+
61
254
  invoice
62
255
  end
63
256
  end