Bug 29234: Further clean Z3950 Tests
[koha-ffzg.git] / t / db_dependent / Koha / Holds.t
index adbb588..4b859cf 100755 (executable)
 
 use Modern::Perl;
 
-use Test::More tests => 6;
+use Test::More tests => 11;
 use Test::Warn;
 
 use C4::Circulation qw( AddIssue );
 use C4::Reserves qw( AddReserve ModReserve ModReserveCancelAll );
 use Koha::AuthorisedValueCategory;
+use Koha::Biblio::ItemGroups;
 use Koha::Database;
+use Koha::DateUtils qw( dt_from_string );
 use Koha::Holds;
 
 use t::lib::Mocks;
@@ -410,7 +412,7 @@ subtest 'Desks' => sub {
 };
 
 subtest 'get_items_that_can_fill' => sub {
-    plan tests => 3;
+    plan tests => 6;
 
     my $biblio = $builder->build_sample_biblio;
     my $itype_1 = $builder->build_object({ class => 'Koha::ItemTypes' }); # For 1, 2, 3, 4
@@ -425,16 +427,19 @@ subtest 'get_items_that_can_fill' => sub {
     my $item_5 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, itype => $itype_2->itemtype } );
     my $lost       = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, itemlost => 1 } );
     my $withdrawn  = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, withdrawn => 1 } );
-    my $notforloan = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, notforloan => 1 } );
+    my $notforloan = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, notforloan => -1 } );
 
     my $patron_1 = $builder->build_object( { class => 'Koha::Patrons' } );
     my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } );
     my $patron_3 = $builder->build_object( { class => 'Koha::Patrons' } );
 
