test/unit/invoice_test.rb in xero_gateway-2.3.0 vs test/unit/invoice_test.rb in xero_gateway-2.4.0
- old
+ new
@@ -1,18 +1,49 @@
require File.join(File.dirname(__FILE__), '../test_helper.rb')
class InvoiceTest < Test::Unit::TestCase
context "with line item totals" do
+ setup do
+ # make sure the invoices think they have a gateway
+ @invoice = create_test_invoice(
+ invoice_id: "a99a9aaa-9999-99a9-9aa9-aaaaaa9a9999",
+ line_items_downloaded: false,
+ total: 6_969_00,
+ total_tax: 1_045.35,
+ sub_total: 5_923.65
+ )
+ @invoice.gateway = stub
+ end
should "allow setting and reading these as instance variables without downloading line items" do
- invoice = create_test_invoice(:line_items_downloaded => false, :total => 6969_00)
+ assert !@invoice.line_items_downloaded?
- assert !invoice.line_items_downloaded?
XeroGateway::Invoice.any_instance.expects(:download_line_items).never
- assert_equal 6969_00, invoice.total
+ assert_equal 6969_00, @invoice.total
+ assert_equal 1_045.35, @invoice.total_tax
+ assert_equal 5_923.65, @invoice.sub_total
end
+
+ should "download line items if we call #line_items" do
+ XeroGateway::Invoice.any_instance.expects(:download_line_items).once.returns([])
+ assert_equal [], @invoice.line_items
+ end
+
+ should "also work when creating an invoice from XML" do
+ invoices_response_xml = File.open(File.join(File.dirname(__FILE__), "..", "stub_responses", "invoices.xml")).read
+ invoice_element = REXML::XPath.first(REXML::Document.new(invoices_response_xml), "/Response/Invoices/Invoice")
+ from_xml = XeroGateway::Invoice.from_xml(invoice_element)
+ from_xml.gateway = stub()
+
+ assert !from_xml.line_items_downloaded?
+ XeroGateway::Invoice.any_instance.expects(:download_line_items).never
+ assert_equal 1125.0, from_xml.total
+ assert_equal 125.0, from_xml.total_tax
+ assert_equal 1000.0, from_xml.sub_total
+ end
+
end
context "building and parsing XML" do
should "work vice versa" do
invoice = create_test_invoice
@@ -30,74 +61,74 @@
end
should "work for optional params" do
invoice = create_test_invoice(:url => 'http://example.com?with=params&and=more')
invoice_element = REXML::XPath.first(REXML::Document.new(invoice.to_xml), "/Invoice")
- assert_match /<Url>http:\/\/example.com\?with=params&and=more<\/Url>/, invoice_element.to_s
+ assert_match(/<Url>http:\/\/example.com\?with=params&and=more<\/Url>/, invoice_element.to_s)
parsed_invoice = XeroGateway::Invoice.from_xml(invoice_element)
assert_equal 'http://example.com?with=params&and=more', parsed_invoice.url
end
end
# Tests the sub_total calculation and that setting it manually doesn't modify the data.
def test_invoice_sub_total_calculation
invoice = create_test_invoice(:line_items_downloaded => true)
line_item = invoice.line_items.first
-
+
# Make sure that everything adds up to begin with.
- expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
+ expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, l | l.line_amount }
assert_equal(expected_sub_total, invoice.sub_total)
-
+
# Change the sub_total and check that it doesn't modify anything.
invoice.sub_total = expected_sub_total * 10
assert_equal(expected_sub_total, invoice.sub_total)
-
- # Change the amount of the first line item and make sure that
+
+ # Change the amount of the first line item and make sure that
# everything still continues to add up.
line_item.unit_amount = line_item.unit_amount + 10
assert_not_equal(expected_sub_total, invoice.sub_total)
- expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.line_amount }
+ expected_sub_total = invoice.line_items.inject(BigDecimal.new('0')) { | sum, l | l.line_amount }
assert_equal(expected_sub_total, invoice.sub_total)
end
-
+
# Tests the total_tax calculation and that setting it manually doesn't modify the data.
def test_invoice_sub_total_calculation2
invoice = create_test_invoice(:line_items_downloaded => true)
line_item = invoice.line_items.first
-
+
# Make sure that everything adds up to begin with.
- expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
+ expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, l | l.tax_amount }
assert_equal(expected_total_tax, invoice.total_tax)
-
+
# Change the total_tax and check that it doesn't modify anything.
invoice.total_tax = expected_total_tax * 10
assert_equal(expected_total_tax, invoice.total_tax)
-
- # Change the tax_amount of the first line item and make sure that
+
+ # Change the tax_amount of the first line item and make sure that
# everything still continues to add up.
line_item.tax_amount = line_item.tax_amount + 10
assert_not_equal(expected_total_tax, invoice.total_tax)
- expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, line_item | line_item.tax_amount }
+ expected_total_tax = invoice.line_items.inject(BigDecimal.new('0')) { | sum, l | l.tax_amount }
assert_equal(expected_total_tax, invoice.total_tax)
end
# Tests the total calculation and that setting it manually doesn't modify the data.
def test_invoice_sub_total_calculation3
invoice = create_test_invoice(:line_items_downloaded => true)
assert invoice.line_items_downloaded?
line_item = invoice.line_items.first
-
+
# Make sure that everything adds up to begin with.
expected_total = invoice.sub_total + invoice.total_tax
assert_equal(expected_total, invoice.total)
-
+
# Change the total and check that it doesn't modify anything.
invoice.total = expected_total * 10
assert_equal(expected_total.to_f, invoice.total.to_f)
-
- # Change the quantity of the first line item and make sure that
+
+ # Change the quantity of the first line item and make sure that
# everything still continues to add up.
line_item.quantity = line_item.quantity + 5
assert_not_equal(expected_total, invoice.total)
expected_total = invoice.sub_total + invoice.total_tax
assert_equal(expected_total, invoice.total)
@@ -105,78 +136,78 @@
# Tests that the LineItem#line_amount calculation is working correctly.
def test_line_amount_calculation
invoice = create_test_invoice
line_item = invoice.line_items.first
-
+
# Make sure that everything adds up to begin with.
expected_amount = line_item.quantity * line_item.unit_amount
assert_equal(expected_amount, line_item.line_amount)
-
+
# Change the line_amount and check that it doesn't modify anything.
line_item.line_amount = expected_amount * 10
assert_equal(expected_amount, line_item.line_amount)
-
+
# Change the quantity and check that the line_amount has been updated.
quantity = line_item.quantity + 2
line_item.quantity = quantity
assert_not_equal(expected_amount, line_item.line_amount)
assert_equal(quantity * line_item.unit_amount, line_item.line_amount)
end
-
+
# Ensure that the totalling methods don't raise exceptions, even when
# invoice.line_items is empty.
def test_totalling_methods_when_line_items_empty
invoice = create_test_invoice
invoice.line_items = []
-
+
assert_nothing_raised(Exception) {
assert_equal(BigDecimal.new('0'), invoice.sub_total)
assert_equal(BigDecimal.new('0'), invoice.total_tax)
assert_equal(BigDecimal.new('0'), invoice.total)
}
end
-
+
def test_invoice_type_helper_methods
# Test accounts receivable invoices.
invoice = create_test_invoice({:invoice_type => 'ACCREC'})
assert_equal(true, invoice.accounts_receivable?, "Accounts RECEIVABLE invoice doesn't think it is.")
assert_equal(false, invoice.accounts_payable?, "Accounts RECEIVABLE invoice thinks it's payable.")
-
+
# Test accounts payable invoices.
invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
assert_equal(false, invoice.accounts_receivable?, "Accounts PAYABLE invoice doesn't think it is.")
assert_equal(true, invoice.accounts_payable?, "Accounts PAYABLE invoice thinks it's receivable.")
end
-
-
+
+
# Make sure that the create_test_invoice method is working correctly
# with all the defaults and overrides.
def test_create_test_invoice_defaults_working
invoice = create_test_invoice
-
+
# Test invoice defaults.
assert_equal('ACCREC', invoice.invoice_type)
assert_kind_of(Date, invoice.date)
assert_kind_of(Date, invoice.due_date)
assert_kind_of(Time, invoice.updated_date_utc)
assert_equal('12345', invoice.invoice_number)
assert_equal('MY REFERENCE FOR THIS INVOICE', invoice.reference)
assert_equal("Exclusive", invoice.line_amount_types)
-
+
# Test the contact defaults.
assert_equal('00000000-0000-0000-0000-000000000000', invoice.contact.contact_id)
assert_equal('CONTACT NAME', invoice.contact.name)
-
+
# Test address defaults.
assert_equal('DEFAULT', invoice.contact.address.address_type)
assert_equal('LINE 1 OF THE ADDRESS', invoice.contact.address.line_1)
-
+
# Test phone defaults.
assert_equal('DEFAULT', invoice.contact.phone.phone_type)
assert_equal('12345678', invoice.contact.phone.number)
-
+
# Test the line_item defaults.
assert_equal('A LINE ITEM', invoice.line_items.first.description)
assert_equal('200', invoice.line_items.first.account_code)
assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
assert_equal(BigDecimal.new('12.5'), invoice.line_items.first.tax_amount)
@@ -185,23 +216,23 @@
assert_nil invoice.url
# Test overriding an invoice parameter (assume works for all).
invoice = create_test_invoice({:invoice_type => 'ACCPAY'})
assert_equal('ACCPAY', invoice.invoice_type)
-
+
# Test overriding a contact/address/phone parameter (assume works for all).
invoice = create_test_invoice({}, {:name => 'OVERRIDDEN NAME', :address => {:line_1 => 'OVERRIDDEN LINE 1'}, :phone => {:number => '999'}})
assert_equal('OVERRIDDEN NAME', invoice.contact.name)
assert_equal('OVERRIDDEN LINE 1', invoice.contact.address.line_1)
assert_equal('999', invoice.contact.phone.number)
-
+
# Test overriding line_items with hash.
invoice = create_test_invoice({}, {}, {:description => 'OVERRIDDEN LINE ITEM'})
assert_equal(1, invoice.line_items.size)
assert_equal('OVERRIDDEN LINE ITEM', invoice.line_items.first.description)
assert_equal(BigDecimal.new('100'), invoice.line_items.first.unit_amount)
-
+
# Test overriding line_items with array of 2 line_items.
invoice = create_test_invoice({}, {}, [
{:description => 'OVERRIDDEN ITEM 1'},
{:description => 'OVERRIDDEN ITEM 2', :account_code => '200', :unit_amount => BigDecimal.new('200'), :tax_amount => '25.0'}
])
@@ -209,32 +240,32 @@
assert_equal('OVERRIDDEN ITEM 1', invoice.line_items[0].description)
assert_equal(BigDecimal.new('100'), invoice.line_items[0].unit_amount)
assert_equal('OVERRIDDEN ITEM 2', invoice.line_items[1].description)
assert_equal(BigDecimal.new('200'), invoice.line_items[1].unit_amount)
end
-
+
def test_auto_creation_of_associated_contact
invoice = create_test_invoice({}, nil) # no contact
- assert_nil(invoice.instance_variable_get("@contact"))
-
+ assert(!invoice.instance_variable_defined?("@contact"))
+
new_contact = invoice.contact
assert_kind_of(XeroGateway::Contact, new_contact)
end
-
+
def test_add_line_item
invoice = create_test_invoice({}, {}, nil) # no line_items
assert_equal(0, invoice.line_items.size)
-
+
line_item_params = {:description => "Test Item 1", :unit_amount => 100}
-
+
# Test adding line item by hash
line_item = invoice.add_line_item(line_item_params)
assert_kind_of(XeroGateway::LineItem, line_item)
assert_equal(line_item_params[:description], line_item.description)
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
assert_equal(1, invoice.line_items.size)
-
+
# Test adding line item by XeroGateway::LineItem
line_item = invoice.add_line_item(line_item_params)
assert_kind_of(XeroGateway::LineItem, line_item)
assert_equal(line_item_params[:description], line_item.description)
assert_equal(line_item_params[:unit_amount], line_item.unit_amount)
@@ -251,23 +282,28 @@
invoice = XeroGateway::Invoice.new
assert_equal(invoice.line_amount_types, 'Exclusive')
end
def test_optional_params
- invoice = create_test_invoice(:url => 'http://example.com', :branding_theme_id => 'a94a78db-5cc6-4e26-a52b-045237e56e6e')
+ eur_code = "EUR"
+ eur_rate = 1.80
+
+ invoice = create_test_invoice(:url => 'http://example.com', :branding_theme_id => 'a94a78db-5cc6-4e26-a52b-045237e56e6e', :currency_code => eur_code, :currency_rate => eur_rate)
assert_equal 'http://example.com', invoice.url
assert_equal 'a94a78db-5cc6-4e26-a52b-045237e56e6e', invoice.branding_theme_id
+ assert_equal eur_code, invoice.currency_code
+ assert_equal eur_rate, invoice.currency_rate
end
def test_updated_date_utc
time = Time.now.utc
invoice = create_test_invoice(:updated_date_utc => time)
assert_equal time, invoice.updated_date_utc
end
private
-
+
def create_test_invoice(invoice_params = {}, contact_params = {}, line_item_params = [])
unless invoice_params.nil?
invoice_params = {
:invoice_type => 'ACCREC',
:date => Date.today,
@@ -277,55 +313,55 @@
:line_amount_types => "Exclusive",
:updated_date_utc => Time.now.utc
}.merge(invoice_params)
end
invoice = XeroGateway::Invoice.new(invoice_params || {})
-
+
unless contact_params.nil?
# Strip out :address key from contact_params to use as the default address.
stripped_address = {
:address_type => 'DEFAULT',
:line_1 => 'LINE 1 OF THE ADDRESS'
}.merge(contact_params.delete(:address) || {})
-
+
# Strip out :phone key from contact_params to use at the default phone.
stripped_phone = {
:phone_type => 'DEFAULT',
:number => '12345678'
}.merge(contact_params.delete(:phone) || {})
-
+
contact_params = {
:contact_id => '00000000-0000-0000-0000-000000000000', # Just any valid GUID
:name => "CONTACT NAME",
:first_name => "Bob",
:last_name => "Builder"
}.merge(contact_params)
-
+
# Create invoice.contact from contact_params.
invoice.contact = XeroGateway::Contact.new(contact_params)
invoice.contact.address = XeroGateway::Address.new(stripped_address)
invoice.contact.phone = XeroGateway::Phone.new(stripped_phone)
end
-
+
unless line_item_params.nil?
line_item_params = [line_item_params].flatten # always use an array, even if only a single hash passed in
-
+
# At least one line item, make first have some defaults.
line_item_params << {} if line_item_params.size == 0
line_item_params[0] = {
:description => "A LINE ITEM",
:account_code => "200",
:unit_amount => BigDecimal.new("100"),
:tax_amount => BigDecimal.new("12.5"),
:tracking => XeroGateway::TrackingCategory.new(:name => "blah", :options => "hello")
}.merge(line_item_params[0])
-
+
# Create invoice.line_items from line_item_params
line_item_params.each do | line_item |
invoice.add_line_item(line_item)
end
end
-
+
invoice
end
# NB: Xero no longer appears to provide XSDs for their api, check http://blog.xero.com/developer/api/invoices/
#