Bug 13969: Testing C4::Review
[koha.git] / t / db_dependent / Holds.t
index 2c28c07..4aee01b 100755 (executable)
@@ -6,11 +6,14 @@ use t::lib::Mocks;
 use C4::Context;
 use C4::Branch;
 
-use Test::More tests => 25;
+use Test::More tests => 38;
 use MARC::Record;
 use C4::Biblio;
 use C4::Items;
 use C4::Members;
+use C4::Calendar;
+
+use Koha::DateUtils qw( dt_from_string output_pref );
 
 BEGIN {
     use FindBin;
@@ -26,13 +29,17 @@ $dbh->{RaiseError} = 1;
 
 my $borrowers_count = 5;
 
+$dbh->do('DELETE FROM itemtypes');
+my $insert_sth = $dbh->prepare('INSERT INTO itemtypes (itemtype) VALUES (?)');
+$insert_sth->execute('CAN');
+$insert_sth->execute('CANNOT');
+$insert_sth->execute('DUMMY');
+
 # Setup Test------------------------
-# Helper biblio.
-diag("Creating biblio instance for testing.");
-my ($bibnum, $title, $bibitemnum) = create_helper_biblio();
+# Create a biblio instance for testing
+my ($bibnum, $title, $bibitemnum) = create_helper_biblio('DUMMY');
 
-# Helper item for that biblio.
-diag("Creating item instance for testing.");
+# Create item instance for testing.
 my ($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => 'CPL', holdingbranch => 'CPL' } , $bibnum);
 
 # Create some borrowers
@@ -71,11 +78,14 @@ foreach my $borrowernumber ( @borrowernumbers ) {
 }
 
 
-my ($count, $reserves) = GetReservesFromBiblionumber($biblionumber);
-is( $count, $borrowers_count, "Test GetReserves()" );
+my $reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber });
+is( scalar(@$reserves), $borrowers_count, "Test GetReserves()" );
 
 
 my ( $reservedate, $borrowernumber, $branchcode, $reserve_id ) = GetReservesFromItemnumber($itemnumber);
+is( $reservedate, output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 }), "GetReservesFromItemnumber should return a valid reserve date");
+is( $borrowernumber, $borrowernumbers[0], "GetReservesFromItemnumber should return a valid borrowernumber");
+is( $branchcode, 'CPL', "GetReservesFromItemnumber should return a valid branchcode");
 ok($reserve_id, "Test GetReservesFromItemnumber()");
 
 
@@ -87,8 +97,8 @@ ok( GetReserveCount( $borrowernumbers[0] ), "Test GetReserveCount()" );
 
 
 CancelReserve({ 'reserve_id' => $reserve_id });
-($count, $reserves) = GetReservesFromBiblionumber($biblionumber);
-ok( $count == $borrowers_count - 1, "Test CancelReserve()" );
+$reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber });
+is( scalar(@$reserves), $borrowers_count - 1, "Test CancelReserve()" );
 
 
 ( $reservedate, $borrowernumber, $branchcode, $reserve_id ) = GetReservesFromItemnumber($itemnumber);
@@ -148,7 +158,7 @@ my $reserve2 = GetReserveInfo( $reserve->{'reserve_id'} );
 ok( $reserve->{'reserve_id'} eq $reserve2->{'reserve_id'}, "Test GetReserveInfo()" );
 
 
-($count, $reserves) = GetReservesFromBiblionumber($biblionumber,1);
+$reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber, all_dates => 1 });
 $reserve = $reserves->[1];
 AlterPriority( 'top', $reserve->{'reserve_id'} );
 $reserve = GetReserve( $reserve->{'reserve_id'} );
@@ -177,7 +187,7 @@ ok( $reserve->{'priority'} eq '5', "Test AlterPriority(), move to bottom" );
 # Note that canreservefromotherbranches has no effect if
 # IndependentBranches is OFF.
 
-my ($foreign_bibnum, $foreign_title, $foreign_bibitemnum) = create_helper_biblio();
+my ($foreign_bibnum, $foreign_title, $foreign_bibitemnum) = create_helper_biblio('DUMMY');
 my ($foreign_item_bibnum, $foreign_item_bibitemnum, $foreign_itemnumber)
   = AddItem({ homebranch => 'MPL', holdingbranch => 'MPL' } , $foreign_bibnum);
 $dbh->do('DELETE FROM issuingrules');
@@ -187,6 +197,12 @@ $dbh->do(
     {},
     '*', '*', '*', 25
 );
+$dbh->do(
+    q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed)
+      VALUES (?, ?, ?, ?)}, 
+    {},
+    '*', '*', 'CANNOT', 0 
+);
 
 # make sure some basic sysprefs are set
 t::lib::Mocks::mock_preference('ReservesControlBranch', 'homebranch');
