From ec3b08e3a1f8a1f612eacd8a4b6ca658a21df4a0 Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Mon, 31 Aug 2015 11:52:42 +0300 Subject: [PATCH] Bug 13906 - TestObjectFactoreis squashables --- C4/Installer/PerlDependencies.pm | 5 + .../Acquisition/Bookseller/ContactFactory.pm | 3 + t/lib/TestObjects/Acquisition/BooksellerFactory.pm | 3 + t/lib/TestObjects/BiblioFactory.pm | 24 ++++- t/lib/TestObjects/BorrowerFactory.pm | 44 +++++--- t/lib/TestObjects/CheckoutFactory.pm | 38 ++++--- t/lib/TestObjects/FileFactory.pm | 118 +++++++++++++++++++++ t/lib/TestObjects/ItemFactory.pm | 30 +++++- t/lib/TestObjects/LetterTemplateFactory.pm | 3 + t/lib/TestObjects/ObjectFactory.pm | 96 +++++++++++++++-- t/lib/TestObjects/Serial/FrequencyFactory.pm | 3 + t/lib/TestObjects/Serial/SubscriptionFactory.pm | 23 ++-- t/lib/TestObjects/SystemPreferenceFactory.pm | 3 + t/lib/TestObjects/objectFactories.t | 95 ++++++++++++++--- 14 files changed, 429 insertions(+), 59 deletions(-) create mode 100644 t/lib/TestObjects/FileFactory.pm diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm index b2a183b..d052fde 100644 --- a/C4/Installer/PerlDependencies.pm +++ b/C4/Installer/PerlDependencies.pm @@ -652,6 +652,11 @@ our $PERL_DEPS = { 'required' => '0', 'min_ver' => '2.07', }, + 'File::Fu::File' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '0.08', + }, 'Archive::Extract' => { 'usage' => 'Plugins', 'required' => '0', diff --git a/t/lib/TestObjects/Acquisition/Bookseller/ContactFactory.pm b/t/lib/TestObjects/Acquisition/Bookseller/ContactFactory.pm index ed117ef..6385e6d 100644 --- a/t/lib/TestObjects/Acquisition/Bookseller/ContactFactory.pm +++ b/t/lib/TestObjects/Acquisition/Bookseller/ContactFactory.pm @@ -38,6 +38,9 @@ sub new { sub getDefaultHashKey { return 'name'; } +sub getObjectType { + return 'Koha::Acquisition::Bookseller::Contact'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @OVERLOADED diff --git a/t/lib/TestObjects/Acquisition/BooksellerFactory.pm b/t/lib/TestObjects/Acquisition/BooksellerFactory.pm index ecdb298..89cbb6e 100644 --- a/t/lib/TestObjects/Acquisition/BooksellerFactory.pm +++ b/t/lib/TestObjects/Acquisition/BooksellerFactory.pm @@ -38,6 +38,9 @@ sub new { sub getDefaultHashKey { return 'name'; } +sub getObjectType { + return 'Koha::Acquisition::Bookseller2'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @OVERLOADED diff --git a/t/lib/TestObjects/BiblioFactory.pm b/t/lib/TestObjects/BiblioFactory.pm index b96cf4e..11874e7 100644 --- a/t/lib/TestObjects/BiblioFactory.pm +++ b/t/lib/TestObjects/BiblioFactory.pm @@ -22,6 +22,7 @@ use Modern::Perl; use Carp; use C4::Biblio; +use Koha::Database; use Koha::Exception::BadParameter; @@ -30,6 +31,9 @@ use base qw(t::lib::TestObjects::ObjectFactory); sub getDefaultHashKey { return 'biblioitems.isbn'; } +sub getObjectType { + return 'MARC::Record'; +} =head t::lib::TestObjects::createTestGroup @@ -50,6 +54,9 @@ The biblionumber is injected to the MARC::Record-object to be easily accessable, so we can get it like this: $records->{$key}->{biblionumber}; +There is a duplication check to first look for Records with the same ISBN. +If a matching ISBN is found, then we use the existing Record instead of adding a new one. + See C4::Biblio::TransformKohaToMarc() for how the biblio- or biblioitem-tables' columns need to be given. @@ -61,14 +68,23 @@ See t::lib::TestObjects::ObjectFactory for more documentation sub handleTestObject { my ($class, $object, $stashes) = @_; - my $record = C4::Biblio::TransformKohaToMarc($object); - my ($biblionumber, $biblioitemnumber) = C4::Biblio::AddBiblio($record,''); + ##First see if the given Record already exists in the DB. For testing purposes we use the isbn as the UNIQUE identifier. + my $resultset = Koha::Database->new()->schema()->resultset('Biblioitem'); + my $existingBiblio = $resultset->search({isbn => $object->{"biblioitems.isbn"}})->next(); + my ($record, $biblionumber, $biblioitemnumber); + unless ($existingBiblio) { + $record = C4::Biblio::TransformKohaToMarc($object); + ($biblionumber, $biblioitemnumber) = C4::Biblio::AddBiblio($record,''); + } + else { + $record = C4::Biblio::GetMarcBiblio($existingBiblio->biblionumber->biblionumber); #Funny! + } #Clone all the parameters of $object to $record foreach my $key (keys(%$object)) { $record->{$key} = $object->{$key}; } - $record->{biblionumber} = $biblionumber; + $record->{biblionumber} = $biblionumber || $existingBiblio->biblionumber->biblionumber; return $record; } @@ -109,6 +125,8 @@ sub validateAndPopulateDefaultValues { unless ($object->{'biblio.title'}) { Koha::Exception::BadParameter->throw(error => __PACKAGE__."->createTestGroup():> 'biblio.title' is a mandatory parameter!"); } + $object->{'biblioitems.isbn'} = '971-972-call-me' unless $object->{'biblioitems.isbn'}; + $self->SUPER::validateAndPopulateDefaultValues($object, $hashKey); } diff --git a/t/lib/TestObjects/BorrowerFactory.pm b/t/lib/TestObjects/BorrowerFactory.pm index 1d8da41..797e1d0 100644 --- a/t/lib/TestObjects/BorrowerFactory.pm +++ b/t/lib/TestObjects/BorrowerFactory.pm @@ -21,6 +21,7 @@ package t::lib::TestObjects::BorrowerFactory; use Modern::Perl; use Carp; use Scalar::Util qw(blessed); +use Encode; use C4::Members; use Koha::Borrowers; @@ -38,6 +39,9 @@ sub new { sub getDefaultHashKey { return 'cardnumber'; } +sub getObjectType { + return 'Koha::Borrower'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @OVERLOADED @@ -79,26 +83,33 @@ See t::lib::TestObjects::ObjectFactory for more documentation sub handleTestObject { my ($class, $object, $stashes) = @_; - #Try to add the Borrower, but it might fail because of the barcode or other UNIQUE constraint. - #Catch the error and try looking for the Borrower if we suspect it is present in the DB. - my $borrowernumber; + my $borrower; eval { - $borrowernumber = C4::Members::AddMember(%$object); + $borrower = Koha::Borrowers->cast($object); #Try getting the borrower first }; - if ($@) { - if (blessed($@) && $@->isa('DBIx::Class::Exception') && - $@->{msg} =~ /Duplicate entry '.+?' for key 'cardnumber'/) { #DBIx should throw other types of exceptions instead of this general type :( - #This exception type is OK, we ignore this and try fetching the existing Object next. - warn "Recovering from duplicate exception.\n"; - } - else { - die $@; + + my $borrowernumber; + unless ($borrower) { + #Try to add the Borrower, but it might fail because of the barcode or other UNIQUE constraint. + #Catch the error and try looking for the Borrower if we suspect it is present in the DB. + eval { + $borrowernumber = C4::Members::AddMember(%$object); + }; + if ($@) { + if (blessed($@) && $@->isa('DBIx::Class::Exception') && + $@->{msg} =~ /Duplicate entry '.+?' for key 'cardnumber'/) { #DBIx should throw other types of exceptions instead of this general type :( + #This exception type is OK, we ignore this and try fetching the existing Object next. + warn "Recovering from duplicate exception.\n"; + } + else { + die $@; + } } + #If adding failed, we still get some strange borrowernumber result. + #Check for sure by finding the real borrower. + $borrower = Koha::Borrowers->cast( $borrowernumber || $object ); } - #If adding failed, we still get some strange borrowernumber result. - #Check for sure by finding the real borrower. - my $borrower = Koha::Borrowers->cast( $borrowernumber || $object ); unless ($borrower) { carp "BorrowerFactory:> No borrower for cardnumber '".$object->{cardnumber}."'"; return(); @@ -118,6 +129,9 @@ sub validateAndPopulateDefaultValues { my ($self, $borrower, $hashKey) = @_; $self->SUPER::validateAndPopulateDefaultValues($borrower, $hashKey); + $borrower->{firstname} = 'Maija' unless $borrower->{firstname}; + $borrower->{surname} = Encode::decode('UTF-8', 'Meikäläinen') unless $borrower->{surname}; + $borrower->{cardnumber} = '167A000001TEST' unless $borrower->{cardnumber}; $borrower->{categorycode} = 'PT' unless $borrower->{categorycode}; $borrower->{branchcode} = 'CPL' unless $borrower->{branchcode}; $borrower->{dateofbirth} = '1985-10-12' unless $borrower->{dateofbirth}; diff --git a/t/lib/TestObjects/CheckoutFactory.pm b/t/lib/TestObjects/CheckoutFactory.pm index bb9a2d1..542f12a 100644 --- a/t/lib/TestObjects/CheckoutFactory.pm +++ b/t/lib/TestObjects/CheckoutFactory.pm @@ -27,6 +27,10 @@ use C4::Members; use C4::Items; use Koha::Borrowers; use Koha::Items; +use Koha::Checkouts; + +use t::lib::TestObjects::BorrowerFactory; +use t::lib::TestObjects::ItemFactory; use base qw(t::lib::TestObjects::ObjectFactory); @@ -41,6 +45,9 @@ sub new { sub getDefaultHashKey { return ['cardnumber', 'barcode']; } +sub getObjectType { + return 'Koha::Checkout'; +} =head t::lib::TestObjects::CheckoutFactory::createTestGroup( $data [, $hashKey], @stashes ) @@ -75,15 +82,12 @@ sub getDefaultHashKey { @PARAM4-6 HASHRef of test contexts. You can save the given objects to multiple test contexts. Usually one is enough. These test contexts are used to help tear down DB changes. -@RETURNS HASHRef of $hashKey => $checkout-objects. +@RETURNS HASHRef of $hashKey => Koha::Checkout-objects. The HASH is keyed with -, or the given $hashKey. Example: { - '11A001-167N0212' => { - cardnumber => , - barcode => , - ...other Checkout-object columns... - }, - ... + '11A001-167N0212' => Koha::Checkout, + ... + } } =cut @@ -100,8 +104,21 @@ sub handleTestObject { } my $oldContextBranch = C4::Context->userenv()->{branch}; - my $borrower = Koha::Borrowers->cast($checkoutParams->{cardnumber}); - my $item = Koha::Items->cast($checkoutParams->{barcode}); + my $borrower = Koha::Borrowers->find({cardnumber => $checkoutParams->{cardnumber}}); + unless($borrower) { + my $borrowers = t::lib::TestObjects::BorrowerFactory->createTestGroup( + {cardnumber => $checkoutParams->{cardnumber}}, + undef, @$stashes); + $borrower = $borrowers->{ $checkoutParams->{cardnumber} }; + } + + my $item = Koha::Items->find({barcode => $checkoutParams->{barcode}}); + unless($item) { + my $items = t::lib::TestObjects::ItemFactory->createTestGroup( + {barcode => $checkoutParams->{barcode}}, + undef, @$stashes); + $item = $items->{ $checkoutParams->{barcode} }; + } my $duedate = DateTime->now(time_zone => C4::Context->tz()); if ($checkoutParams->{daysOverdue}) { @@ -155,12 +172,9 @@ sub validateAndPopulateDefaultValues { unless ($object->{cardnumber}) { croak __PACKAGE__.":> Mandatory parameter 'cardnumber' missing."; } - $object->{borrower} = Koha::Borrowers->cast($object->{cardnumber}); - unless ($object->{barcode}) { croak __PACKAGE__.":> Mandatory parameter 'barcode' missing."; } - $object->{item} = Koha::Items->cast($object->{barcode}); if ($object->{checkoutBranchRule} && not($object->{checkoutBranchRule} =~ m/(homebranch)|(holdingbranch)/)) { croak __PACKAGE__.":> Optional parameter 'checkoutBranchRule' must be one of these: homebranch, holdingbranch"; diff --git a/t/lib/TestObjects/FileFactory.pm b/t/lib/TestObjects/FileFactory.pm new file mode 100644 index 0000000..7bbd1ef --- /dev/null +++ b/t/lib/TestObjects/FileFactory.pm @@ -0,0 +1,118 @@ +package t::lib::TestObjects::FileFactory; + +# Copyright Vaara-kirjastot 2015 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +use Modern::Perl; +use Carp; +use File::Spec; +use File::Path; + +use Koha::AtomicUpdater; +use Koha::Database; +use File::Fu::File; + +use Koha::Exception::BadParameter; + +use base qw(t::lib::TestObjects::ObjectFactory); + +my $tmpdir = File::Spec->tmpdir(); + +sub getDefaultHashKey { + return 'OVERLOADED'; +} +sub getObjectType { + return 'File::Fu::File'; +} + +=head t::lib::TestObjects::createTestGroup + + my $files = t::lib::TestObjects::FileFactory->createTestGroup([ + {'filepath' => 'atomicupdate/', #this is prepended with the system's default tmp directory, usually /tmp/ + 'filename' => '#30-RabiesIsMyDog.pl', + 'content' => 'print "Mermaids are my only love\nI never let them down";', + }, + ], ['filepath', 'filename'], $testContext1, $testContext2, $testContext3); + +Calls Koha::FileFactory to add files with content to your system, and clean up automatically. + +The HASH is keyed with the 'filename', or the given $hashKeys. + +@RETURNS HASHRef of File::Fu::File-objects + +See t::lib::TestObjects::ObjectFactory for more documentation +=cut + +sub handleTestObject { + my ($class, $object, $stashes) = @_; + + my $absolutePath = $tmpdir.'/'.$object->{filepath}; + File::Path::make_path($absolutePath); + my $file = File::Fu::File->new($absolutePath.'/'.$object->{filename}); + + $file->write($object->{content}) if $object->{content}; + + return $file; +} + +=head validateAndPopulateDefaultValues +@OVERLOAD + +Validates given Object parameters and makes sure that critical fields are given +and populates defaults for missing values. +=cut + +sub validateAndPopulateDefaultValues { + my ($self, $object, $hashKey) = @_; + + foreach my $param (('filename', 'filepath')) { + unless ($object->{$param}) { + Koha::Exception::BadParameter->throw( + error => __PACKAGE__."->validateAndPopulateDefaultValues():> parameter '$param' is mandatory."); + } + if ($object->{$param} =~ m/(\$|\.\.|~|\s)/) { + Koha::Exception::BadParameter->throw( + error => __PACKAGE__."->validateAndPopulateDefaultValues():> parameter '$param' as '".$object->{$param}."'.". + 'Disallowed characters present .. ~ $ + whitespace'); + } + } +} + +sub deleteTestGroup { + my ($class, $objects) = @_; + + while( my ($key, $object) = each %$objects) { + $object->remove if $object->e; + #We could as well remove the complete subfolder but I am too afraid to automate "rm -r" here + } +} + +=head getHashKey +@OVERLOADED + +@RETURNS String, The test context/stash HASH key to differentiate this object + from all other such test objects. +=cut + +sub getHashKey { + my ($class, $fileObject, $primaryKey, $hashKeys) = @_; + + return $fileObject->get_file(); +} + +1; diff --git a/t/lib/TestObjects/ItemFactory.pm b/t/lib/TestObjects/ItemFactory.pm index ab33802..f75fb97 100644 --- a/t/lib/TestObjects/ItemFactory.pm +++ b/t/lib/TestObjects/ItemFactory.pm @@ -22,9 +22,12 @@ use Modern::Perl; use Carp; use C4::Items; +use Koha::Biblios; use Koha::Items; use Koha::Checkouts; +use t::lib::TestObjects::BiblioFactory; + use base qw(t::lib::TestObjects::ObjectFactory); sub new { @@ -38,6 +41,9 @@ sub new { sub getDefaultHashKey { return 'barcode'; } +sub getObjectType { + return 'Koha::Item'; +} =head t::lib::TestObjects::ItemFactory::createTestGroup( $data [, $hashKey] ) @OVERLOADED @@ -56,9 +62,29 @@ See t::lib::TestObjects::ObjectFactory for more documentation sub handleTestObject { my ($class, $object, $stashes) = @_; + #Look for the parent biblio, if we don't find one, create a default one. my ($biblionumber, $biblioitemnumber, $itemnumber); + my $biblio; + $biblio = Koha::Biblios->find({biblionumber => $object->{biblionumber}}) if $object->{biblionumber}; + unless ($biblio) { + my $biblios = t::lib::TestObjects::BiblioFactory->createTestGroup({"biblio.title" => "Test Items' Biblio",}, + undef, @$stashes); + $biblio = $biblios->{'971-972-call-me'}; + $object->{biblionumber} = $biblio->{biblionumber}; + } + else { + $object->{biblionumber} = $biblio->biblionumber; + } + + #Ok we got a biblio, now we can add an Item for it. First see if the Item already exists. + my $item; eval { - ($biblionumber, $biblioitemnumber, $itemnumber) = C4::Items::AddItem($object, $object->{biblionumber}); + eval { + $item = Koha::Items->cast($object); + }; + unless ($item) { + ($biblionumber, $biblioitemnumber, $itemnumber) = C4::Items::AddItem($object, $object->{biblionumber}); + } }; if ($@) { if (blessed($@) && $@->isa('DBIx::Class::Exception') && @@ -70,7 +96,7 @@ sub handleTestObject { die $@; } } - my $item = Koha::Items->cast($itemnumber || $object); + $item = Koha::Items->cast($itemnumber || $object) unless $item; unless ($item) { carp "ItemFactory:> No item for barcode '".$object->{barcode}."'"; next(); diff --git a/t/lib/TestObjects/LetterTemplateFactory.pm b/t/lib/TestObjects/LetterTemplateFactory.pm index 6a6d4fd..8214ba6 100644 --- a/t/lib/TestObjects/LetterTemplateFactory.pm +++ b/t/lib/TestObjects/LetterTemplateFactory.pm @@ -37,6 +37,9 @@ sub new { sub getDefaultHashKey { return ['module', 'code', 'branchcode', 'message_transport_type']; } +sub getObjectType { + return 'Koha::LetterTemplate'; +} =head t::lib::TestObjects::LetterTemplateFactory->createTestGroup Returns a HASH of Koha::LetterTemplate-objects diff --git a/t/lib/TestObjects/ObjectFactory.pm b/t/lib/TestObjects/ObjectFactory.pm index 34cb90d..e4f6441 100644 --- a/t/lib/TestObjects/ObjectFactory.pm +++ b/t/lib/TestObjects/ObjectFactory.pm @@ -79,7 +79,8 @@ sub createTestGroup { my $addedObject = $class->handleTestObject($o, $stashes); if (not($addedObject) || - not(ref($addedObject) eq 'HASH' || $addedObject->isa('Koha::Object') || $addedObject->isa('MARC::Record') ) + (blessed($addedObject) && not($addedObject->isa($class->getObjectType()))) || + not(ref($addedObject) eq $class->getObjectType() ) ) { Koha::Exception::UnknownObject->throw(error => __PACKAGE__."->createTestGroup():> Subroutine '$class->handleTestObject()' must return a HASH or a Koha::Object"); } @@ -130,6 +131,11 @@ sub tearDownTestContext { my ($self, $stash) = @_; ##You should introduce tearDowns in such an order that to not provoke FOREIGN KEY issues. + if ($stash->{'file'}) { + require t::lib::TestObjects::FileFactory; + t::lib::TestObjects::FileFactory->deleteTestGroup($stash->{'file'}); + delete $stash->{'file'}; + } if ($stash->{'serial-subscription'}) { require t::lib::TestObjects::Serial::SubscriptionFactory; t::lib::TestObjects::Serial::SubscriptionFactory->deleteTestGroup($stash->{'serial-subscription'}); @@ -206,6 +212,33 @@ sub getHashKey { return join('-', @collectedHashKeys); } +=head + +=cut + +sub addToContext { + my ($class, $objects, $hashKeys, $featureStash, $scenarioStash, $stepStash) = @_; + my @stashes = ($featureStash, $scenarioStash, $stepStash); + + if (ref($objects) eq 'ARRAY') { + foreach my $object (@$objects) { + $class->addToContext($object, $hashKeys, @stashes); + } + return undef; #End recursion + } + elsif (ref($objects) eq 'HASH') { + #Apparently we get a HASH of keyed objects. + $class->_persistToStashes($objects, $class->getHashGroupName(), @stashes); + return undef; #End recursion + } + else { + #Here $objects is verified to be a single object, instead of a group of objects. + #We create a hash key for it and append it to the stashes. + my $hash = { $class->getHashKey($objects, undef, $class->getDefaultHashKey) => $objects}; + $class->_persistToStashes($hash, $class->getHashGroupName(), @stashes); + } +} + =head validateAndPopulateDefaultValues @INTERFACE @@ -225,6 +258,54 @@ sub validateAndPopulateDefaultValues { } } +=head validateObjectType + + try { + $object = $class->validateObjectType($object); + } catch { + ... + } + +Validates if the given Object matches the expected type of the subclassing TestObjectFactory. +@PARAM1 Object that needs to be validated. +@THROWS Koha::Exception::UnknownObject, if the given object is not of the same type that the object factory creates. + +=cut + +sub validateObjectType { + my ($class, $object) = @_; + + my $invalid = 0; + if (blessed($object)) { + unless ($object->isa( $class->getObjectType() )) { + $invalid = 1; + } + } + else { + unless (ref($object) eq $class->getObjectType()) { + $invalid = 1; + } + } + + Koha::Exception::UnknownObject->throw( + error => "$class->validateObjectType():> Given object '$object' isn't a '".$class->getObjectType()."'-object." + ) if $invalid; + + return $object; +} + +=head getObjectType +@OVERLOAD +Get the type of objects this factory creates. +@RETURN String, the object package this factory creates. eg. Koha::Borrower +=cut + +sub getObjectType { + my ($class) = @_; + die "You must overload 'validateObjectType()' in the implementing ObjectFactory subclass '$class'."; + return 'Koha::Object derivative or other Object'; +} + =head _validateStashes _validateStashes($featureStash, $scenarioStash, $stepStash); @@ -255,15 +336,16 @@ Saves the given HASH to the given stashes using the given stash key. =cut sub _persistToStashes { - my ($self, $objects, $stashKey, $featureStash, $scenarioStash, $stepStash) = @_; + my ($class, $objects, $stashKey, $featureStash, $scenarioStash, $stepStash) = @_; if ($featureStash || $scenarioStash || $stepStash) { - while( my ($key, $biblio) = each %$objects) { - $featureStash->{$stashKey}->{ $key } = $biblio if $featureStash; - $scenarioStash->{$stashKey}->{ $key } = $biblio if $scenarioStash; - $stepStash->{$stashKey}->{ $key } = $biblio if $stepStash; + while( my ($key, $object) = each %$objects) { + $class->validateObjectType($object); #Make sure we put in what we are expected to + $featureStash->{$stashKey}->{ $key } = $object if $featureStash; + $scenarioStash->{$stashKey}->{ $key } = $object if $scenarioStash; + $stepStash->{$stashKey}->{ $key } = $object if $stepStash; } } } -1; \ No newline at end of file +1; diff --git a/t/lib/TestObjects/Serial/FrequencyFactory.pm b/t/lib/TestObjects/Serial/FrequencyFactory.pm index da48246..09889d3 100644 --- a/t/lib/TestObjects/Serial/FrequencyFactory.pm +++ b/t/lib/TestObjects/Serial/FrequencyFactory.pm @@ -38,6 +38,9 @@ sub new { sub getDefaultHashKey { return 'description'; } +sub getObjectType { + return 'Koha::Serial::Subscription::Frequency'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @OVERLOADED diff --git a/t/lib/TestObjects/Serial/SubscriptionFactory.pm b/t/lib/TestObjects/Serial/SubscriptionFactory.pm index f09514b..521ce90 100644 --- a/t/lib/TestObjects/Serial/SubscriptionFactory.pm +++ b/t/lib/TestObjects/Serial/SubscriptionFactory.pm @@ -21,7 +21,9 @@ package t::lib::TestObjects::Serial::SubscriptionFactory; use Modern::Perl; use Carp; use Scalar::Util qw(blessed); +use DateTime; +use C4::Context; use C4::Serials; use t::lib::TestObjects::BorrowerFactory; @@ -40,6 +42,9 @@ use base qw(t::lib::TestObjects::ObjectFactory); sub getDefaultHashKey { return 'internalnotes'; } +sub getObjectType { + return 'Koha::Serial::Subscription'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @@ -54,7 +59,7 @@ sub getDefaultHashKey { aqbudgetid => undef, #DEFAULT biblio => 21 || Koha::Biblio, #DEFAULT creates a "Serial magazine" Record startdate => '2015-01-01', #DEFAULTs to 1.1 this year, so the subscription is active by default. - periodicity => 7 || Koha::Serial::Subscription::Frequency, #DEFAULTS to a Frequency of 1/month. + periodicity => 2 || Koha::Serial::Subscription::Frequency, #DEFAULTS to a Frequency of 1/week. numberlength => 12, #DEFAULT one year subscription, only one of ['numberlength', 'weeklength', 'monthlength'] is needed weeklength => 52, #DEFAULT one year subscription monthlength => 12, #DEFAULT one year subscription @@ -170,6 +175,10 @@ and populates defaults for missing values. sub validateAndPopulateDefaultValues { my ($self, $object, $hashKey, $stashes) = @_; + #Get this year so we can use it to populate always active Objects. + my $now = DateTime->now(time_zone => C4::Context->tz()); + my $year = $now->year(); + if ($object->{librarian}) { $object->{librarian} = Koha::Borrowers->cast($object->{librarian}); } @@ -195,27 +204,27 @@ sub validateAndPopulateDefaultValues { $object->{biblio} = t::lib::TestObjects::BiblioFactory->createTestGroup([ {'biblio.title' => 'Serial magazine', 'biblio.author' => 'Pertti Kurikka', - 'biblio.copyrightdate' => '2015', + 'biblio.copyrightdate' => $year, 'biblioitems.isbn' => 'isbnisnotsocoolnowadays!', 'biblioitems.itemtype' => 'CR', }, ], undef, @$stashes) ->{'isbnisnotsocoolnowadays!'}; } - unless ($object->{internalnotes}) { croak __PACKAGE__.":> Mandatory parameter 'internalnotes' missing. This is used as the returning hash-key!"; } - $object->{periodicity} = 7 unless $object->{periodicity}; + + $object->{periodicity} = 4 unless $object->{periodicity}; $object->{numberpattern} = 2 unless $object->{numberpattern}; $object->{branchcode} = 'CPL' unless $object->{branchcode}; $object->{cost} = undef unless $object->{cost}; $object->{aqbudgetid} = undef unless $object->{aqbudgetid}; - $object->{startdate} = '2015-01-01' unless $object->{startdate}; + $object->{startdate} = "$year-01-01" unless $object->{startdate}; $object->{numberlength} = undef unless $object->{numberlength}; $object->{weeklength} = undef unless $object->{weeklength} || $object->{numberlength}; $object->{monthlength} = 12 unless $object->{monthlength} || $object->{weeklength} || $object->{numberlength}; - $object->{lastvalue1} = 2015 unless $object->{lastvalue1}; + $object->{lastvalue1} = $year unless $object->{lastvalue1}; $object->{innerloop1} = undef unless $object->{innerloop1}; $object->{lastvalue2} = 1 unless $object->{lastvalue2}; $object->{innerloop2} = undef unless $object->{innerloop2}; @@ -224,7 +233,7 @@ sub validateAndPopulateDefaultValues { $object->{status} = 1 unless $object->{status}; $object->{notes} = 'Public note' unless $object->{notes}; $object->{letter} = 'RLIST' unless $object->{letter}; - $object->{firstacquidate} = '2015-01-01' unless $object->{firstacquidate}; + $object->{firstacquidate} = "$year-01-01" unless $object->{firstacquidate}; $object->{irregularity} = undef unless $object->{irregularity}; $object->{locale} = undef unless $object->{locale}; $object->{callnumber} = 'MAG 10.2 AZ' unless $object->{callnumber}; diff --git a/t/lib/TestObjects/SystemPreferenceFactory.pm b/t/lib/TestObjects/SystemPreferenceFactory.pm index 8b58eba..81f4d3c 100644 --- a/t/lib/TestObjects/SystemPreferenceFactory.pm +++ b/t/lib/TestObjects/SystemPreferenceFactory.pm @@ -40,6 +40,9 @@ sub new { sub getDefaultHashKey { return 'preference'; } +sub getObjectType { + return 'HASH'; +} =head createTestGroup( $data [, $hashKey, $testContexts...] ) @OVERLOADED diff --git a/t/lib/TestObjects/objectFactories.t b/t/lib/TestObjects/objectFactories.t index 62646db..c6668b9 100644 --- a/t/lib/TestObjects/objectFactories.t +++ b/t/lib/TestObjects/objectFactories.t @@ -40,6 +40,9 @@ use t::lib::TestObjects::Acquisition::Bookseller::ContactFactory; use Koha::Acquisition::Bookseller::Contacts; use t::lib::TestObjects::Acquisition::BooksellerFactory; use Koha::Acquisition::Booksellers; +use t::lib::TestObjects::FileFactory; +use File::Slurp; +use File::Fu::File; use t::lib::TestObjects::Serial::SubscriptionFactory; use Koha::Serial::Subscriptions; use Koha::Serial::Subscription::Frequencies; @@ -53,24 +56,83 @@ my $testContext = {}; #Gather all created Objects here so we can finally remove +########## FileFactory subtests ########## +subtest 't::lib::TestObjects::FileFactory' => \&testFileFactory; +sub testFileFactory { + my ($files); + my $subtestContext = {}; + + $files = t::lib::TestObjects::FileFactory->createTestGroup([ + {'filepath' => 'atomicupdate', + 'filename' => '#30-RabiesIsMyDog.pl', + 'content' => 'print "Mermaids are my only love\nI never let them down";', + }, + {'filepath' => 'atomicupdate', + 'filename' => '#31-FrogsArePeopleToo.pl', + 'content' => 'print "Listen to the Maker!";', + }, + {'filepath' => 'atomicupdate', + 'filename' => '#32-AnimalLover.pl', + 'content' => "print 'Do not hurt them!;", + }, + ], undef, $subtestContext); + + my $file30content = File::Slurp::read_file( $files->{'#30-RabiesIsMyDog.pl'}->absolutely ); + ok($file30content =~ m/Mermaids are my only love/, + "'#30-RabiesIsMyDog.pl' created and content matches"); + my $file31content = File::Slurp::read_file( $files->{'#31-FrogsArePeopleToo.pl'}->absolutely ); + ok($file31content =~ m/Listen to the Maker!/, + "'#31-FrogsArePeopleToo.pl' created and content matches"); + my $file32content = File::Slurp::read_file( $files->{'#32-AnimalLover.pl'}->absolutely ); + ok($file32content =~ m/Do not hurt them!/, + "'#32-AnimalLover.pl' created and content matches"); + + ##addToContext() test, create new file + my $dir = $files->{'#32-AnimalLover.pl'}->dirname(); + my $file = File::Fu::File->new("$dir/addToContext.txt"); + $file->touch; + t::lib::TestObjects::FileFactory->addToContext($file, undef, $subtestContext); + ok($file->e, + "'addToContext.txt' created"); + + t::lib::TestObjects::ObjectFactory->tearDownTestContext($subtestContext); + + ok(not(-e $files->{'#30-RabiesIsMyDog.pl'}->absolutely), + "'#30-RabiesIsMyDog.pl' deleted"); + ok(not(-e $files->{'#31-FrogsArePeopleToo.pl'}->absolutely), + "'#31-FrogsArePeopleToo.pl' deleted"); + ok(not(-e $files->{'#32-AnimalLover.pl'}->absolutely), + "'#32-AnimalLover.pl' deleted"); + ok(not(-e $file->absolutely), + "'addToContext.txt' deleted"); +}; + + + ########## Serial subtests ########## -subtest 't::lib::TestObjects::Serial' => sub { - my ($subscriptions, $subscription, $frequency, $numberpattern, $biblio, $borrower, $bookseller, $items, $serials); +subtest 't::lib::TestObjects::Serial' => \&testSerialFactory; +sub testSerialFactory { + my ($subscriptions, $subscription, $frequency, $numberpattern, $biblio, $sameBiblio, $borrower, $bookseller, $items, $serials); my $subtestContext = {}; my $dontDeleteTestContext = {}; ##Create and delete $subscriptions = t::lib::TestObjects::Serial::SubscriptionFactory->createTestGroup([ {internalnotes => 'TESTDEFAULTS', receiveSerials => 3}, + {internalnotes => 'SAMEBIBLIO',}, ], undef, $subtestContext); $subscription = Koha::Serial::Subscriptions->find( $subscriptions->{'TESTDEFAULTS'}->subscriptionid ); $frequency = $subscription->periodicity(); $numberpattern = $subscription->numberpattern(); $biblio = $subscription->biblio(); + $sameBiblio = $subscriptions->{SAMEBIBLIO}->biblio; $borrower = $subscription->borrower(); $bookseller = $subscription->bookseller(); $items = $subscription->items(); $serials = $subscription->serials(); + is($biblio->biblionumber, + $sameBiblio->biblionumber, + "Default Subscriptions use the same default Biblio"); ok(($subscriptions->{'TESTDEFAULTS'}->callnumber eq $subscription->callnumber && $subscriptions->{'TESTDEFAULTS'}->subscriptionid eq $subscription->subscriptionid), "Default Subscription created."); @@ -163,7 +225,8 @@ subtest 't::lib::TestObjects::Serial' => sub { ########## Acquisition subtests ########## -subtest 't::lib::TestObjects::Acquisition' => sub { +subtest 't::lib::TestObjects::Acquisition' => \&testAcquisitionFactories; +sub testAcquisitionFactories { my ($booksellers, $bookseller, $contacts, $contact); my $subtestContext = {}; ##Create and delete @@ -198,7 +261,8 @@ subtest 't::lib::TestObjects::Acquisition' => sub { ########## BorrowerFactory subtests ########## -subtest 't::lib::TestObjects::BorrowerFactory' => sub { +subtest 't::lib::TestObjects::BorrowerFactory' => \&testBorrowerFactory; +sub testBorrowerFactory { my $subtestContext = {}; ##Create and Delete. Add one my $f = t::lib::TestObjects::BorrowerFactory->new(); @@ -223,10 +287,10 @@ subtest 't::lib::TestObjects::BorrowerFactory' => sub { ##Delete objects t::lib::TestObjects::ObjectFactory->tearDownTestContext($subtestContext); - my $object11A001 = Koha::Borrowers->find({cardnumber => '11A001'}); - ok (not($object11A001), "Borrower '11A001' deleted"); - my $object11A002 = Koha::Borrowers->find({cardnumber => '11A002'}); - ok (not($object11A002), "Borrower '11A002' deleted"); + foreach my $cn (('11A001', '11A002')) { + ok (not(Koha::Borrowers->find({cardnumber => $cn})), + "Borrower '11A001' deleted"); + } #Prepare for global autoremoval. $objects = $f->createTestGroup([ @@ -246,7 +310,8 @@ subtest 't::lib::TestObjects::BorrowerFactory' => sub { ########## BiblioFactory and ItemFactory subtests ########## -subtest 't::lib::TestObjects::BiblioFactory and ::ItemFactory' => sub { +subtest 't::lib::TestObjects::BiblioFactory and ::ItemFactory' => \&testBiblioItemFactories; +sub testBiblioItemFactories { my $subtestContext = {}; ##Create and Delete. Add one my $biblios = t::lib::TestObjects::BiblioFactory->createTestGroup([ @@ -302,7 +367,8 @@ subtest 't::lib::TestObjects::BiblioFactory and ::ItemFactory' => sub { ########## CheckoutFactory subtests ########## -subtest 't::lib::TestObjects::CheckoutFactory' => sub { +subtest 't::lib::TestObjects::CheckoutFactory' => \&testCheckoutFactory; +sub testCheckoutFactory { my $subtestContext = {}; ##Create and Delete using dependencies in the $testContext instantiated in previous subtests. my $biblios = t::lib::TestObjects::BiblioFactory->createTestGroup([ @@ -376,7 +442,8 @@ subtest 't::lib::TestObjects::CheckoutFactory' => sub { ########## LetterTemplateFactory subtests ########## -subtest 't::lib::TestObjects::LetterTemplateFactory' => sub { +subtest 't::lib::TestObjects::LetterTemplateFactory' => \&testLetterTemplateFactory; +sub testLetterTemplateFactory { my $subtestContext = {}; ##Create and Delete using dependencies in the $testContext instantiated in previous subtests. my $f = t::lib::TestObjects::LetterTemplateFactory->new(); @@ -406,7 +473,8 @@ subtest 't::lib::TestObjects::LetterTemplateFactory' => sub { ########## SystemPreferenceFactory subtests ########## -subtest 't::lib::TestObjects::SystemPreferenceFactory' => sub { +subtest 't::lib::TestObjects::SystemPreferenceFactory' => \&testSystemPreferenceFactory; +sub testSystemPreferenceFactory { my $subtestContext = {}; # take syspref 'opacuserlogin' and save its current value @@ -443,7 +511,8 @@ subtest 't::lib::TestObjects::SystemPreferenceFactory' => sub { ########## Global test context subtests ########## -subtest 't::lib::TestObjects::ObjectFactory clearing global test context' => sub { +subtest 't::lib::TestObjects::ObjectFactory clearing global test context' => \&testGlobalSubtestContext; +sub testGlobalSubtestContext { my $object11A001 = Koha::Borrowers->find({cardnumber => '11A001'}); ok ($object11A001, "Global Borrower '11A001' exists"); my $object11A002 = Koha::Borrowers->find({cardnumber => '11A002'}); -- 1.9.1