+    my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } );
+
     t::lib::Mocks::mock_userenv( { patron => $patron_1 } );
 
     my $reserve_id_1 = C4::Reserves::AddReserve(
         {
+            branchcode     => $library_1->branchcode,
             borrowernumber => $patron_1->borrowernumber,
             biblionumber   => $biblio->biblionumber,
             priority       => 1,
@@ -448,6 +453,7 @@ subtest 'get_items_that_can_fill' => sub {
 
     my $reserve_id_2 = C4::Reserves::AddReserve(
         {
+            branchcode     => $library_1->branchcode,
             borrowernumber => $patron_2->borrowernumber,
             biblionumber   => $biblio->biblionumber,
             priority       => 2,
@@ -457,6 +463,7 @@ subtest 'get_items_that_can_fill' => sub {
 
     my $waiting_reserve_id = C4::Reserves::AddReserve(
         {
+            branchcode     => $library_1->branchcode,
             borrowernumber => $patron_2->borrowernumber,
             biblionumber   => $biblio->biblionumber,
             priority       => 0,
@@ -465,6 +472,16 @@ subtest 'get_items_that_can_fill' => sub {
         }
     );
 
+    my $notforloan_reserve_id = C4::Reserves::AddReserve(
+        {
+            branchcode     => $library_1->branchcode,
+            borrowernumber => $patron_2->borrowernumber,
+            biblionumber   => $biblio->biblionumber,
+            priority       => 0,
+            itemnumber     => $notforloan->itemnumber,
+        }
+    );
+
     # item 3 is on loan
     AddIssue( $patron_3->unblessed, $item_3->barcode );
 
@@ -482,7 +499,7 @@ subtest 'get_items_that_can_fill' => sub {
 
     $holds = Koha::Holds->search(
         {
-            reserve_id => [ $reserve_id_1, $reserve_id_2, $waiting_reserve_id, ]
+            reserve_id => [ $reserve_id_1, $reserve_id_2, $waiting_reserve_id, $notforloan_reserve_id, ]
         }
     );
 
@@ -502,8 +519,292 @@ subtest 'get_items_that_can_fill' => sub {
     is_deeply( [ map { $_->itemnumber } $items->as_list ],
         [ $item_2->itemnumber ], 'Only item 2 is available for filling the hold' );
 
+
+    my $noloan_itype = $builder->build_object( { class => 'Koha::ItemTypes', value => { notforloan => 1 } } );
+    t::lib::Mocks::mock_preference( 'item-level_itypes', 0 );
+    Koha::Holds->find( $waiting_reserve_id )->delete;
+    $holds = Koha::Holds->search(
+        {
+            reserve_id => [ $reserve_id_1, $reserve_id_2 ]
+        }
+    );
+    $items = $holds->get_items_that_can_fill;
+    is_deeply( [ sort { $a <=> $b } map { $_->itemnumber } $items->as_list ],
+        [ $item_1->itemnumber, $item_2->itemnumber, $item_5->itemnumber ], 'Items 1, 2, and 5 are available for filling the holds' );
+
+    my $no_holds = Koha::Holds->new->empty();
+    my $no_items = $no_holds->get_items_that_can_fill();
+    is( ref $no_items, "Koha::Items", "Routine returns a Koha::Items object");
+    is( $no_items->count, 0, "Object is empty when called on no holds");
+
+};
+
+subtest 'set_waiting+patron_expiration_date' => sub {
+    plan tests => 2;
+    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
+
+    my $item =
+      $builder->build_sample_item( { library => $library->branchcode } );
+    my $manager = $builder->build_object( { class => "Koha::Patrons" } );
+    t::lib::Mocks::mock_userenv(
+        { patron => $manager, branchcode => $manager->branchcode } );
+
+    my $patron = $builder->build_object(
+        {
+            class => 'Koha::Patrons',
+            value => { branchcode => $library->branchcode, }
+        }
+    );
+
+    subtest 'patron_expiration_date < expiration_date' => sub {
+        plan tests => 6;
+        t::lib::Mocks::mock_preference( 'ReservesMaxPickUpDelay', 5 );
+        my $patron_expiration_date = dt_from_string->add( days => 3 )->ymd;
+        my $reserve_id             = C4::Reserves::AddReserve(
+            {
+                branchcode      => $library->branchcode,
+                borrowernumber  => $patron->borrowernumber,
+                biblionumber    => $item->biblionumber,
+                priority        => 1,
+                itemnumber      => $item->itemnumber,
+                expiration_date => $patron_expiration_date,
+            }
+        );
+
+        my $hold = Koha::Holds->find($reserve_id);
+
+        is(
+            $hold->expirationdate,
+            $patron_expiration_date,
+            'expiration date set to patron expiration date'
+        );
+        is(
+            $hold->patron_expiration_date, $patron_expiration_date,
+            'patron expiration date correctly set'
+        );
+
+        $hold->set_waiting;
+
+        $hold = $hold->get_from_storage;
+        is( $hold->expirationdate,         $patron_expiration_date );
+        is( $hold->patron_expiration_date, $patron_expiration_date );
+
+        C4::Reserves::RevertWaitingStatus(
+            { itemnumber => $item->itemnumber }
+        );
+
+        $hold = $hold->get_from_storage;
+        is( $hold->expirationdate,         $patron_expiration_date );
+        is( $hold->patron_expiration_date, $patron_expiration_date );
+    };
+
+    subtest 'patron_expiration_date > expiration_date' => sub {
+        plan tests => 6;
+        t::lib::Mocks::mock_preference( 'ReservesMaxPickUpDelay', 5 );
+        my $new_expiration_date = dt_from_string->add( days => 5 )->ymd;
+        my $patron_expiration_date = dt_from_string->add( days => 6 )->ymd;
+        my $reserve_id             = C4::Reserves::AddReserve(
+            {
+                branchcode      => $library->branchcode,
+                borrowernumber  => $patron->borrowernumber,
+                biblionumber    => $item->biblionumber,
+                priority        => 1,
+                itemnumber      => $item->itemnumber,
+                expiration_date => $patron_expiration_date,
+            }
+        );
+
+        my $hold = Koha::Holds->find($reserve_id);
+
+        is(
+            $hold->expirationdate,
+            $patron_expiration_date,
+            'expiration date set to patron expiration date'
+        );
+        is(
+            $hold->patron_expiration_date, $patron_expiration_date,
+            'patron expiration date correctly set'
+        );
+
+        $hold->set_waiting;
+
+        $hold = $hold->get_from_storage;
+        is( $hold->expirationdate,         $new_expiration_date );
+        is( $hold->patron_expiration_date, $patron_expiration_date );
+
+        C4::Reserves::RevertWaitingStatus(
+            { itemnumber => $item->itemnumber }
+        );
+
+        $hold = $hold->get_from_storage;
+        is( $hold->expirationdate,         $patron_expiration_date );
+        is( $hold->patron_expiration_date, $patron_expiration_date );
+    };
+};
+
+subtest 'Test Koha::Hold::item_group' => sub {
+    plan tests => 1;
+    my $library    = $builder->build_object( { class => 'Koha::Libraries' } );
+    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
+    my $item = $builder->build_sample_item;
+    my $item_group = $builder->build_object(
+        {
+            class => 'Koha::Biblio::ItemGroups',
+        }
+    );
+    my $reserve_id = AddReserve(
+        {
+            branchcode       => $library->branchcode,
+            borrowernumber   => $patron->borrowernumber,
+            biblionumber     => $item->biblionumber,
+            itemnumber       => $item->itemnumber,
+            item_group_id    => $item_group->id,
+        }
+    );
+
+    my $hold = Koha::Holds->find($reserve_id);
+    is( $hold->item_group_id, $item_group->id,
+        'Koha::Hold::item_group returns the correct item_group' );
 };
 
+
 $schema->storage->txn_rollback;
 
-1;
+subtest 'filter_by_found() tests' => sub {
+
+    plan tests => 5;
+
+    $schema->storage->txn_begin;
+
+    my $unfilled   = $builder->build_object( { class => 'Koha::Holds', value => { found => undef } } );
+    my $processing = $builder->build_object( { class => 'Koha::Holds', value => { found => 'P' } } );
+    my $in_transit = $builder->build_object( { class => 'Koha::Holds', value => { found => 'T' } } );
+    my $waiting    = $builder->build_object( { class => 'Koha::Holds', value => { found => 'W' } } );
+
+    my $holds = Koha::Holds->search(
+        { reserve_id => [ $unfilled->id, $processing->id, $in_transit->id, $waiting->id ] },
+        { order_by => ['reserve_id'] }
+    );
+
+    is( $holds->count, 4, 'Resultset count is correct' );
+
+    my $found_holds = $holds->filter_by_found;
+
+    is( $found_holds->count, 3, 'Resultset count is correct' );
+
+    ok( $found_holds->next->is_in_processing, 'Status is correct (P)' );
+    ok( $found_holds->next->is_in_transit, 'Status is correct (T)' );
+    ok( $found_holds->next->is_waiting, 'Status is correct (W)' );
+
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'filter_by_has_cancellation_requests() and filter_out_has_cancellation_requests() tests' => sub {
+
+    plan tests => 7;
+
+    $schema->storage->txn_begin;
+
+    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
+
+    my $item_1 = $builder->build_sample_item;
+    my $item_2 = $builder->build_sample_item;
+    my $item_3 = $builder->build_sample_item;
+
+    my $hold_1 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => {
+                found          => 'W',
+                itemnumber     => $item_1->id,
+                biblionumber   => $item_1->biblionumber,
+                borrowernumber => $patron->id
+            }
+        }
+    );
+    my $hold_2 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => {
+                found          => 'W',
+                itemnumber     => $item_2->id,
+                biblionumber   => $item_2->biblionumber,
+                borrowernumber => $patron->id
+            }
+        }
+    );
+    my $hold_3 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => {
+                found          => 'W',
+                itemnumber     => $item_3->id,
+                biblionumber   => $item_3->biblionumber,
+                borrowernumber => $patron->id
+            }
+        }
+    );
+
+    my $rs = Koha::Holds->search(
+        { reserve_id => [ $hold_1->id, $hold_2->id, $hold_3->id ] } );
+
+    is( $rs->count, 3 );
+
+    my $filtered_rs = $rs->filter_by_has_cancellation_requests;
+
+    is( $filtered_rs->count, 0 );
+
+    my $filtered_out_rs = $rs->filter_out_has_cancellation_requests;
+
+    is( $filtered_out_rs->count, 3 );
+
+    $hold_2->add_cancellation_request;
+
+    $filtered_rs = $rs->filter_by_has_cancellation_requests;
+
+    is( $filtered_rs->count,    1 );
+    is( $filtered_rs->next->id, $hold_2->id );
+
+    $filtered_out_rs = $rs->filter_out_has_cancellation_requests;
+
+    is( $filtered_out_rs->count,    2 );
+    is( $filtered_out_rs->next->id, $hold_1->id );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'processing() tests' => sub {
+
+    plan tests => 3;
+
+    $schema->storage->txn_begin;
+
+    my $hold_1 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => { found => 'P' }
+        }
+    );
+    my $hold_2 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => { found => undef }
+        }
+    );
+    my $hold_3 = $builder->build_object(
+        {
+            class => 'Koha::Holds',
+            value => { found => 'T' }
+        }
+    );
+
+    my $holds = Koha::Holds->search({ reserve_id => [ $hold_1->id, $hold_2->id, $hold_3->id ] });
+    is( $holds->count, 3, 'Resultset contains 3 holds' );
+
+    my $processing = $holds->processing;
+    is( $processing->count, 1 );
+    is( $processing->next->id, $hold_1->id, "First hold is the only one in 'processing'" );
+
+    $schema->storage->txn_rollback;
+};