From e2baedcd6f19d2ac629a9d22d3f9425865153751 Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Fri, 3 Sep 2021 16:47:14 -0300
Subject: [PATCH] Bug 28529: Unit tests

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 t/db_dependent/Reserves.t | 184 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 183 insertions(+), 1 deletion(-)

diff --git a/t/db_dependent/Reserves.t b/t/db_dependent/Reserves.t
index 5bda45c4fa..a15a997056 100755
--- a/t/db_dependent/Reserves.t
+++ b/t/db_dependent/Reserves.t
@@ -17,7 +17,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 71;
+use Test::More tests => 73;
 use Test::MockModule;
 use Test::Warn;
 
@@ -1519,3 +1519,185 @@ subtest 'AlterPriorty() tests' => sub {
 
     $schema->storage->txn_rollback;
 };
+
+subtest 'CanBookBeReserved() tests' => sub {
+
+    plan tests => 4;
+
+    $schema->storage->txn_begin;
+
+    my $library = $builder->build_object(
+        { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
+    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
+    my $itype  = $builder->build_object( { class => 'Koha::ItemTypes' } );
+
+    my $biblio = $builder->build_sample_biblio();
+    my $item_1 = $builder->build_sample_item(
+        { biblionumber => $biblio->id, itype => $itype->id } );
+    my $item_2 = $builder->build_sample_item(
+        { biblionumber => $biblio->id, itype => $itype->id } );
+
+    Koha::CirculationRules->delete;
+    Koha::CirculationRules->set_rules(
+        {
+            branchcode   => undef,
+            categorycode => undef,
+            itemtype     => undef,
+            rules        => {
+                holds_per_record => 100,
+            }
+        }
+    );
+    Koha::CirculationRules->set_rules(
+        {
+            branchcode   => undef,
+            categorycode => undef,
+            itemtype     => $itype->id,
+            rules        => {
+                reservesallowed => 2,
+            }
+        }
+    );
+
+    C4::Reserves::AddReserve(
+        {
+            branchcode     => $library->id,
+            borrowernumber => $patron->id,
+            biblionumber   => $biblio->id,
+            title          => $biblio->title,
+            itemnumber     => $item_1->id
+        }
+    );
+
+    ## Limit on item type is 2, only one hold, success tests
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 1 );
+
+    my $res = CanBookBeReserved( $patron->id, $biblio->id, $library->id,
+        { itemtype => $itype->id } );
+    is_deeply( $res, { status => 'OK' },
+        'Holds on itemtype limit not reached' );
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 0 );
+
+    $res = CanBookBeReserved( $patron->id, $biblio->id, $library->id,
+        { itemtype => $itype->id } );
+    is_deeply(
+        $res,
+        { status => 'OK' },
+        'Holds on itemtype not considering biblio-level'
+    );
+
+    # Add a second hold, biblio-level and item type-constrained
+    C4::Reserves::AddReserve(
+        {
+            branchcode     => $library->id,
+            borrowernumber => $patron->id,
+            biblionumber   => $biblio->id,
+            title          => $biblio->title,
+            itemtype       => $itype->id,
+        }
+    );
+
+    ## Limit on item type is 2, two holds, one of them biblio-level/item type-constrained
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 1 );
+
+    $res = CanBookBeReserved( $patron->id, $biblio->id, $library->id,
+        { itemtype => $itype->id } );
+    is_deeply( $res, { status => '' }, 'Holds on itemtype limit reached' );
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 0 );
+
+    $res = CanBookBeReserved( $patron->id, $biblio->id, $library->id,
+        { itemtype => $itype->id } );
+    is_deeply(
+        $res,
+        { status => 'OK' },
+        'Holds on itemtype not considering biblio-level'
+    );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'CanItemBeReserved() tests' => sub {
+
+    plan tests => 4;
+
+    $schema->storage->txn_begin;
+
+    my $library = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
+    my $patron  = $builder->build_object( { class => 'Koha::Patrons' } );
+    my $itype   = $builder->build_object( { class => 'Koha::ItemTypes' } );
+
+    my $biblio = $builder->build_sample_biblio();
+    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->id, itype => $itype->id });
+    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->id, itype => $itype->id });
+
+    Koha::CirculationRules->delete;
+    Koha::CirculationRules->set_rules(
+        {   branchcode   => undef,
+            categorycode => undef,
+            itemtype     => undef,
+            rules        => {
+                holds_per_record => 100,
+            }
+        }
+    );
+    Koha::CirculationRules->set_rules(
+        {   branchcode   => undef,
+            categorycode => undef,
+            itemtype     => $itype->id,
+            rules        => {
+                reservesallowed => 2,
+            }
+        }
+    );
+
+    C4::Reserves::AddReserve(
+        {
+            branchcode     => $library->id,
+            borrowernumber => $patron->id,
+            biblionumber   => $biblio->id,
+            title          => $biblio->title,
+            itemnumber     => $item_1->id
+        }
+    );
+
+    ## Limit on item type is 2, only one hold, success tests
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 1 );
+
+    my $res = CanItemBeReserved( $patron, $item_2, $library->id );
+    is_deeply( $res, { status => 'OK' }, 'Holds on itemtype limit not reached' );
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 0 );
+
+    $res = CanItemBeReserved( $patron, $item_2, $library->id );
+    is_deeply( $res, { status => 'OK' }, 'Holds on itemtype not considering biblio-level' );
+
+    # Add a second hold, biblio-level and item type-constrained
+    C4::Reserves::AddReserve(
+        {
+            branchcode     => $library->id,
+            borrowernumber => $patron->id,
+            biblionumber   => $biblio->id,
+            title          => $biblio->title,
+            itemtype       => $itype->id,
+        }
+    );
+
+    ## Limit on item type is 2, two holds, one of them biblio-level/item type-constrained
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 1 );
+
+    $res = CanItemBeReserved( $patron, $item_2, $library->id );
+    is_deeply( $res, { status => 'tooManyReserves', limit => 2 }, 'Holds on itemtype limit reached' );
+
+    t::lib::Mocks::mock_preference( 'BiblioHoldItemTypeUseForRules', 0 );
+
+    $res = CanItemBeReserved( $patron, $item_2, $library->id );
+    is_deeply( $res, { status => 'OK' }, 'Holds on itemtype not considering biblio-level' );
+
+    $schema->storage->txn_rollback;
+};
-- 
2.20.1