@@ -195,7 +211,7 @@ t::lib::Mocks::mock_preference('item-level_itypes', 1);
 # if IndependentBranches is OFF, a CPL patron can reserve an MPL item
 t::lib::Mocks::mock_preference('IndependentBranches', 0);
 ok(
-    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
+    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'OK',
     'CPL patron allowed to reserve MPL item with IndependentBranches OFF (bug 2394)'
 );
 
@@ -203,20 +219,19 @@ ok(
 t::lib::Mocks::mock_preference('IndependentBranches', 1);
 t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
 ok(
-    ! CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
+    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'cannotReserveFromOtherBranches',
     'CPL patron NOT allowed to reserve MPL item with IndependentBranches ON ... (bug 2394)'
 );
 
 # ... unless canreservefromotherbranches is ON
 t::lib::Mocks::mock_preference('canreservefromotherbranches', 1);
 ok(
-    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
+    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'OK',
     '... unless canreservefromotherbranches is ON (bug 2394)'
 );
 
 # Regression test for bug 11336
-($bibnum, $title, $bibitemnum) = create_helper_biblio();
-my ( $hold1, $hold2 );
+($bibnum, $title, $bibitemnum) = create_helper_biblio('DUMMY');
 ($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => 'CPL', holdingbranch => 'CPL' } , $bibnum);
 AddReserve(
     $branch,
@@ -278,14 +293,87 @@ ModReserve({ reserve_id => $reserveid2, rank => 'del' });
 $reserve3 = GetReserve( $reserveid3 );
 is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
 
+ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
+C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
+ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
+ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
+C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
+ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
+ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" );
+
+# Regression test for bug 9532
+($bibnum, $title, $bibitemnum) = create_helper_biblio('CANNOT');
+($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => 'CPL', holdingbranch => 'CPL', itype => 'CANNOT' } , $bibnum);
+AddReserve(
+    $branch,
+    $borrowernumbers[0],
+    $bibnum,
+    'a',
+    '',
+    1,
+);
+ok(
+    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'tooManyReserves',
+    "cannot request item if policy that matches on item-level item type forbids it"
+);
+ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
+ok(
+    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK',
+    "can request item if policy that matches on item type allows it"
+);
+
+t::lib::Mocks::mock_preference('item-level_itypes', 0);
+ModItem({ itype => undef }, $item_bibnum, $itemnumber);
+ok(
+    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'tooManyReserves',
+    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
+);
+
+# Test CancelExpiredReserves
+C4::Context->set_preference('ExpireReservesMaxPickUpDelay', 1);
+C4::Context->set_preference('ReservesMaxPickUpDelay', 1);
+
+my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);
+$year += 1900;
+$mon += 1;
+$reserves = $dbh->selectall_arrayref('SELECT * FROM reserves', { Slice => {} });
+$reserve = $reserves->[0];
+my $calendar = C4::Calendar->new(branchcode => $reserve->{branchcode});
+$calendar->insert_single_holiday(
+    day         => $mday,
+    month       => $mon,
+    year        => $year,
+    title       => 'Test',
+    description => 'Test',
+);
+$reserve_id = $reserve->{reserve_id};
+$dbh->do("UPDATE reserves SET waitingdate = DATE_SUB( NOW(), INTERVAL 5 DAY ), found = 'W', priority = 0 WHERE reserve_id = ?", undef, $reserve_id );
+C4::Context->set_preference('ExpireReservesOnHolidays', 0);
+CancelExpiredReserves();
+my $count = $dbh->selectrow_array("SELECT COUNT(*) FROM reserves WHERE reserve_id = ?", undef, $reserve_id );
+is( $count, 1, "Waiting reserve beyond max pickup delay *not* canceled on holiday" );
+C4::Context->set_preference('ExpireReservesOnHolidays', 1);
+CancelExpiredReserves();
+$count = $dbh->selectrow_array("SELECT COUNT(*) FROM reserves WHERE reserve_id = ?", undef, $reserve_id );
+is( $count, 0, "Waiting reserve beyond max pickup delay canceled on holiday" );
+
+# Test expirationdate
+$reserve = $reserves->[1];
+$reserve_id = $reserve->{reserve_id};
+$dbh->do("UPDATE reserves SET expirationdate = DATE_SUB( NOW(), INTERVAL 1 DAY ) WHERE reserve_id = ?", undef, $reserve_id );
+CancelExpiredReserves();
+$count = $dbh->selectrow_array("SELECT COUNT(*) FROM reserves WHERE reserve_id = ?", undef, $reserve_id );
+is( $count, 0, "Reserve with manual expiration date canceled correctly" );
 
 # Helper method to set up a Biblio.
 sub create_helper_biblio {
+    my $itemtype = shift;
     my $bib = MARC::Record->new();
     my $title = 'Silence in the library';
     $bib->append_fields(
         MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
         MARC::Field->new('245', ' ', ' ', a => $title),
+        MARC::Field->new('942', ' ', ' ', c => $itemtype),
     );
     return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
 }