Merge with HEAD, 10472
This commit is contained in:
commit
19f703dc9b
102 changed files with 5700 additions and 2269 deletions
|
|
@ -49,6 +49,7 @@ my $ad;
|
|||
my ($richAd, $textAd, $imageAd, $nonAd, $setAd);
|
||||
my $adSpace;
|
||||
my $imageStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($imageStorage);
|
||||
$imageStorage->addFileFromScalar('foo.bmp', 'This is not really an image');
|
||||
|
||||
SKIP: {
|
||||
|
|
@ -219,7 +220,4 @@ END {
|
|||
if (defined $adSpace and ref $adSpace eq 'WebGUI::AdSpace') {
|
||||
$adSpace->delete;
|
||||
}
|
||||
if (defined $imageStorage and ref $imageStorage eq 'WebGUI::Storage') {
|
||||
$imageStorage->delete;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ is($gcAsPath->absolute($exportPath)->stringify, $litmus->absolute($exportPath)->
|
|||
|
||||
# now let's get tricky and test different file extensions
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage->getId);
|
||||
my $filename = 'somePerlFile_pl.txt';
|
||||
$storage->addFileFromScalar($filename, $filename);
|
||||
$session->user({userId=>3});
|
||||
|
|
@ -299,6 +300,7 @@ is($fileAsPath->absolute($exportPath)->stringify, $litmus->absolute($exportPath)
|
|||
|
||||
# test a different extension, the .foobar extension
|
||||
$storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage->getId);
|
||||
$filename = 'someFoobarFile.foobar';
|
||||
$storage->addFileFromScalar($filename, $filename);
|
||||
$properties = {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
##Create a storage location
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
|
||||
##Save the image to the location
|
||||
my $filename = "someScalarFile.txt";
|
||||
|
|
@ -84,6 +85,7 @@ $versionTag->commit;
|
|||
############################################
|
||||
|
||||
my $fileStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($fileStorage);
|
||||
$mocker->set_always('getValue', $fileStorage->getId);
|
||||
my $fileFormStorage = $asset->getStorageFromPost();
|
||||
isa_ok($fileFormStorage, 'WebGUI::Storage', 'Asset::File::getStorageFromPost');
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ $rectangle->setBackgroundColor('#0000FF');
|
|||
|
||||
##Create a storage location
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
|
||||
##Save the image to the location
|
||||
$rectangle->saveToStorageLocation($storage, 'blue.png');
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ my $otherUser = WebGUI::User->new($session, 'new');
|
|||
my $groupIdEditUser = WebGUI::User->new($session, 'new');
|
||||
my $groupToEditPost = WebGUI::Group->new($session, $collab->get('groupToEditPost'));
|
||||
my $groupIdEditGroup = WebGUI::Group->new($session, $collab->get('groupIdEdit'));
|
||||
WebGUI::Test->groupsToDelete($groupToEditPost, $groupIdEditGroup);
|
||||
$postingUser->username('userForPosting');
|
||||
$otherUser->username('otherUser');
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ my $session = WebGUI::Test->session;
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 19; # Increment this number for each test you create
|
||||
plan tests => 17; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
|
@ -56,9 +56,6 @@ is($sku->getQuantityAvailable, 99999999, "skus should have an unlimited quantity
|
|||
is($sku->getQuantityAvailable, $sku->getMaxAllowedInCart, "quantity available and max allowed in cart should be the same");
|
||||
is($sku->getPrice, 0.00, "Got a valid default price.");
|
||||
is($sku->getWeight, 0, "Got a valid default weight.");
|
||||
is($sku->getTaxRate, undef, "Tax rate is not overridden.");
|
||||
$sku->update({overrideTaxRate=>1, taxRateOverride=>5});
|
||||
is($sku->getTaxRate, 5, "Tax rate is overridden.");
|
||||
isnt($sku->processStyle, "", "Got some style information.");
|
||||
is($sku->onAdjustQuantityInCart, undef, "onAdjustQuantityInCart should exist and return undef");
|
||||
is($sku->onCompletePurchase, undef, "onCompletePurchase should exist and return undef");
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ my $product = $node->addChild({
|
|||
is($product->getThumbnailUrl(), '', 'Product with no image1 property returns the empty string');
|
||||
|
||||
my $image = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($image);
|
||||
$image->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('lamp.jpg'));
|
||||
|
||||
my $imagedProduct = $node->addChild({
|
||||
|
|
@ -61,6 +62,7 @@ ok($imagedProduct->getThumbnailUrl(), 'getThumbnailUrl is not empty');
|
|||
is($imagedProduct->getThumbnailUrl(), $image->getThumbnailUrl('lamp.jpg'), 'getThumbnailUrl returns the right path to the URL');
|
||||
|
||||
my $otherImage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($otherImage);
|
||||
$otherImage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('gooey.jpg'));
|
||||
|
||||
ok($imagedProduct->getThumbnailUrl($otherImage), 'getThumbnailUrl with an explicit storageId returns something');
|
||||
|
|
@ -89,8 +91,6 @@ is($imagedProduct->getConfiguredTitle, 'Bible - English', 'getConfiguredTitle is
|
|||
END {
|
||||
$product->purge;
|
||||
$imagedProduct->purge;
|
||||
$image->delete;
|
||||
$otherImage->delete;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ my $pathedFile = WebGUI::Test->getTestCollateralPath($filename);
|
|||
|
||||
# Use some test collateral to create a storage location and assign it to our article
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
my $storedFilename = $storage->addFileFromFilesystem($pathedFile);
|
||||
my $filenameOK = is ($storedFilename, $filename, 'storage created correctly');
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ my $pathedFile = WebGUI::Test->getTestCollateralPath($filename);
|
|||
|
||||
# Use some test collateral to create a storage location and assign it to our article
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
my $storedFilename = $storage->addFileFromFilesystem($pathedFile);
|
||||
my $filenameOK = is ($storedFilename, $filename, 'storage created correctly');
|
||||
|
||||
|
|
@ -87,6 +88,7 @@ isa_ok($duplicateArticle, 'WebGUI::Asset::Wobject::Article');
|
|||
|
||||
my $duplicateStorageId = $duplicateArticle->get("storageId");
|
||||
my $duplicateStorage = WebGUI::Storage->get($session,$duplicateStorageId);
|
||||
WebGUI::Test->storagesToDelete($duplicateStorage);
|
||||
my $duplicateFilename = $duplicateStorage->getFiles->[0];
|
||||
|
||||
is ($duplicateFilename, $filename, "duplicate method copies collateral");
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
my $tests = 64;
|
||||
my $tests = 82;
|
||||
plan tests => $tests + 1;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -352,42 +352,85 @@ cmp_deeply($rJSON->responseScoresByVariableName, { s1q0 => 100, s1q1 => 200, s1
|
|||
# Turn on the survey Expression Engine
|
||||
WebGUI::Test->originalConfig('enableSurveyExpressionEngine');
|
||||
$session->config->set('enableSurveyExpressionEngine', 1);
|
||||
$rJSON->survey->section([0])->{variable} = 's0'; # our first test jump target
|
||||
$rJSON->survey->section([2])->{variable} = 's2'; # our second test jump target
|
||||
$rJSON->survey->question([1,0])->{variable} = 's1q0'; # a question variable to use in our expressions
|
||||
$rJSON->survey->answer([1,0,0])->{recordedAnswer} = 3; # value recorded in responses hash for multi-choice answer
|
||||
$rJSON->survey->section([0])->{variable} = 's0';
|
||||
$rJSON->survey->question([0,0])->{variable} = 's0q0'; # surveyOrder index = 0
|
||||
$rJSON->survey->question([0,1])->{variable} = 's0q1'; # surveyOrder index = 1
|
||||
$rJSON->survey->question([0,2])->{variable} = 's0q2'; # surveyOrder index = 2
|
||||
$rJSON->survey->section([1])->{variable} = 's1';
|
||||
$rJSON->survey->question([1,0])->{variable} = 's1q0'; # surveyOrder index = 3
|
||||
$rJSON->survey->question([1,1])->{variable} = 's1q1'; # surveyOrder index = 4
|
||||
$rJSON->survey->section([2])->{variable} = 's2'; # empty section appears as surveyOrder index = 5
|
||||
$rJSON->survey->section([3])->{variable} = 's3';
|
||||
$rJSON->survey->question([3,0])->{variable} = 's3q0'; # surveyOrder index = 6
|
||||
$rJSON->survey->question([3,1])->{variable} = 's3q1'; # surveyOrder index = 7
|
||||
$rJSON->survey->question([3,2])->{variable} = 's3q2'; # surveyOrder index = 8
|
||||
|
||||
$rJSON->lastResponse(2);
|
||||
$rJSON->survey->answer([0,0,0])->{recordedAnswer} = 3; # value recorded in responses hash for multi-choice answer
|
||||
$rJSON->survey->answer([0,0,0])->{value} = 100; # set answer score
|
||||
$rJSON->survey->answer([0,1,0])->{value} = 200; # set answer score
|
||||
|
||||
# Reset responses and record first answer
|
||||
$rJSON->lastResponse(-1);
|
||||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'My chosen answer',
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
'0-0-0' => 'I chose the first answer to s0q0',
|
||||
'0-1-0' => 'I chose the first answer to s0q1',
|
||||
});
|
||||
is($rJSON->lastResponse, 4, 'lastResponse at 4 before any gotoExpressions processed');
|
||||
|
||||
is($rJSON->nextResponse, 2, 'nextResponse at 2 (s0q1) after first response');
|
||||
|
||||
$rJSON->processGotoExpression('blah-dee-blah-blah {');
|
||||
is($rJSON->lastResponse, 4, '..unchanged after duff expression');
|
||||
is($rJSON->nextResponse, 2, '..unchanged after duff expression');
|
||||
|
||||
$rJSON->processGotoExpression('jump { value(s1q0) == 4} s0');
|
||||
is($rJSON->lastResponse, 4, '..unchanged after false expression');
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 4} s1');
|
||||
is($rJSON->nextResponse, 2, '..unchanged after false expression');
|
||||
|
||||
$rJSON->processGotoExpression('jump { value(s1q0) == 4} s0; jump { value(s1q0) == 5} s0;');
|
||||
is($rJSON->lastResponse, 4, '..similarly for multi-statement false expression');
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 4} s0; jump { value(s1q0) == 5} s1;');
|
||||
is($rJSON->nextResponse, 2, '..similarly for multi-statement false expression');
|
||||
|
||||
$rJSON->processGotoExpression('jump { value(s1q0) == 3} DUFF_TARGET');
|
||||
is($rJSON->lastResponse, 4, '..similarly for expression with invalid target');
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} DUFF_TARGET');
|
||||
is($rJSON->nextResponse, 2, '..similarly for expression with invalid target');
|
||||
|
||||
$rJSON->processGotoExpression('jump { value(s1q0) == 3} s0');
|
||||
is($rJSON->lastResponse, -1, '..but updated to s0 after true expression');
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} s1');
|
||||
is($rJSON->nextResponse, 3, 'jumps to index of first question in section');
|
||||
|
||||
$rJSON->processGotoExpression('jump { value(s1q0) == 4} s0; jump { value(s1q0) == 3} s2');
|
||||
is($rJSON->lastResponse, 4, '..changed again for multi-statement true expression');
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} s2');
|
||||
is($rJSON->nextResponse, 5, '..and updated to s2 with different jump target');
|
||||
|
||||
$rJSON->processGotoExpression('jump { score(s1q0) == 100} s0');
|
||||
is($rJSON->lastResponse, -1, '..and again when score used');
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} s3');
|
||||
is($rJSON->nextResponse, 6, '..and updated to s3 with different jump target');
|
||||
|
||||
$rJSON->processGotoExpression('jump { score("s1") == 300} s2');
|
||||
is($rJSON->lastResponse, 4, '..and again when section score total used');
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} s3q1');
|
||||
is($rJSON->nextResponse, 7, '..we can also jump to a question rather than a section');
|
||||
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} NEXT_SECTION');
|
||||
is($rJSON->nextResponse, 3, '..we can also use the NEXT_SECTION target');
|
||||
|
||||
$rJSON->lastResponse(3); # pretend we just finished s1q0
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} NEXT_SECTION');
|
||||
is($rJSON->nextResponse, 5, '..try that again from a different starting point');
|
||||
|
||||
$rJSON->lastResponse(8); # pretend we just finished s3q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} NEXT_SECTION');
|
||||
is($rJSON->nextResponse, 9, '..NEXT_SECTION on the last section is ok, it just ends the survey');
|
||||
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 3} END_SURVEY');
|
||||
is($rJSON->nextResponse, 9, '..we can also jump to end with END_SURVEY target');
|
||||
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { value(s0q0) == 4} s0; jump { value(s0q0) == 3} s1');
|
||||
is($rJSON->nextResponse, 3, '..first true statement wins');
|
||||
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { score(s0q0) == 100} s1');
|
||||
is($rJSON->nextResponse, 3, '..and again when score used');
|
||||
|
||||
$rJSON->nextResponse(2); # pretend we just finished s0q2
|
||||
$rJSON->processGotoExpression('jump { score("s0") == 300} s1');
|
||||
is($rJSON->nextResponse, 3, '..and again when section score total used');
|
||||
|
||||
$rJSON->responses({});
|
||||
$rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered);
|
||||
|
|
@ -475,6 +518,7 @@ cmp_deeply(
|
|||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'First answer',
|
||||
'1-0-0verbatim' => 'First answer verbatim', # ignored
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
}),
|
||||
[ 1, 'question 1-0 terminal' ],
|
||||
|
|
@ -494,6 +538,7 @@ cmp_deeply(
|
|||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
'time' => num(time(), 3),
|
||||
value => 1, # 'recordedAnswer' value used because question is multi-choice
|
||||
verbatim => undef,
|
||||
},
|
||||
'1-1' => {
|
||||
comment => undef,
|
||||
|
|
@ -502,11 +547,42 @@ cmp_deeply(
|
|||
'recordResponses: recorded responses correctly, two questions, one answer, comments, values and time'
|
||||
);
|
||||
|
||||
# Check that raw input is recorded for verbatim mc answers
|
||||
$rJSON->survey->answer([1,0,0])->{verbatim} = 1;
|
||||
$rJSON->lastResponse(2);
|
||||
$rJSON->responses({});
|
||||
$rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered);
|
||||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'First answer',
|
||||
'1-0-0verbatim' => 'First answer verbatim',
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
});
|
||||
cmp_deeply(
|
||||
$rJSON->responses,
|
||||
{
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
'1-0-0' => {
|
||||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
'time' => num(time(), 3),
|
||||
value => 1, # 'recordedAnswer' value used because question is multi-choice
|
||||
verbatim => 'First answer verbatim',
|
||||
},
|
||||
'1-1' => {
|
||||
comment => undef,
|
||||
}
|
||||
},
|
||||
'recordResponses: verbatim answer recorded responses correctly'
|
||||
);
|
||||
$rJSON->survey->answer([1,0,0])->{verbatim} = 0; # revert change
|
||||
|
||||
# Repeat with non multi-choice question, to check that submitted answer value is used
|
||||
# instead of recordedValue
|
||||
$rJSON->survey->question([1,0])->{questionType} = 'Text';
|
||||
$rJSON->lastResponse(2);
|
||||
$rJSON->responses({});
|
||||
$rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered);
|
||||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
|
|
@ -523,6 +599,7 @@ cmp_deeply(
|
|||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
'time' => num(time(), 3),
|
||||
value => 'First answer', # submitted answer value used this time because non-mc
|
||||
verbatim => undef,
|
||||
},
|
||||
'1-1' => {
|
||||
comment => undef,
|
||||
|
|
@ -561,9 +638,108 @@ cmp_deeply(
|
|||
'recordResponses: if the answer is all whitespace, it is skipped over'
|
||||
);
|
||||
is($rJSON->questionsAnswered, 0, 'question was all whitespace, not answered');
|
||||
#delete $rJSON->{_session};
|
||||
#delete $rJSON->survey->{_session};
|
||||
#diag(Dumper($rJSON));
|
||||
|
||||
####################################################
|
||||
#
|
||||
# pop
|
||||
#
|
||||
####################################################
|
||||
$rJSON->responses({});
|
||||
$rJSON->lastResponse(2);
|
||||
is($rJSON->pop, undef, 'pop with no responses returns undef');
|
||||
cmp_deeply($rJSON->responses, {}, 'initially no responses');
|
||||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'First answer',
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
'1-1comment' => 'Section 1, question 1 comment',
|
||||
'1-1-0' => 'Second answer',
|
||||
'1-1-0comment' => 'Section 1, question 1, answer 0 comment',
|
||||
|
||||
});
|
||||
my $popped = $rJSON->pop;
|
||||
cmp_deeply($popped, {
|
||||
# the first q answer
|
||||
'1-0-0' => {
|
||||
value => 1,
|
||||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
time => num(time(), 3),
|
||||
verbatim => undef,
|
||||
},
|
||||
# the second q answer
|
||||
'1-1-0' => {
|
||||
value => 0,
|
||||
comment => 'Section 1, question 1, answer 0 comment',
|
||||
time => num(time(), 3),
|
||||
verbatim => undef,
|
||||
},
|
||||
# the first question comment
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
# the second question comment
|
||||
'1-1' => {
|
||||
comment => 'Section 1, question 1 comment',
|
||||
}
|
||||
}, 'pop removes only existing response');
|
||||
cmp_deeply($rJSON->responses, {}, 'and now back to no responses');
|
||||
is($rJSON->pop, undef, 'additional pop has no effect');
|
||||
|
||||
$rJSON->responses({});
|
||||
$rJSON->lastResponse(2);
|
||||
$rJSON->recordResponses({
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'First answer',
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
'1-1comment' => 'Section 1, question 1 comment',
|
||||
'1-1-0' => 'Second answer',
|
||||
'1-1-0comment' => 'Section 1, question 1, answer 0 comment',
|
||||
});
|
||||
|
||||
# fake time so that pop thinks first response happened earlier
|
||||
$rJSON->responses->{'1-0-0'}->{time} -= 1;
|
||||
cmp_deeply($rJSON->pop, {
|
||||
# the second q answer
|
||||
'1-1-0' => {
|
||||
value => 0,
|
||||
comment => 'Section 1, question 1, answer 0 comment',
|
||||
time => num(time(), 3),
|
||||
verbatim => undef,
|
||||
},
|
||||
# the second question comment
|
||||
'1-1' => {
|
||||
comment => 'Section 1, question 1 comment',
|
||||
}
|
||||
}, 'pop now only removes the most recent response');
|
||||
cmp_deeply($rJSON->responses, {
|
||||
# the first q answer
|
||||
'1-0-0' => {
|
||||
value => 1,
|
||||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
time => num(time(), 3),
|
||||
verbatim => undef,
|
||||
},
|
||||
# the first question comment
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
}, 'and first response left in tact');
|
||||
cmp_deeply($rJSON->pop, {
|
||||
# the first q answer
|
||||
'1-0-0' => {
|
||||
value => 1,
|
||||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
time => num(time(), 3),
|
||||
verbatim => undef,
|
||||
},
|
||||
# the first question comment
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
}, 'second pop removes first response');
|
||||
cmp_deeply($rJSON->responses, {}, '..and now responses hash empty again');
|
||||
|
||||
is($rJSON->pop, undef, 'additional pop has no effect');
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
my $tests = 139;
|
||||
my $tests = 137;
|
||||
plan tests => $tests + 1 + 3;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -1384,15 +1384,15 @@ cmp_deeply(
|
|||
|
||||
####################################################
|
||||
#
|
||||
# addAnswersToQuestion
|
||||
# addAnswersToQuestion, getMultiChoiceBundle
|
||||
#
|
||||
####################################################
|
||||
|
||||
#We'll work exclusively with Question 3-0
|
||||
|
||||
my $answerBundle = $surveyJSON->getMultiChoiceBundle('Yes/No');
|
||||
$surveyJSON->addAnswersToQuestion( [3,0],
|
||||
[ qw[ one two three ] ],
|
||||
{}
|
||||
$answerBundle,
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
|
|
@ -1400,85 +1400,20 @@ cmp_deeply(
|
|||
superhashof({
|
||||
answers => [
|
||||
superhashof({
|
||||
text => 'one',
|
||||
text => 'Yes',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
value => 1,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'two',
|
||||
text => 'No',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 2,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'three',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 3,
|
||||
recordedAnswer => 0,
|
||||
value => 1,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
'addAnswersToQuestion: setup three answers, no verbatims'
|
||||
);
|
||||
|
||||
$surveyJSON->question([3,0])->{answers} = [];
|
||||
|
||||
$surveyJSON->addAnswersToQuestion( [3,0],
|
||||
[ qw[ one two three ] ],
|
||||
{ 1 => 1, 2 => 1 }
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0]),
|
||||
superhashof({
|
||||
answers => [
|
||||
superhashof({
|
||||
text => 'one',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'two',
|
||||
verbatim => 1,
|
||||
recordedAnswer => 2,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'three',
|
||||
verbatim => 1,
|
||||
recordedAnswer => 3,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
'addAnswersToQuestion: setup verbatims on two answers'
|
||||
);
|
||||
|
||||
$surveyJSON->question([3,0])->{answers} = [];
|
||||
|
||||
$surveyJSON->addAnswersToQuestion( [3,0],
|
||||
[ qw[ one two three ] ],
|
||||
{ 1 => 0 }
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0]),
|
||||
superhashof({
|
||||
answers => [
|
||||
superhashof({
|
||||
text => 'one',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'two',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 2,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'three',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 3,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
'addAnswersToQuestion: verbatims have to exist, and be true'
|
||||
'addAnswersToQuestion: Yes/No bundle created'
|
||||
);
|
||||
|
||||
####################################################
|
||||
|
|
@ -1507,12 +1442,12 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Male',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
superhashof({
|
||||
text => 'Female',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 2,
|
||||
recordedAnswer => 1,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Gender type'
|
||||
|
|
@ -1530,7 +1465,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'No',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 2,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Yes/No type'
|
||||
|
|
@ -1548,10 +1483,10 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'False',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 2,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Yes/No type'
|
||||
'updateQuestionAnswers: True/False type'
|
||||
);
|
||||
|
||||
$surveyJSON->updateQuestionAnswers([3,0], 'Agree/Disagree');
|
||||
|
|
@ -1561,7 +1496,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Strongly disagree',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1571,7 +1506,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Strongly agree',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 7,
|
||||
recordedAnswer => 6,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Agree/Disagree type'
|
||||
|
|
@ -1584,7 +1519,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Strongly oppose',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1594,7 +1529,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Strongly support',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 7,
|
||||
recordedAnswer => 6,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Agree/Disagree type'
|
||||
|
|
@ -1607,7 +1542,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all important',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1617,7 +1552,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely important',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Importance type'
|
||||
|
|
@ -1630,7 +1565,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all likely',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1640,7 +1575,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely likely',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Likelihood type'
|
||||
|
|
@ -1653,7 +1588,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all certain',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1663,7 +1598,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely certain',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Certainty type'
|
||||
|
|
@ -1676,7 +1611,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all satisfied',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1686,7 +1621,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely satisfied',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Satisfaction type'
|
||||
|
|
@ -1699,7 +1634,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all confident',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1709,7 +1644,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely confident',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Confidence type'
|
||||
|
|
@ -1722,7 +1657,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all effective',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1732,7 +1667,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely effective',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Effectiveness type'
|
||||
|
|
@ -1745,7 +1680,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all concerned',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1755,7 +1690,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely concerned',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Concern type'
|
||||
|
|
@ -1768,7 +1703,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'No risk',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1778,7 +1713,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extreme risk',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Risk type'
|
||||
|
|
@ -1791,7 +1726,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'No threat',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1801,7 +1736,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extreme threat',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Threat type'
|
||||
|
|
@ -1814,7 +1749,7 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Not at all secure',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 1,
|
||||
recordedAnswer => 0,
|
||||
}),
|
||||
( superhashof({
|
||||
text => '',
|
||||
|
|
@ -1824,14 +1759,14 @@ cmp_deeply(
|
|||
superhashof({
|
||||
text => 'Extremely secure',
|
||||
verbatim => 0,
|
||||
recordedAnswer => 11,
|
||||
recordedAnswer => 10,
|
||||
}),
|
||||
],
|
||||
'updateQuestionAnswers: Security type'
|
||||
);
|
||||
|
||||
$surveyJSON->updateQuestionAnswers([3,0], 'Ideology');
|
||||
my $index = 1;
|
||||
my $index = 0;
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0])->{answers},
|
||||
[
|
||||
|
|
@ -1854,14 +1789,14 @@ cmp_deeply(
|
|||
);
|
||||
|
||||
$surveyJSON->updateQuestionAnswers([3,0], 'Race');
|
||||
$index = 1;
|
||||
$index = 0;
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0])->{answers},
|
||||
[
|
||||
map {
|
||||
superhashof({
|
||||
text => $_,
|
||||
verbatim => $index == 6 ? 1 : 0,
|
||||
verbatim => $index == 5 ? 1 : 0,
|
||||
recordedAnswer => $index++,
|
||||
})
|
||||
} 'American Indian', 'Asian', 'Black', 'Hispanic', 'White non-Hispanic', 'Something else (verbatim)',
|
||||
|
|
@ -1870,14 +1805,14 @@ cmp_deeply(
|
|||
);
|
||||
|
||||
$surveyJSON->updateQuestionAnswers([3,0], 'Party');
|
||||
$index = 1;
|
||||
$index = 0;
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0])->{answers},
|
||||
[
|
||||
map {
|
||||
superhashof({
|
||||
text => $_,
|
||||
verbatim => $index == 4 ? 1 : 0,
|
||||
verbatim => $index == 3 ? 1 : 0,
|
||||
recordedAnswer => $index++,
|
||||
})
|
||||
} 'Democratic party', 'Republican party (or GOP)', 'Independent party', 'Other party (verbatim)',
|
||||
|
|
@ -1886,14 +1821,14 @@ cmp_deeply(
|
|||
);
|
||||
|
||||
$surveyJSON->updateQuestionAnswers([3,0], 'Education');
|
||||
$index = 1;
|
||||
$index = 0;
|
||||
cmp_deeply(
|
||||
$surveyJSON->question([3,0])->{answers},
|
||||
[
|
||||
map {
|
||||
superhashof({
|
||||
text => $_,
|
||||
verbatim => $index == 8 ? 1 : 0,
|
||||
verbatim => $index == 7 ? 1 : 0,
|
||||
recordedAnswer => $index++,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,24 @@ my $testBlock = [
|
|||
expected => 0,
|
||||
comment => 'rejects float',
|
||||
},
|
||||
{
|
||||
key => 'Int6',
|
||||
testValue => '0',
|
||||
expected => 0,
|
||||
comment => 'zero passes',
|
||||
},
|
||||
{
|
||||
key => 'Int7',
|
||||
testValue => '',
|
||||
expected => 0,
|
||||
comment => 'empty string returns 0',
|
||||
},
|
||||
{
|
||||
key => 'Int8',
|
||||
testValue => undef,
|
||||
expected => 0,
|
||||
comment => 'undef returns 0',
|
||||
},
|
||||
];
|
||||
|
||||
my $formClass = 'WebGUI::Form::Integer';
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ sub setupTest {
|
|||
foreach my $testSet (@testSets) {
|
||||
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
my $filename = join '.', 'fileName', $testNum;
|
||||
$testSet->{filename} = $filename;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ my $spectreConf = WebGUI::Test->root . '/etc/spectre.conf';
|
|||
my $goodFile = 'The contents of this file are accessible';
|
||||
my $twoLines = "This file contains two lines of text\nThis is the second line";
|
||||
my $storage = WebGUI::Storage->createTemp($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
$storage->addFileFromScalar('goodFile', $goodFile);
|
||||
$storage->addFileFromScalar('twoLines', $twoLines);
|
||||
$storage->addFileFromScalar('unreadableFile', 'The contents of this file are not readable');
|
||||
|
|
@ -112,5 +113,4 @@ SKIP: {
|
|||
}
|
||||
|
||||
END {
|
||||
$storage->delete;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ $square->setBackgroundColor('#0000FF');
|
|||
|
||||
##Create a storage location
|
||||
my $storage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($storage);
|
||||
|
||||
##Save the image to the location
|
||||
$square->saveToStorageLocation($storage, 'square.png');
|
||||
|
|
|
|||
675
t/Shop/Tax.t
675
t/Shop/Tax.t
|
|
@ -17,684 +17,119 @@ 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;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $addExceptions = getAddExceptions($session);
|
||||
my $tests = 10;
|
||||
plan tests => $tests + 1; # Add initial use_ok test
|
||||
|
||||
my $tests = 80 + 2*scalar(@{$addExceptions});
|
||||
plan tests => 1 + $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
my $loaded = use_ok('WebGUI::Shop::Tax');
|
||||
|
||||
my $storage;
|
||||
my ($taxableDonation, $taxFreeDonation);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip 'Unable to load module WebGUI::Shop::Tax', $tests unless $loaded;
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# new
|
||||
# new
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $taxer = WebGUI::Shop::Tax->new($session);
|
||||
eval { my $tax = WebGUI::Shop::Tax->new( ) };
|
||||
|
||||
isa_ok($taxer, 'WebGUI::Shop::Tax');
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'new: throws error when no session object is passed' );
|
||||
is( $e->error, 'Need a session.', 'add: correct message for ommitted session object' );
|
||||
|
||||
isa_ok($taxer->session, 'WebGUI::Session', 'session method returns a session object');
|
||||
my $tax = WebGUI::Shop::Tax->new( $session );
|
||||
|
||||
is($session->getId, $taxer->session->getId, 'session method returns OUR session object');
|
||||
isa_ok( $tax, 'WebGUI::Shop::Tax', 'constructor returns instance of WebGUI::Shop::Tax' );
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getItems
|
||||
# session
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $taxIterator = $taxer->getItems;
|
||||
isa_ok( $tax->session, 'WebGUI::Session', 'session method returns a session object');
|
||||
|
||||
isa_ok($taxIterator, 'WebGUI::SQL::ResultSet');
|
||||
|
||||
is($taxIterator->rows, 0, 'WebGUI ships with no predefined tax data');
|
||||
is( $session->getId, $tax->session->getId, 'session method returns OUR session object');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# add
|
||||
# calculate
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
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.');
|
||||
|
||||
##Madison zip codes:
|
||||
##53701-53709
|
||||
##city rate: 0.5%
|
||||
##Wisconsin rate 5.0%
|
||||
# TODO: Figure out how to test this.
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getAllItems
|
||||
# getDriver
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
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,
|
||||
},
|
||||
];
|
||||
# Try to get a non-existing plugin
|
||||
$session->setting->set( 'activeTaxPlugin', 'WebGUI::Shop::TaxDriver::HairgreaseTaxDeduction' );
|
||||
|
||||
cmp_bag(
|
||||
$taxer->getAllItems,
|
||||
$expectedTaxData,
|
||||
'getAllItems returns the whole set of tax data',
|
||||
);
|
||||
my $driver = $tax->getDriver;
|
||||
is( $driver, undef, 'getDriver returns undef when the driver cannot be loaded' );
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# delete
|
||||
#
|
||||
#######################################################################
|
||||
# Try to get an existing plugin
|
||||
$session->setting->set( 'activeTaxPlugin', 'WebGUI::Shop::TaxDriver::Generic' );
|
||||
$driver = $tax->getDriver;
|
||||
isa_ok( $driver, 'WebGUI::Shop::TaxDriver::Generic', 'getDriver returns correct plugin' );
|
||||
|
||||
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');
|
||||
$driver = WebGUI::Shop::Tax->getDriver( $session );
|
||||
isa_ok( $driver, 'WebGUI::Shop::TaxDriver::Generic', 'getDriver returns correct plugin when called as class method' );
|
||||
|
||||
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
|
||||
##
|
||||
########################################################################
|
||||
|
||||
$storage = $taxer->exportTaxData();
|
||||
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);
|
||||
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'
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# calculate
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
eval { $taxer->calculate(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate: error handling for not sending a cart');
|
||||
is($e->error, 'Must pass in a WebGUI::Shop::Cart object', 'calculate: error handling for not sending a cart');
|
||||
|
||||
##Build a cart, add some Donation SKUs to it. Set one to be taxable.
|
||||
|
||||
my $cart = WebGUI::Shop::Cart->newBySession($session);
|
||||
|
||||
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,
|
||||
});
|
||||
|
||||
$cart->addItem($taxableDonation);
|
||||
|
||||
foreach my $item (@{ $cart->getItems }) {
|
||||
$item->setQuantity(1);
|
||||
}
|
||||
|
||||
my $tax = $taxer->calculate($cart);
|
||||
is($tax, 5.5, 'calculate: simple tax calculation on 1 item in the cart');
|
||||
|
||||
$cart->update({ shippingAddressId => $taxFreeAddress->getId});
|
||||
is($taxer->calculate($cart), 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,
|
||||
overrideTaxRate => 1,
|
||||
taxRateOverride => 0,
|
||||
});
|
||||
|
||||
$cart->addItem($taxFreeDonation);
|
||||
|
||||
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');
|
||||
|
||||
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',
|
||||
);
|
||||
eval { my $tax = WebGUI::Shop::Tax->getDriver() };
|
||||
my $e = Exception::Class->caught();
|
||||
isa_ok( $e, 'WebGUI::Error::InvalidParam', 'getDriver throws error when no session object is passed in class context' );
|
||||
is( $e->error, 'Need a session.', 'getDriver passes correct message for ommitted session object' );
|
||||
|
||||
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');
|
||||
local $TODO = 'test www_ methods';
|
||||
#######################################################################
|
||||
#
|
||||
# www_do
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# www_manage
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# www_setActivePlugin
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# www_setActivePluginConfirm
|
||||
#
|
||||
#######################################################################
|
||||
}
|
||||
|
||||
$cart->delete;
|
||||
$book->delete;
|
||||
$taxableDonation->purge;
|
||||
$taxFreeDonation->purge;
|
||||
}
|
||||
|
||||
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},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
$session->db->write('delete from tax');
|
||||
$session->db->write('delete from cart');
|
||||
$session->db->write('delete from addressBook');
|
||||
$session->db->write('delete from address');
|
||||
$storage->delete;
|
||||
|
||||
if (defined $taxableDonation and ref $taxableDonation eq 'WebGUI::Sku::Donation') {
|
||||
$taxableDonation->purge;
|
||||
}
|
||||
|
||||
if (defined $taxFreeDonation and ref $taxFreeDonation eq 'WebGUI::Sku::Donation') {
|
||||
$taxFreeDonation->purge;
|
||||
}
|
||||
}
|
||||
#vim:ft=perl
|
||||
|
|
|
|||
705
t/Shop/TaxDriver/Generic.t
Normal file
705
t/Shop/TaxDriver/Generic.t
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
# 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;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $addExceptions = getAddExceptions($session);
|
||||
|
||||
my $tests = 78 + 2*scalar(@{$addExceptions});
|
||||
plan tests => 1 + $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
my $loaded = use_ok('WebGUI::Shop::TaxDriver::Generic');
|
||||
|
||||
my $storage;
|
||||
my ($taxableDonation, $taxFreeDonation);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip 'Unable to load module WebGUI::Shop::TaxDriver::Generic', $tests unless $loaded;
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# 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.');
|
||||
|
||||
##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
|
||||
##
|
||||
########################################################################
|
||||
|
||||
$storage = $taxer->exportTaxData();
|
||||
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);
|
||||
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'
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# 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);
|
||||
|
||||
# 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,
|
||||
});
|
||||
|
||||
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,
|
||||
});
|
||||
$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');
|
||||
}
|
||||
|
||||
$cart->delete;
|
||||
$book->delete;
|
||||
$taxableDonation->purge;
|
||||
$taxFreeDonation->purge;
|
||||
}
|
||||
|
||||
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},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
$session->db->write('delete from tax_generic_rates');
|
||||
$session->db->write('delete from cart');
|
||||
$session->db->write('delete from addressBook');
|
||||
$session->db->write('delete from address');
|
||||
$storage->delete;
|
||||
|
||||
if (defined $taxableDonation and ref $taxableDonation eq 'WebGUI::Sku::Donation') {
|
||||
$taxableDonation->purge;
|
||||
}
|
||||
|
||||
if (defined $taxFreeDonation and ref $taxFreeDonation eq 'WebGUI::Sku::Donation') {
|
||||
$taxFreeDonation->purge;
|
||||
}
|
||||
}
|
||||
|
|
@ -82,6 +82,7 @@ ok ($uploadUrl, "uploadDir defined in config");
|
|||
####################################################
|
||||
|
||||
my $imageStore = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($imageStore);
|
||||
my $expectedFiles = ['.', '..'];
|
||||
cmp_bag($imageStore->getFiles(1), $expectedFiles, 'Starting with an empty storage object, no files in here except for . and ..');
|
||||
$imageStore->addFileFromScalar('.dotfile', 'dot file');
|
||||
|
|
@ -118,6 +119,7 @@ foreach my $extTest ( @{ $extensionTests } ) {
|
|||
WebGUI::Test->interceptLogging();
|
||||
|
||||
my $thumbStore = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($thumbStore);
|
||||
my $square = WebGUI::Image->new($session, 500, 500);
|
||||
$square->setBackgroundColor('#FF0000');
|
||||
$square->saveToStorageLocation($thumbStore, 'square.png');
|
||||
|
|
@ -168,6 +170,7 @@ like($WebGUI::Test::logger_error, qr/^Couldn't read image to check the size of i
|
|||
####################################################
|
||||
|
||||
my $imageCopy = $thumbStore->copy();
|
||||
WebGUI::Test->storagesToDelete($imageCopy);
|
||||
isa_ok($imageCopy, 'WebGUI::Storage', 'copy returns an object');
|
||||
cmp_bag(
|
||||
$imageCopy->getFiles(),
|
||||
|
|
@ -216,6 +219,7 @@ is($thumbStore->getThumbnailUrl('square.png'), $thumbStore->getUrl('thumb-square
|
|||
my $origMaxImageSize = $session->setting->get('maxImageSize');
|
||||
|
||||
my $sizeTest = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($sizeTest);
|
||||
|
||||
my $resizeTarget = 80;
|
||||
$session->setting->set('maxImageSize', 200 );
|
||||
|
|
@ -279,9 +283,4 @@ TODO: {
|
|||
}
|
||||
|
||||
END {
|
||||
foreach my $stor (
|
||||
$imageStore, $thumbStore, $imageCopy, $sizeTest,
|
||||
) {
|
||||
ref $stor eq "WebGUI::Storage" and $stor->delete;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ use Cwd qw[];
|
|||
use Test::MockObject::Extends;
|
||||
use WebGUI::PseudoRequest;
|
||||
use Scalar::Util qw( blessed );
|
||||
use List::MoreUtils qw/ any /;
|
||||
|
||||
##Hack to get ALL test output onto STDOUT.
|
||||
use Test::Builder;
|
||||
|
|
@ -53,6 +54,7 @@ my $originalSetting;
|
|||
|
||||
my @groupsToDelete;
|
||||
my @storagesToDelete;
|
||||
my @usersToDelete;
|
||||
|
||||
BEGIN {
|
||||
|
||||
|
|
@ -138,9 +140,14 @@ BEGIN {
|
|||
|
||||
END {
|
||||
my $Test = Test::Builder->new;
|
||||
foreach my $group (@groupsToDelete) {
|
||||
GROUP: foreach my $group (@groupsToDelete) {
|
||||
$group->delete;
|
||||
}
|
||||
USER: foreach my $user (@usersToDelete) {
|
||||
my $userId = $user->userId;
|
||||
next USER if any { $userId eq $_ } (1,3);
|
||||
$user->delete;
|
||||
}
|
||||
foreach my $stor (@storagesToDelete) {
|
||||
if ($SESSION->id->valid($stor)) {
|
||||
my $storage = WebGUI::Storage->get($SESSION, $stor);
|
||||
|
|
@ -430,6 +437,22 @@ sub storagesToDelete {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 usersToDelete ( $user, [$user, ...] )
|
||||
|
||||
Push a list of user objects onto the stack of groups to be automatically deleted
|
||||
at the end of the test. If found in the stack, the Admin and Visitor users will not be deleted.
|
||||
|
||||
This is a class method.
|
||||
|
||||
=cut
|
||||
|
||||
sub usersToDelete {
|
||||
my $class = shift;
|
||||
push @usersToDelete, @_;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
When trying to load the APR module, perl invariably throws an Out Of Memory
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue