PageRenderTime 27ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/test/unit/credit_note_test.rb

http://github.com/tlconnor/xero_gateway
Ruby | 272 lines | 178 code | 51 blank | 43 comment | 5 complexity | fe15fbf9b8aa627b479e7edc24a1d6a6 MD5 | raw file
Possible License(s): 0BSD
  1. require File.join(File.dirname(__FILE__), '../test_helper.rb')
  2. class CreditNoteTest < Test::Unit::TestCase
  3. # Tests that a credit note can be converted into XML that Xero can understand, and then converted back to a credit note
  4. def test_build_and_parse_xml
  5. credit_note = create_test_credit_note
  6. # Generate the XML message
  7. credit_note_as_xml = credit_note.to_xml
  8. # Parse the XML message and retrieve the credit_note element
  9. credit_note_element = REXML::XPath.first(REXML::Document.new(credit_note_as_xml), "/CreditNote")
  10. # Build a new credit_note from the XML
  11. result_credit_note = XeroGateway::CreditNote.from_xml(credit_note_element)
  12. assert_equal(credit_note, result_credit_note)
  13. end
  14. # Tests the sub_total calculation and that setting it manually doesn't modify the data.
  15. def test_credit_note_sub_total_calculation
  16. credit_note = create_test_credit_note
  17. line_item = credit_note.line_items.first
  18. # Make sure that everything adds up to begin with.
  19. expected_sub_total = credit_note.line_items.inject(BigDecimal('0')) { | sum, l | l.line_amount }
  20. assert_equal(expected_sub_total, credit_note.sub_total)
  21. # Change the amount of the first line item and make sure that
  22. # everything still continues to add up.
  23. line_item.unit_amount = line_item.unit_amount + 10
  24. assert_not_equal(expected_sub_total, credit_note.sub_total)
  25. expected_sub_total = credit_note.line_items.inject(BigDecimal('0')) { | sum, l | l.line_amount }
  26. assert_equal(expected_sub_total, credit_note.sub_total)
  27. end
  28. # Tests the total_tax calculation and that setting it manually doesn't modify the data.
  29. def test_credit_note_sub_total_calculation2
  30. credit_note = create_test_credit_note
  31. line_item = credit_note.line_items.first
  32. # Make sure that everything adds up to begin with.
  33. expected_total_tax = credit_note.line_items.inject(BigDecimal('0')) { | sum, l | l.tax_amount }
  34. assert_equal(expected_total_tax, credit_note.total_tax)
  35. # Change the tax_amount of the first line item and make sure that
  36. # everything still continues to add up.
  37. line_item.tax_amount = line_item.tax_amount + 10
  38. assert_not_equal(expected_total_tax, credit_note.total_tax)
  39. expected_total_tax = credit_note.line_items.inject(BigDecimal('0')) { | sum, l | l.tax_amount }
  40. assert_equal(expected_total_tax, credit_note.total_tax)
  41. end
  42. # Tests the total calculation and that setting it manually doesn't modify the data.
  43. def test_credit_note_sub_total_calculation3
  44. credit_note = create_test_credit_note
  45. line_item = credit_note.line_items.first
  46. # Make sure that everything adds up to begin with.
  47. expected_total = credit_note.sub_total + credit_note.total_tax
  48. assert_equal(expected_total, credit_note.total)
  49. # Change the quantity of the first line item and make sure that
  50. # everything still continues to add up.
  51. line_item.quantity = line_item.quantity + 5
  52. assert_not_equal(expected_total, credit_note.total)
  53. expected_total = credit_note.sub_total + credit_note.total_tax
  54. assert_equal(expected_total, credit_note.total)
  55. end
  56. # Tests that the LineItem#line_amount calculation is working correctly.
  57. def test_line_amount_calculation
  58. credit_note = create_test_credit_note
  59. line_item = credit_note.line_items.first
  60. # Make sure that everything adds up to begin with.
  61. expected_amount = line_item.quantity * line_item.unit_amount
  62. assert_equal(expected_amount, line_item.line_amount)
  63. # Change the line_amount and check that it doesn't modify anything.
  64. line_item.line_amount = expected_amount * 10
  65. assert_equal(expected_amount, line_item.line_amount)
  66. # Change the quantity and check that the line_amount has been updated.
  67. quantity = line_item.quantity + 2
  68. line_item.quantity = quantity
  69. assert_not_equal(expected_amount, line_item.line_amount)
  70. assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
  71. end
  72. # Ensure that the totalling methods don't raise exceptions, even when
  73. # credit_note.line_items is empty.
  74. def test_totalling_methods_when_line_items_empty
  75. credit_note = create_test_credit_note
  76. credit_note.line_items = []
  77. assert_nothing_raised(Exception) {
  78. assert_equal(BigDecimal('0'), credit_note.sub_total)
  79. assert_equal(BigDecimal('0'), credit_note.total_tax)
  80. assert_equal(BigDecimal('0'), credit_note.total)
  81. }
  82. end
  83. def test_type_helper_methods
  84. # Test accounts receivable credit_notes.
  85. credit_note = create_test_credit_note({:type => 'ACCRECCREDIT'})
  86. assert_equal(true, credit_note.accounts_receivable?, "Accounts RECEIVABLE credit_note doesn't think it is.")
  87. assert_equal(false, credit_note.accounts_payable?, "Accounts RECEIVABLE credit_note thinks it's payable.")
  88. # Test accounts payable credit_notes.
  89. credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
  90. assert_equal(false, credit_note.accounts_receivable?, "Accounts PAYABLE credit_note doesn't think it is.")
  91. assert_equal(true, credit_note.accounts_payable?, "Accounts PAYABLE credit_note thinks it's receivable.")
  92. end
  93. # Make sure that the create_test_credit_note method is working correctly
  94. # with all the defaults and overrides.
  95. def test_create_test_credit_note_defaults_working
  96. credit_note = create_test_credit_note
  97. # Test credit_note defaults.
  98. assert_equal('ACCRECCREDIT', credit_note.type)
  99. assert_kind_of(Date, credit_note.date)
  100. assert_equal('12345', credit_note.credit_note_number)
  101. assert_equal('MY REFERENCE FOR THIS CREDIT NOTE', credit_note.reference)
  102. assert_equal("Exclusive", credit_note.line_amount_types)
  103. # Test the contact defaults.
  104. assert_equal('00000000-0000-0000-0000-000000000000', credit_note.contact.contact_id)
  105. assert_equal('CONTACT NAME', credit_note.contact.name)
  106. # Test address defaults.
  107. assert_equal('DEFAULT', credit_note.contact.address.address_type)
  108. assert_equal('LINE 1 OF THE ADDRESS', credit_note.contact.address.line_1)
  109. # Test phone defaults.
  110. assert_equal('DEFAULT', credit_note.contact.phone.phone_type)
  111. assert_equal('12345678', credit_note.contact.phone.number)
  112. # Test the line_item defaults.
  113. assert_equal('A LINE ITEM', credit_note.line_items.first.description)
  114. assert_equal('200', credit_note.line_items.first.account_code)
  115. assert_equal(BigDecimal('100'), credit_note.line_items.first.unit_amount)
  116. assert_equal(BigDecimal('12.5'), credit_note.line_items.first.tax_amount)
  117. # Test overriding an credit_note parameter (assume works for all).
  118. credit_note = create_test_credit_note({:type => 'ACCPAYCREDIT'})
  119. assert_equal('ACCPAYCREDIT', credit_note.type)
  120. # Test overriding a contact/address/phone parameter (assume works for all).
  121. credit_note = create_test_credit_note({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
  122. assert_equal('OVERRIDDEN NAME', credit_note.contact.name)
  123. assert_equal('OVERRIDDEN LINE 1', credit_note.contact.address.line_1)
  124. assert_equal('999', credit_note.contact.phone.number)
  125. # Test overriding line_items with hash.
  126. credit_note = create_test_credit_note({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
  127. assert_equal(1, credit_note.line_items.size)
  128. assert_equal('OVERRIDDEN LINE ITEM', credit_note.line_items.first.description)
  129. assert_equal(BigDecimal('100'), credit_note.line_items.first.unit_amount)
  130. # Test overriding line_items with array of 2 line_items.
  131. credit_note = create_test_credit_note({}, {}, [
  132. {:description => 'OVERRIDDEN ITEM 1'},
  133. {:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal('200'), :tax_amount => '25.0'}
  134. ])
  135. assert_equal(2, credit_note.line_items.size)
  136. assert_equal('OVERRIDDEN ITEM 1', credit_note.line_items[0].description)
  137. assert_equal(BigDecimal('100'), credit_note.line_items[0].unit_amount)
  138. assert_equal('OVERRIDDEN ITEM 2', credit_note.line_items[1].description)
  139. assert_equal(BigDecimal('200'), credit_note.line_items[1].unit_amount)
  140. end
  141. def test_auto_creation_of_associated_contact
  142. credit_note = create_test_credit_note({}, nil) # no contact
  143. assert(!credit_note.instance_variable_defined?("@contact"))
  144. new_contact = credit_note.contact
  145. assert_kind_of(XeroGateway::Contact, new_contact)
  146. end
  147. def test_add_line_item
  148. credit_note = create_test_credit_note({}, {}, nil) # no line_items
  149. assert_equal(0, credit_note.line_items.size)
  150. line_item_params = {:description => "Test Item 1", :unit_amount => 100}
  151. # Test adding line item by hash
  152. line_item = credit_note.add_line_item(line_item_params)
  153. assert_kind_of(XeroGateway::LineItem, line_item)
  154. assert_equal(line_item_params[:description], line_item.description)
  155. assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
  156. assert_equal(1, credit_note.line_items.size)
  157. # Test adding line item by XeroGateway::LineItem
  158. line_item = credit_note.add_line_item(line_item_params)
  159. assert_kind_of(XeroGateway::LineItem, line_item)
  160. assert_equal(line_item_params[:description], line_item.description)
  161. assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
  162. assert_equal(2, credit_note.line_items.size)
  163. # Test that pushing anything else into add_line_item fails.
  164. ["invalid", 100, nil, []].each do | invalid_object |
  165. assert_raise(XeroGateway::InvalidLineItemError) { credit_note.add_line_item(invalid_object) }
  166. assert_equal(2, credit_note.line_items.size)
  167. end
  168. end
  169. private
  170. def create_test_credit_note(credit_note_params = {}, contact_params = {}, line_item_params = [])
  171. unless credit_note_params.nil?
  172. credit_note_params = {
  173. :type => 'ACCRECCREDIT',
  174. :date => Date.today,
  175. :credit_note_number => '12345',
  176. :reference => "MY REFERENCE FOR THIS CREDIT NOTE",
  177. :line_amount_types => "Exclusive"
  178. }.merge(credit_note_params)
  179. end
  180. credit_note = XeroGateway::CreditNote.new(credit_note_params || {})
  181. unless contact_params.nil?
  182. # Strip out :address key from contact_params to use as the default address.
  183. stripped_address = {
  184. :address_type => 'DEFAULT',
  185. :line_1 => 'LINE 1 OF THE ADDRESS'
  186. }.merge(contact_params.delete(:address) || {})
  187. # Strip out :phone key from contact_params to use at the default phone.
  188. stripped_phone = {
  189. :phone_type => 'DEFAULT',
  190. :number => '12345678'
  191. }.merge(contact_params.delete(:phone) || {})
  192. contact_params = {
  193. :contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
  194. :name => "CONTACT NAME",
  195. :first_name => "Bob",
  196. :last_name => "Builder"
  197. }.merge(contact_params)
  198. # Create credit_note.contact from contact_params.
  199. credit_note.contact = XeroGateway::Contact.new(contact_params)
  200. credit_note.contact.address = XeroGateway::Address.new(stripped_address)
  201. credit_note.contact.phone = XeroGateway::Phone.new(stripped_phone)
  202. end
  203. unless line_item_params.nil?
  204. line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
  205. # At least one line item, make first have some defaults.
  206. line_item_params << {} if line_item_params.size == 0
  207. line_item_params[0] = {
  208. :description => "A LINE ITEM",
  209. :account_code => "200",
  210. :unit_amount => BigDecimal("100"),
  211. :tax_amount => BigDecimal("12.5"),
  212. :tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
  213. }.merge(line_item_params[0])
  214. # Create credit_note.line_items from line_item_params
  215. line_item_params.each do | line_item |
  216. credit_note.add_line_item(line_item)
  217. end
  218. end
  219. credit_note
  220. end
  221. end