Ready for 7.10.29 development.
This commit is contained in:
commit
c806f99b7b
4236 changed files with 1217679 additions and 0 deletions
577
t/Shop/TaxDriver/EU.t
Normal file
577
t/Shop/TaxDriver/EU.t
Normal file
|
|
@ -0,0 +1,577 @@
|
|||
# vim:syntax=perl
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#------------------------------------------------------------------
|
||||
|
||||
# Write a little about what this script tests.
|
||||
#
|
||||
#
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../lib";
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
use Test::MockObject::Extends;
|
||||
use Exception::Class;
|
||||
use Data::Dumper;
|
||||
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Text;
|
||||
use WebGUI::Shop::Cart;
|
||||
use WebGUI::Shop::AddressBook;
|
||||
use WebGUI::Shop::TaxDriver::EU;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
# Test user
|
||||
my $taxUser = WebGUI::User->new( $session, 'new' );
|
||||
$taxUser->username( 'Tex Evasion' );
|
||||
$session->user({userId => $taxUser->getId});
|
||||
WebGUI::Test->addToCleanup($taxUser);
|
||||
|
||||
# Test VAT numbers
|
||||
my $testVAT_NL = 'NL123456789B12';
|
||||
my $testVAT_BE = 'BE0123456789';
|
||||
my $noServiceVAT= 'NotGonnaWork';
|
||||
my $invalidVAT = 'ByNoMeansAllowed';
|
||||
my $visitorUser = WebGUI::User->new( $session, 1 );
|
||||
|
||||
my @EU_COUNTRIES = (
|
||||
'Austria', 'Belgium', 'Bulgaria', 'Cyprus', 'Czech Republic',
|
||||
'Germany', 'Denmark', 'Estonia', 'Greece', 'Spain', 'Finland',
|
||||
'France', 'United Kingdom', 'Hungary', 'Ireland', 'Italy',
|
||||
'Lithuania', 'Luxembourg', 'Latvia', 'Malta', 'Netherlands',
|
||||
'Poland', 'Portugal', 'Romania', 'Sweden', 'Slovenia', 'Slovakia',
|
||||
);
|
||||
|
||||
# Test SKU
|
||||
my $sku = WebGUI::Asset->getRoot($session)->addChild( {
|
||||
className => 'WebGUI::Asset::Sku::Donation',
|
||||
title => 'Taxable donation',
|
||||
defaultPrice => 100.00,
|
||||
} );
|
||||
WebGUI::Test->addToCleanup($sku);
|
||||
|
||||
my $book = WebGUI::Shop::AddressBook->create($session);
|
||||
WebGUI::Test->addToCleanup($book);
|
||||
|
||||
# setup address in EU but not in residential country of merchant
|
||||
my $beAddress = $book->addAddress({
|
||||
label => 'BE',
|
||||
city => 'Antwerpen',
|
||||
country => 'Belgium',
|
||||
});
|
||||
|
||||
# setup address in residential country of merchant
|
||||
my $nlAddress = $book->addAddress({
|
||||
label => 'NL',
|
||||
city => 'Delft',
|
||||
country => 'Netherlands',
|
||||
});
|
||||
|
||||
# setup address outside EU
|
||||
my $usAddress = $book->addAddress({
|
||||
label => 'outside eu',
|
||||
city => 'New Amsterdam',
|
||||
country => 'US',
|
||||
});
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $tests = 342;
|
||||
plan tests => $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# new
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
isa_ok($taxer, 'WebGUI::Shop::TaxDriver::EU');
|
||||
|
||||
isa_ok($taxer->session, 'WebGUI::Session', 'session method returns a session object');
|
||||
|
||||
is($session->getId, $taxer->session->getId, 'session method returns OUR session object');
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# className
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
is( $taxer->className, 'WebGUI::Shop::TaxDriver::EU', 'className returns correct class name' );
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getConfigurationScreen
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
#### TODO: Figure out how to test this.
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getCountryCode / getCOuntryName
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
is( $taxer->getCountryCode( 'Netherlands' ), 'NL', 'getCountryCode returns correct code for country inside EU.' );
|
||||
is( $taxer->getCountryCode( 'United States' ), undef, 'getCountryCode returns undef for countries outside EU.' );
|
||||
|
||||
is( $taxer->getCountryName( 'NL' ), 'Netherlands', 'getCountryName returns correct name for country code within EU.' );
|
||||
is( $taxer->getCountryName( 'US' ), undef, 'getCountryName returns undef for county codes outside EU.' );
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# updateVATNumber
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
$session->user( {userId=>$taxUser->userId} );
|
||||
|
||||
# Mock the Validation module
|
||||
my $validator = Test::MockObject::Extends->new( Business::Tax::VAT::Validation->new );
|
||||
local *Business::Tax::VAT::Validation::new;
|
||||
$validator->fake_new( 'Business::Tax::VAT::Validation' );
|
||||
|
||||
eval { $taxer->updateVATNumber };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'A VAT number is required' );
|
||||
is( $e, 'A VAT number is required', 'updateVATNumber returns correct message for missing VAT number' );
|
||||
|
||||
eval { $taxer->updateVATNumber( $testVAT_NL, 'NotAUserObject' ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'Second argument must be a user object' );
|
||||
is( $e, 'The second argument must be an instanciated WebGUI::User object', 'updateVATNumber returns correct message when user object is of wrong type' );
|
||||
|
||||
eval { $taxer->updateVATNumber( $testVAT_NL, $visitorUser ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'User may not be visitor' );
|
||||
is( $e, 'Visitor cannot add VAT numbers', 'updateVATNumber returns correct message when user is visitor' );
|
||||
|
||||
for my $errorCode ( 0 .. 16 ) {
|
||||
$validator->set_always( 'check', 0 );
|
||||
$validator->set_always( 'get_last_error_code', $errorCode );
|
||||
|
||||
is(
|
||||
$taxer->updateVATNumber( $invalidVAT, $taxUser ),
|
||||
'INVALID',
|
||||
"updateVATNumber returns INVALID for error $errorCode",
|
||||
);
|
||||
}
|
||||
|
||||
for my $errorCode ( 17 .. 255 ) {
|
||||
$validator->set_always( 'check', 0 );
|
||||
$validator->set_always( 'get_last_error_code', $errorCode );
|
||||
|
||||
is(
|
||||
$taxer->updateVATNumber( $invalidVAT, $taxUser ),
|
||||
'UNKNOWN',
|
||||
"updateVATNumber returns UNKNOWN for error $errorCode",
|
||||
);
|
||||
}
|
||||
|
||||
$validator->set_always( 'check', 1 );
|
||||
$validator->set_always( 'get_last_error_code', undef );
|
||||
is(
|
||||
$taxer->updateVATNumber( $testVAT_NL, $taxUser ),
|
||||
'VALID',
|
||||
"updateVATNumber returns VALID for valid numbers",
|
||||
);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# addVATNumber
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
my $response;
|
||||
local *WebGUI::Shop::TaxDriver::EU::updateVATNumber = sub { return $response };
|
||||
|
||||
#----- invalid vat number
|
||||
$response = 'INVALID';
|
||||
is(
|
||||
$taxer->addVATNumber( $invalidVAT, $taxUser ),
|
||||
'The entered VAT number is invalid.',
|
||||
'addVATNumber returns the correct error message for invalid numbers',
|
||||
);
|
||||
|
||||
#----- service unavailable
|
||||
$response = 'UNKNOWN';
|
||||
like(
|
||||
$taxer->addVATNumber( $noServiceVAT, $taxUser ),
|
||||
qr{^Number validation is currently not available.},
|
||||
'addVATNumber returns the correct message when VIES is unavailable',
|
||||
);
|
||||
|
||||
my $workflows = WebGUI::Workflow::Instance->getAllInstances( $session );
|
||||
my ($workflow) = grep { $_->get('parameters')->{ vatNumber } eq $noServiceVAT } @{ $workflows };
|
||||
ok( defined $workflow , 'addVATNumber fires a recheck workflow when VIES is down' );
|
||||
|
||||
#----- valid number
|
||||
$response = 'VALID';
|
||||
ok(
|
||||
!defined $taxer->addVATNumber( $testVAT_NL, $taxUser ),
|
||||
'Valid VAT numbers return undef.',
|
||||
);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# recheckVATNumber
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
for my $response ( qw{ INVALID VALID UNKNOWN } ) {
|
||||
local *WebGUI::Shop::TaxDriver::EU::updateVATNumber = sub { return $response };
|
||||
|
||||
is(
|
||||
$taxer->recheckVATNumber( $invalidVAT, $taxUser ),
|
||||
$response,
|
||||
"recheckVATNumber returns correct value when updateVATNumber returns $response",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getVATNumbers / deleteVATNumber
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = setupTestNumbers();
|
||||
|
||||
my $expectNL = {
|
||||
userId => $taxUser->userId,
|
||||
countryCode => 'NL',
|
||||
vatNumber => $testVAT_NL,
|
||||
viesValidated => 1,
|
||||
viesErrorCode => undef,
|
||||
approved => 0,
|
||||
};
|
||||
my $expectBE = {
|
||||
userId => $taxUser->userId,
|
||||
countryCode => 'BE',
|
||||
vatNumber => $testVAT_BE,
|
||||
approved => 0,
|
||||
viesErrorCode => undef,
|
||||
viesValidated => 1,
|
||||
};
|
||||
|
||||
my $vatNumbers = $taxer->getVATNumbers( undef, $taxUser );
|
||||
cmp_bag( $vatNumbers, [ $expectNL, $expectBE ], 'VAT Numbers are correctly returned by getVATNumbers' );
|
||||
|
||||
$vatNumbers = $taxer->getVATNumbers( 'BE', $taxUser );
|
||||
cmp_bag( $vatNumbers, [ $expectBE ], 'getVATNumbers filters on country code when one is passed' );
|
||||
|
||||
$taxer->deleteVATNumber( $testVAT_BE, $taxUser );
|
||||
$vatNumbers = $taxer->getVATNumbers( undef, $taxUser );
|
||||
cmp_bag( $vatNumbers, [ $expectNL ], 'deleteVATNumber deletes number' );
|
||||
|
||||
$taxer->deleteVATNumber( $testVAT_NL, $taxUser );
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# addGroup / getGroupRate / deleteGroup
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = setupTestNumbers();
|
||||
|
||||
eval { $taxer->addGroup };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'addGroup requires a group name' );
|
||||
is( $e, 'A group name is required', 'addGroup returns correct message for omitted group name' );
|
||||
|
||||
eval { $taxer->addGroup( 'Dummy' ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'addGroup requires a tax rate' );
|
||||
is( $e, 'Group rate must be within 0 and 100', 'addGroup returns correct message on omitted tax rate' );
|
||||
|
||||
eval { $taxer->addGroup( 'Dummy', -1 ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'addGroup: tax rate cannot be < 0' );
|
||||
is( $e, 'Group rate must be within 0 and 100', 'addGroup returns correct message on tax rate < 0' );
|
||||
|
||||
eval { $taxer->addGroup( 'Dummy', 101 ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'addGroup: tax rate cannot be > 100' );
|
||||
is( $e, 'Group rate must be within 0 and 100', 'addGroup returns correct message on tax rate > 100' );
|
||||
|
||||
my $id0 = eval { $taxer->addGroup( 'Group0', 0 ) };
|
||||
$e = Exception::Class->caught();
|
||||
ok( !$e, 'addGroup: 0% is a valid group rate' );
|
||||
|
||||
my $id100 = eval { $taxer->addGroup( 'Group100', 100 ) };
|
||||
$e = Exception::Class->caught();
|
||||
ok( !$e, 'addGroup: 100% is a valid group rate' );
|
||||
|
||||
my $id50_5 = eval { $taxer->addGroup( 'Group50.5', 50.5 ) };
|
||||
$e = Exception::Class->caught();
|
||||
ok( !$e, 'addGroup: floats are a valid group rate' );
|
||||
|
||||
my $taxGroups = $taxer->get( 'taxGroups' );
|
||||
my $expectGroups = [
|
||||
{
|
||||
name => 'Group0',
|
||||
rate => 0,
|
||||
id => $id0,
|
||||
},
|
||||
{
|
||||
name => 'Group100',
|
||||
rate => 100,
|
||||
id => $id100,
|
||||
},
|
||||
{
|
||||
name => 'Group50.5',
|
||||
rate => 50.5,
|
||||
id => $id50_5,
|
||||
},
|
||||
];
|
||||
cmp_bag( $taxGroups, $expectGroups, 'addGroup saves correctly' );
|
||||
|
||||
# getGroupRate
|
||||
ok(
|
||||
$taxer->getGroupRate( $id0 ) == 0
|
||||
&& $taxer->getGroupRate( $id100 ) == 100
|
||||
&& $taxer->getGroupRate( $id50_5 ) == 50.5,
|
||||
'getGroup rate gets correct rates'
|
||||
);
|
||||
|
||||
# deleteGroup
|
||||
eval { $taxer->deleteGroup };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'addGroup requires a group id' );
|
||||
is( $e, 'A group id is required', 'addGroup returns correct message for missing group id' );
|
||||
|
||||
$taxer->deleteGroup( $id50_5 );
|
||||
|
||||
$taxGroups = $taxer->get( 'taxGroups' );
|
||||
cmp_bag( $taxGroups, [
|
||||
{
|
||||
name => 'Group0',
|
||||
rate => 0,
|
||||
id => $id0,
|
||||
},
|
||||
{
|
||||
name => 'Group100',
|
||||
rate => 100,
|
||||
id => $id100,
|
||||
},
|
||||
], 'deleteGroup deletes correctly' );
|
||||
|
||||
# Clean up a bit.
|
||||
$taxer->deleteGroup( $_ ) for ( $id0, $id100 );
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getTaxRate
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = setupTestNumbers();
|
||||
my $id100 = $taxer->addGroup( 'Group100', 100 );
|
||||
my $id50_5 = $taxer->addGroup( 'Group50.5', 50.5 );
|
||||
|
||||
$taxer->update( { 'automaticViesApproval' => 1 } );
|
||||
|
||||
eval { $taxer->getTaxRate(); };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'getTaxRate: error handling for not sending a sku');
|
||||
is($e->error, 'Must pass in a WebGUI::Asset::Sku object', 'getTaxRate: error handling for not sending a sku');
|
||||
|
||||
# Set defaultTaxGroup and residential country
|
||||
$taxer->update( { defaultGroup => $id50_5, shopCountry => 'NL' } );
|
||||
|
||||
# Check default tax group
|
||||
is( $taxer->getTaxRate( $sku ), 50.5, 'getTaxRate returns default tax group when no address is given and sku has no tax group set');
|
||||
|
||||
# Check case when no address is given
|
||||
$sku->setTaxConfiguration( 'WebGUI::Shop::TaxDriver::EU', { taxGroup => $id100 } );
|
||||
is( $taxer->getTaxRate( $sku ), 100, 'getTaxRate returns tax group set by sku when no address is given');
|
||||
|
||||
# Addresses inside EU with VAT number
|
||||
is( $taxer->getTaxRate( $sku, $beAddress ), 0,
|
||||
'getTaxRate: shipping addresses inside EU but other country than merchant w/ VAT number are tax exempt.'
|
||||
);
|
||||
is( $taxer->getTaxRate( $sku, $nlAddress ), 100, 'getTaxRate: shipping addresses in country of merchant w/ VAT number pay tax' );
|
||||
|
||||
$taxer->deleteVATNumber( $testVAT_NL, $taxUser );
|
||||
$taxer->deleteVATNumber( $testVAT_BE, $taxUser );
|
||||
|
||||
# Addresses inside EU without VAT number
|
||||
foreach my $country ( @EU_COUNTRIES ) {
|
||||
next if $country eq $nlAddress->get('country'); # Residents of merchant country should be checked separately.
|
||||
|
||||
$beAddress->update( { country => $country } );
|
||||
is( $taxer->getTaxRate( $sku, $beAddress ), 100, "getTaxRate: shipping addresses in $country w/o VAT number pay tax" );
|
||||
}
|
||||
$beAddress->update( { country => 'Belgium' } );
|
||||
is( $taxer->getTaxRate( $sku, $nlAddress ), 100, 'getTaxRate: shipping addresses in country of merchant w/o VAT number pay tax' );
|
||||
|
||||
|
||||
# Address outside EU
|
||||
is( $taxer->getTaxRate( $sku, $usAddress ), 0, 'getTaxRate: shipping addresses outside EU are tax exempt' );
|
||||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# appendCartItemVars
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = setupTestNumbers();
|
||||
|
||||
eval { $taxer->appendCartItemVars };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'appendCartItemVars requires a hash ref.' );
|
||||
is( $e, 'Must supply a hash ref', 'appendCartItemVars returns correct message for missing hash ref' );
|
||||
|
||||
eval { $taxer->appendCartItemVars( {}, 'NotAUserObject' ) };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidObject', 'appendCartItemVars: Second argument must be a cart item object' );
|
||||
cmp_deeply( $e, methods(
|
||||
error => 'Must pass a cart item',
|
||||
expected => 'WebGUI::Shop::CartItem',
|
||||
got => '',
|
||||
), 'appendCartItemVars returns correct error for missing CartItem' );
|
||||
|
||||
|
||||
my $cart = WebGUI::Shop::Cart->newBySession( $session );
|
||||
WebGUI::Test->addToCleanup($cart);
|
||||
|
||||
my $item = $cart->addItem( $sku );
|
||||
$item->setQuantity( 2 );
|
||||
$item->update( { shippingAddressId => $nlAddress->getId } );
|
||||
|
||||
my $cartItemVars = { must => 'be kept' };
|
||||
$taxer->appendCartItemVars( $cartItemVars, $item );
|
||||
cmp_deeply( $cartItemVars, {
|
||||
pricePlusTax => '200.00',
|
||||
extendedPricePlusTax => '400.00',
|
||||
taxRate => '100',
|
||||
taxAmount => '100.00',
|
||||
VATNumber => $testVAT_NL,
|
||||
must => 'be kept',
|
||||
}, 'appendCartItemVars returns correct data for address in shopy country.' );
|
||||
|
||||
$item->update( { shippingAddressId => $beAddress->getId } );
|
||||
$cartItemVars = { must => 'be kept' };
|
||||
$taxer->appendCartItemVars( $cartItemVars, $item );
|
||||
cmp_deeply( $cartItemVars, {
|
||||
pricePlusTax => '100.00',
|
||||
extendedPricePlusTax => '200.00',
|
||||
taxRate => '0',
|
||||
taxAmount => '0.00',
|
||||
VATNumber => $testVAT_BE,
|
||||
must => 'be kept',
|
||||
}, 'appendCartItemVars returns correct data for address in otrher country in EU.' );
|
||||
|
||||
$item->update( { shippingAddressId => $usAddress->getId } );
|
||||
$cartItemVars = { must => 'be kept' };
|
||||
$taxer->appendCartItemVars( $cartItemVars, $item );
|
||||
cmp_deeply( $cartItemVars, {
|
||||
pricePlusTax => '100.00',
|
||||
extendedPricePlusTax => '200.00',
|
||||
taxRate => '0',
|
||||
taxAmount => '0.00',
|
||||
must => 'be kept',
|
||||
}, 'appendCartItemVars returns correct data for address outside EU.' );
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getTransactionTaxData
|
||||
#
|
||||
#######################################################################
|
||||
{
|
||||
my $taxer = setupTestNumbers();
|
||||
$taxer->update( { 'automaticViesApproval' => 1 } );
|
||||
|
||||
my $details = $taxer->getTransactionTaxData( $sku, $usAddress );
|
||||
cmp_deeply( $details, {
|
||||
className => 'WebGUI::Shop::TaxDriver::EU',
|
||||
outsideEU => 1,
|
||||
}, 'getTransactionTaxData returns correct hashref for addresses outside EU' );
|
||||
|
||||
$details = $taxer->getTransactionTaxData( $sku, $beAddress );
|
||||
cmp_deeply( $details, {
|
||||
className => 'WebGUI::Shop::TaxDriver::EU',
|
||||
useVATNumber => 1,
|
||||
VATNumber => $testVAT_BE,
|
||||
}, 'getTransactionTaxData returns correct hashref for addresses inside EU but not shop country w/ VAT number' );
|
||||
|
||||
$details = $taxer->getTransactionTaxData( $sku, $nlAddress );
|
||||
cmp_deeply( $details, {
|
||||
className => 'WebGUI::Shop::TaxDriver::EU',
|
||||
useVATNumber => 1,
|
||||
VATNumber => $testVAT_NL,
|
||||
}, 'getTransactionTaxData returns correct hashref for addresses in shop country w/ VAT number' );
|
||||
|
||||
$taxer->deleteVATNumber( $testVAT_NL );
|
||||
|
||||
$details = $taxer->getTransactionTaxData( $sku, $nlAddress );
|
||||
cmp_deeply( $details, {
|
||||
className => 'WebGUI::Shop::TaxDriver::EU',
|
||||
useVATNumber => 0,
|
||||
}, 'getTransactionTaxData returns correct hashref for addresses in EU w/o VAT number' );
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub setupTestNumbers {
|
||||
my $taxer = WebGUI::Shop::TaxDriver::EU->new($session);
|
||||
|
||||
$session->db->write('delete from taxDriver where className=?', [ 'WebGUI::Shop::TaxDriver::EU' ]);
|
||||
$session->db->write('delete from tax_eu_vatNumbers');
|
||||
|
||||
$taxer->addVATNumber( $testVAT_NL, $taxUser, 1);
|
||||
$taxer->addVATNumber( $testVAT_BE, $taxUser, 1);
|
||||
|
||||
return $taxer;
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
$session->db->write('delete from tax_eu_vatNumbers');
|
||||
$session->db->write('delete from addressBook');
|
||||
$session->db->write('delete from address');
|
||||
$session->db->write('delete from taxDriver where className=?', [ 'WebGUI::Shop::TaxDriver::EU' ]);
|
||||
|
||||
}
|
||||
723
t/Shop/TaxDriver/Generic.t
Normal file
723
t/Shop/TaxDriver/Generic.t
Normal file
|
|
@ -0,0 +1,723 @@
|
|||
# vim:syntax=perl
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#------------------------------------------------------------------
|
||||
|
||||
# Write a little about what this script tests.
|
||||
#
|
||||
#
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../lib";
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
use Exception::Class;
|
||||
use Data::Dumper;
|
||||
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Text;
|
||||
use WebGUI::Shop::Cart;
|
||||
use WebGUI::Shop::AddressBook;
|
||||
use WebGUI::Shop::TaxDriver::Generic;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
$session->user({userId => 3});
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $addExceptions = getAddExceptions($session);
|
||||
|
||||
my $tests = 80 + 2*scalar(@{$addExceptions});
|
||||
plan tests => $tests;
|
||||
|
||||
#WebGUI::Test->addToCleanup(SQL => 'delete from tax_generic_rates');
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
|
||||
my ($taxableDonation, $taxFreeDonation);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# new
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $taxer = WebGUI::Shop::TaxDriver::Generic->new($session);
|
||||
|
||||
isa_ok($taxer, 'WebGUI::Shop::TaxDriver::Generic');
|
||||
|
||||
isa_ok($taxer->session, 'WebGUI::Session', 'session method returns a session object');
|
||||
|
||||
is($session->getId, $taxer->session->getId, 'session method returns OUR session object');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getItems
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $taxIterator = $taxer->getItems;
|
||||
|
||||
isa_ok($taxIterator, 'WebGUI::SQL::ResultSet');
|
||||
|
||||
is($taxIterator->rows, 0, 'WebGUI ships with no predefined tax data');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# add
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $e;
|
||||
|
||||
eval{$taxer->add()};
|
||||
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'add: correct type of exception thrown for missing hashref');
|
||||
is($e->error, 'Must pass in a hashref of params', 'add: correct message for a missing hashref');
|
||||
|
||||
foreach my $inputSet ( @{ $addExceptions } ){
|
||||
eval{$taxer->add($inputSet->{args})};
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'add: '.$inputSet->{comment});
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => $inputSet->{error},
|
||||
param => $inputSet->{param},
|
||||
),
|
||||
'add: '.$inputSet->{comment},
|
||||
);
|
||||
}
|
||||
|
||||
my $taxData = {
|
||||
country => 'USA',
|
||||
state => 'OR',
|
||||
taxRate => '0',
|
||||
};
|
||||
|
||||
my $oregonTaxId = $taxer->add($taxData);
|
||||
|
||||
ok($session->id->valid($oregonTaxId), 'add method returns a valid GUID');
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 1, 'add added only 1 row to the tax table');
|
||||
|
||||
my $addedData = $taxIterator->hashRef;
|
||||
$taxData->{taxId} = $oregonTaxId;
|
||||
$taxData->{city} = undef;
|
||||
$taxData->{code} = undef;
|
||||
|
||||
cmp_deeply($addedData, $taxData, 'add put the right data into the database for Oregon');
|
||||
|
||||
$taxData = {
|
||||
country => 'USA',
|
||||
state => 'Wisconsin',
|
||||
city => 'Madcity',
|
||||
code => '53702',
|
||||
taxRate => '5',
|
||||
};
|
||||
|
||||
my $wisconsinTaxId = $taxer->add($taxData);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 2, 'add added another row to the tax table');
|
||||
|
||||
$taxData = {
|
||||
country => 'USA',
|
||||
state => 'Oregon',
|
||||
taxRate => '0.1',
|
||||
};
|
||||
|
||||
my $dupId = $taxer->add($taxData);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 3, 'add permits adding duplicate information.');
|
||||
|
||||
my $spaceId = $taxer->add({
|
||||
country => 'USA, United States , United States Of America ,U.S.A',
|
||||
state => 'Wisconsin, WI',
|
||||
city => 'MADCITY, madcity, Madison , WebGUIVille',
|
||||
code => '77575, 54703 , 97424',
|
||||
taxRate => '7.77',
|
||||
});
|
||||
|
||||
my $no_spaces = $taxer->getItem($spaceId);
|
||||
cmp_deeply (
|
||||
$no_spaces,
|
||||
{
|
||||
country => 'USA,United States,United States Of America,U.S.A',
|
||||
state => 'Wisconsin,WI',
|
||||
city => 'MADCITY,madcity,Madison,WebGUIVille',
|
||||
taxRate => '7.77',
|
||||
taxId => $spaceId,
|
||||
code => '77575,54703,97424',
|
||||
},
|
||||
'Spaces removed from content when adding'
|
||||
);
|
||||
|
||||
$taxer->delete({taxId => $spaceId});
|
||||
|
||||
##Madison zip codes:
|
||||
##53701-53709
|
||||
##city rate: 0.5%
|
||||
##Wisconsin rate 5.0%
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getAllItems
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $expectedTaxData = [
|
||||
{
|
||||
country => 'USA',
|
||||
state => 'OR',
|
||||
city => undef,
|
||||
code => undef,
|
||||
taxRate => 0,
|
||||
},
|
||||
{
|
||||
country => 'USA',
|
||||
state => 'Wisconsin',
|
||||
city => 'Madcity',
|
||||
code => '53702',
|
||||
taxRate => 5,
|
||||
},
|
||||
{
|
||||
country => 'USA',
|
||||
state => 'Oregon',
|
||||
city => undef,
|
||||
code => undef,
|
||||
taxRate => 0.1,
|
||||
},
|
||||
];
|
||||
|
||||
cmp_bag(
|
||||
$taxer->getAllItems,
|
||||
$expectedTaxData,
|
||||
'getAllItems returns the whole set of tax data',
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# delete
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
eval{$taxer->delete()};
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'delete: error handling for missing hashref');
|
||||
is($e->error, 'Must pass in a hashref of params', 'delete: error message for missing hashref');
|
||||
|
||||
eval{$taxer->delete({})};
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'delete: error handling for missing key in hashref');
|
||||
is($e->error, 'Hash ref must contain a taxId key with a defined value', 'delete: error message for missing key in hashref');
|
||||
|
||||
eval{$taxer->delete({ taxId => undef })};
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'delete: error handling for an undefined taxId value');
|
||||
is($e->error, 'Hash ref must contain a taxId key with a defined value', 'delete: error message for an undefined taxId value');
|
||||
|
||||
$taxer->delete({ taxId => $dupId });
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 2, 'One row was deleted from the tax table, even though another row has duplicate information');
|
||||
|
||||
$taxer->delete({ taxId => $oregonTaxId });
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 1, 'Another row was deleted from the tax table');
|
||||
|
||||
$taxer->delete({ taxId => $session->id->generate });
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 1, 'No rows were deleted from the table since the requested id does not exist');
|
||||
is($taxIterator->hashRef->{taxId}, $wisconsinTaxId, 'The correct tax information was deleted');
|
||||
|
||||
########################################################################
|
||||
##
|
||||
## exportTaxData
|
||||
##
|
||||
########################################################################
|
||||
|
||||
my $storage = $taxer->exportTaxData();
|
||||
WebGUI::Test->addToCleanup($storage);
|
||||
isa_ok($storage, 'WebGUI::Storage', 'exportTaxData returns a WebGUI::Storage object');
|
||||
is(substr($storage->getPathFrag, 0, 5), 'temp/', 'The storage object is in the temporary area');
|
||||
ok(-e $storage->getPath('siteTaxData.csv'), 'siteTaxData.csv file exists in the storage object');
|
||||
cmp_ok($storage->getFileSize('siteTaxData.csv'), '!=', 0, 'CSV file is not empty');
|
||||
my @fileLines = split /\n+/, $storage->getFileContentsAsScalar('siteTaxData.csv');
|
||||
#my @fileLines = ();
|
||||
my @header = WebGUI::Text::splitCSV($fileLines[0]);
|
||||
my @expectedHeader = qw/country state city code taxRate/;
|
||||
cmp_deeply(\@header, \@expectedHeader, 'exportTaxData: header line is correct');
|
||||
my @row1 = WebGUI::Text::splitCSV($fileLines[1]);
|
||||
my $wiData = $taxer->getItems->hashRef;
|
||||
##Need to ignore the taxId from the database
|
||||
cmp_bag([ @{ $wiData }{ @expectedHeader } ], \@row1, 'exportTaxData: first line of data is correct');
|
||||
|
||||
my $newTaxId = $taxer->add({
|
||||
country => 'USA|U.S.A.',
|
||||
state => 'washington|WA',
|
||||
taxRate => '7',
|
||||
code => '',
|
||||
city => '',
|
||||
});
|
||||
$taxer->delete({taxId => $wisconsinTaxId});
|
||||
$storage = $taxer->exportTaxData();
|
||||
@fileLines = split /\n+/, $storage->getFileContentsAsScalar('siteTaxData.csv');
|
||||
my @row1 = WebGUI::Text::splitCSV($fileLines[1]);
|
||||
my $wiData = $taxer->getItems->hashRef;
|
||||
##Need to ignore the taxId from the database
|
||||
cmp_bag([ @{ $wiData }{ @expectedHeader } ], \@row1, 'exportTaxData: first line of data is correct');
|
||||
|
||||
$taxer->delete({taxId => $newTaxId});
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# import
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
eval { $taxer->importTaxData(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'importTaxData: error handling for an undefined taxId value');
|
||||
is($e->error, 'Must provide the path to a file', 'importTaxData: error handling for an undefined taxId value');
|
||||
|
||||
eval { $taxer->importTaxData('/path/to/nowhere'); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidFile', 'importTaxData: error handling for file that does not exist in the filesystem');
|
||||
is($e->error, 'File could not be found', 'importTaxData: error handling for file that does not exist in the filesystem');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
brokenFile => '/path/to/nowhere',
|
||||
),
|
||||
'importTaxData: error handling for file that does not exist in the filesystem',
|
||||
);
|
||||
|
||||
my $taxFile = WebGUI::Test->getTestCollateralPath('taxTables/goodTaxTable.csv');
|
||||
|
||||
SKIP: {
|
||||
skip 'Root will cause this test to fail since it does not obey file permissions', 3
|
||||
if $< == 0;
|
||||
|
||||
my $originalChmod = (stat $taxFile)[2];
|
||||
chmod oct(0000), $taxFile;
|
||||
|
||||
eval { $taxer->importTaxData($taxFile); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidFile', 'importTaxData: error handling for file that cannot be read');
|
||||
is($e->error, 'File is not readable', 'importTaxData: error handling for file that that cannot be read');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
brokenFile => $taxFile,
|
||||
),
|
||||
'importTaxData: error handling for file that that cannot be read',
|
||||
);
|
||||
|
||||
chmod $originalChmod, $taxFile;
|
||||
|
||||
}
|
||||
|
||||
my $expectedTaxData = [
|
||||
{
|
||||
country => 'USA',
|
||||
state => '',
|
||||
city => '',
|
||||
code => '',
|
||||
taxRate => 0,
|
||||
},
|
||||
{
|
||||
country => 'USA',
|
||||
state => 'Wisconsin',
|
||||
city => '',
|
||||
code => '',
|
||||
taxRate => 5,
|
||||
},
|
||||
{
|
||||
country => 'USA',
|
||||
state => 'Wisconsin',
|
||||
city => 'Madison',
|
||||
code => '53701',
|
||||
taxRate => 0.5,
|
||||
},
|
||||
];
|
||||
|
||||
ok(
|
||||
$taxer->importTaxData(
|
||||
$taxFile
|
||||
),
|
||||
'Good tax data inserted',
|
||||
);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 3, 'import: Old data deleted, new data imported');
|
||||
cmp_bag(
|
||||
$taxer->getAllItems,
|
||||
$expectedTaxData,
|
||||
'Correct data inserted.',
|
||||
);
|
||||
|
||||
ok(
|
||||
$taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/orderedTaxTable.csv')
|
||||
),
|
||||
'Reordered tax data inserted',
|
||||
);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 3, 'import: Old data deleted, new data imported again');
|
||||
cmp_bag(
|
||||
$taxer->getAllItems,
|
||||
$expectedTaxData,
|
||||
'Correct data inserted, with CSV in different columnar order.',
|
||||
);
|
||||
|
||||
ok(
|
||||
$taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/commentedTaxTable.csv')
|
||||
),
|
||||
'Commented tax data inserted',
|
||||
);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 3, 'import: Old data deleted, new data imported the third time');
|
||||
cmp_bag(
|
||||
$taxer->getAllItems,
|
||||
$expectedTaxData,
|
||||
'Correct data inserted, with comments in the CSV file',
|
||||
);
|
||||
|
||||
ok(
|
||||
! $taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/emptyTaxTable.csv')
|
||||
),
|
||||
'Empty tax data not inserted',
|
||||
);
|
||||
|
||||
$taxIterator = $taxer->getItems;
|
||||
is($taxIterator->rows, 3, 'import: Old data still exists and was not deleted');
|
||||
|
||||
my $failure;
|
||||
eval {
|
||||
$failure = $taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/badTaxTable.csv')
|
||||
);
|
||||
};
|
||||
ok (!$failure, 'Tax data not imported');
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidFile', 'importTaxData: a file with an error on 1 line');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Error found in the CSV file',
|
||||
brokenFile => WebGUI::Test->getTestCollateralPath('taxTables/badTaxTable.csv'),
|
||||
brokenLine => 1,
|
||||
),
|
||||
'importTaxData: error handling for file with errors in the CSV data',
|
||||
);
|
||||
|
||||
eval {
|
||||
$failure = $taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/missingHeaders.csv')
|
||||
);
|
||||
};
|
||||
ok (!$failure, 'Tax data not imported when headers are missing');
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidFile', 'importTaxData: a file with a missing header column');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Bad header found in the CSV file',
|
||||
brokenFile => WebGUI::Test->getTestCollateralPath('taxTables/missingHeaders.csv'),
|
||||
),
|
||||
'importTaxData: error handling for a file with a missing header',
|
||||
);
|
||||
|
||||
eval {
|
||||
$failure = $taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/badHeaders.csv')
|
||||
);
|
||||
};
|
||||
ok (!$failure, 'Tax data not imported when headers are wrong');
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidFile', 'importTaxData: a file with a bad header column');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Bad header found in the CSV file',
|
||||
brokenFile => WebGUI::Test->getTestCollateralPath('taxTables/badHeaders.csv'),
|
||||
),
|
||||
'importTaxData: error handling for a file with a bad header',
|
||||
);
|
||||
|
||||
ok(
|
||||
$taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/alternations.csv')
|
||||
),
|
||||
'Tax data with alternations inserted',
|
||||
);
|
||||
|
||||
my $altData = $taxer->getItems->hashRef; ##Just 1 row
|
||||
cmp_deeply(
|
||||
$altData,
|
||||
{
|
||||
taxId => ignore,
|
||||
country => q{U.S.A.,USA},
|
||||
state => q{WI,Wisconsin},
|
||||
city => q{Madison},
|
||||
code => 53701,
|
||||
taxRate => 0.5,
|
||||
},
|
||||
'import: Data correctly loaded with alternations'
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getTaxRates
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
##Set up the tax information
|
||||
$taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/largeTaxTable.csv')
|
||||
),
|
||||
my $book = WebGUI::Shop::AddressBook->create($session);
|
||||
WebGUI::Test->addToCleanup($book);
|
||||
my $taxingAddress = $book->addAddress({
|
||||
label => 'taxing',
|
||||
city => 'Madison',
|
||||
state => 'WI',
|
||||
code => '53701',
|
||||
country => 'USA',
|
||||
});
|
||||
my $taxFreeAddress = $book->addAddress({
|
||||
label => 'no tax',
|
||||
city => 'Portland',
|
||||
state => 'OR',
|
||||
code => '97123',
|
||||
country => 'USA',
|
||||
});
|
||||
my $alternateAddress = $book->addAddress({
|
||||
label => 'using alternations',
|
||||
city => 'Los Angeles',
|
||||
state => 'CalifornIA',
|
||||
code => '92801',
|
||||
country => 'USA',
|
||||
});
|
||||
|
||||
eval { $taxer->getTaxRates(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidObject', 'calculate: error handling for not sending a cart');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Need an address.',
|
||||
got => '',
|
||||
expected => 'WebGUI::Shop::Address',
|
||||
),
|
||||
'importTaxData: error handling for file that does not exist in the filesystem',
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$taxer->getTaxRates($taxingAddress),
|
||||
[0, 5, 0.5],
|
||||
'getTaxRates: return correct data for a state with tax data'
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$taxer->getTaxRates($taxFreeAddress),
|
||||
[0,0],
|
||||
'getTaxRates: return correct data for a state with no tax data'
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$taxer->getTaxRates($alternateAddress),
|
||||
[0.0, 8.25], #Hits USA and Los Angeles, California using the alternate spelling of the state
|
||||
'getTaxRates: return correct data for a state when the address has alternations'
|
||||
);
|
||||
|
||||
my $capitalized = $taxer->add({
|
||||
country => 'USA',
|
||||
state => 'wi',
|
||||
taxRate => '50',
|
||||
});
|
||||
|
||||
cmp_deeply(
|
||||
$taxer->getTaxRates($taxingAddress),
|
||||
[0, 5, 0.5],
|
||||
'... multiple entries with different capitalization, first matches'
|
||||
);
|
||||
|
||||
$taxer->delete({ taxId => $capitalized });
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# calculate
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
eval { $taxer->getTaxRate(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'getTaxRate: error handling for not sending a sku');
|
||||
is($e->error, 'Must pass in a WebGUI::Asset::Sku object', 'getTaxRate: error handling for not sending a sku');
|
||||
|
||||
##Build a cart, add some Donation SKUs to it. Set one to be taxable.
|
||||
|
||||
my $cart = WebGUI::Shop::Cart->newBySession($session);
|
||||
WebGUI::Test->addToCleanup($cart);
|
||||
|
||||
# is($taxer->calculate($cart), 0, 'calculate returns 0 if there is no shippingAddressId in the cart');
|
||||
|
||||
# $cart->update({ shippingAddressId => $taxingAddress->getId});
|
||||
|
||||
##Set up the tax information
|
||||
$taxer->importTaxData(
|
||||
WebGUI::Test->getTestCollateralPath('taxTables/largeTaxTable.csv')
|
||||
),
|
||||
|
||||
$taxableDonation = WebGUI::Asset->getRoot($session)->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Donation',
|
||||
title => 'Taxable donation',
|
||||
defaultPrice => 100.00,
|
||||
});
|
||||
WebGUI::Test->addToCleanup($taxableDonation);
|
||||
|
||||
is($taxer->getTaxRate($taxableDonation), 0, 'calculate returns 0 if there is no shippingAddressId in the cart');
|
||||
|
||||
|
||||
# $cart->addItem($taxableDonation);
|
||||
|
||||
# foreach my $item (@{ $cart->getItems }) {
|
||||
# $item->setQuantity(1);
|
||||
# }
|
||||
|
||||
my $tax = $taxer->getTaxRate( $taxableDonation, $taxingAddress );
|
||||
is($tax, 5.5, 'calculate: simple tax calculation on 1 item in the cart');
|
||||
|
||||
$cart->update({ shippingAddressId => $taxFreeAddress->getId});
|
||||
is($taxer->getTaxRate( $taxableDonation, $taxFreeAddress ), 0, 'calculate: simple tax calculation on 1 item in the cart, tax free location');
|
||||
|
||||
# foreach my $item (@{ $cart->getItems }) {
|
||||
# $item->setQuantity(2);
|
||||
# }
|
||||
#
|
||||
# $cart->update({ shippingAddressId => $taxingAddress->getId});
|
||||
# is($taxer->calculate($cart), 11, 'calculate: simple tax calculation on 1 item in the cart, qty 2');
|
||||
|
||||
$taxFreeDonation = WebGUI::Asset->getRoot($session)->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Donation',
|
||||
title => 'Tax Free Donation',
|
||||
defaultPrice => 100.00,
|
||||
});
|
||||
WebGUI::Test->addToCleanup($taxFreeDonation);
|
||||
$taxFreeDonation->setTaxConfiguration( 'WebGUI::Shop::TaxDriver::Generic', {
|
||||
overrideTaxRate => 1,
|
||||
taxRateOverride => 0,
|
||||
});
|
||||
|
||||
# $cart->addItem($taxFreeDonation);
|
||||
|
||||
# foreach my $item (@{ $cart->getItems }) {
|
||||
# $item->setQuantity(1);
|
||||
# }
|
||||
is($taxer->getTaxRate( $taxFreeDonation, $taxingAddress), 0, 'getTaxRate: tax rate override should override tax derived from address');
|
||||
|
||||
# my $remoteItem = $cart->addItem($taxableDonation);
|
||||
# $remoteItem->update({shippingAddressId => $taxFreeAddress->getId});
|
||||
#
|
||||
# foreach my $item (@{ $cart->getItems }) {
|
||||
# $item->setQuantity(1);
|
||||
# }
|
||||
# is($taxer->calculate($cart), 5.5, 'calculate: simple tax calculation on 2 items in the cart, 1 without taxes, 1 shipped to a location with no taxes');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# www_getTaxesAsJson
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$session->user({userId=>3});
|
||||
my $json = $taxer->www_getTaxesAsJson();
|
||||
ok($json, 'www_getTaxesAsJson returned something');
|
||||
is($session->http->getMimeType, 'application/json', 'MIME type set to application/json');
|
||||
my $jsonTax = JSON::from_json($json);
|
||||
cmp_deeply(
|
||||
$jsonTax,
|
||||
{
|
||||
sort => undef,
|
||||
startIndex => 0,
|
||||
totalRecords => 1778,
|
||||
recordsReturned => 25,
|
||||
dir => 'asc',
|
||||
records => array_each({
|
||||
taxId=>ignore,
|
||||
country => 'USA',
|
||||
state=>ignore,
|
||||
city=>ignore,
|
||||
code=>ignore,
|
||||
taxRate=>re('^\d+(\.\d+)?$')
|
||||
}),
|
||||
},
|
||||
'Check major elements of tax JSON',
|
||||
);
|
||||
|
||||
TODO: {
|
||||
local $TODO = 'More getTaxesAsJson tests';
|
||||
ok(0, 'test group privileges to this method');
|
||||
ok(0, 'test startIndex variable');
|
||||
ok(0, 'test results form variable');
|
||||
ok(0, 'test keywords');
|
||||
}
|
||||
|
||||
sub getAddExceptions {
|
||||
my $session = shift;
|
||||
my $inputValidion = [
|
||||
{
|
||||
args => {},
|
||||
error => q{Missing required information.},
|
||||
param => q{country},
|
||||
comment => q{missing country},
|
||||
},
|
||||
{
|
||||
args => {country => undef},
|
||||
error => q{Missing required information.},
|
||||
param => q{country},
|
||||
comment => q{undef country},
|
||||
},
|
||||
{
|
||||
args => {country => ''},
|
||||
error => q{Missing required information.},
|
||||
param => q{country},
|
||||
comment => q{empty country},
|
||||
},
|
||||
{
|
||||
args => {country => 'USA'},
|
||||
error => q{Missing required information.},
|
||||
param => q{taxRate},
|
||||
comment => q{missing taxRate},
|
||||
},
|
||||
{
|
||||
args => {country => 'USA', taxRate => undef},
|
||||
error => q{Missing required information.},
|
||||
param => q{taxRate},
|
||||
comment => q{empty taxRate},
|
||||
},
|
||||
];
|
||||
}
|
||||
#vim:ft=perl
|
||||
Loading…
Add table
Add a link
Reference in a new issue