3 # Copyright 2020 Koha Development team
5 # This file is part of Koha
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
22 use Test::More tests => 11;
28 use t::lib::TestBuilder;
32 use Koha::DateUtils qw(dt_from_string);
37 my $schema = Koha::Database->new->schema;
38 my $builder = t::lib::TestBuilder->new;
40 subtest 'store() tests' => sub {
43 $schema->storage->txn_begin;
45 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
46 my $item = $builder->build_sample_item;
50 borrowernumber => $patron->borrowernumber,
51 biblionumber => $item->biblionumber,
53 itemnumber => $item->itemnumber,
57 'Koha::Exceptions::Hold::MissingPickupLocation',
58 'Exception thrown because branchcode was not passed';
60 my $hold = $builder->build_object( { class => 'Koha::Holds' } );
62 $hold->branchcode(undef)->store;
64 'Koha::Exceptions::Hold::MissingPickupLocation',
65 'Exception thrown if one tries to set branchcode to null';
67 $schema->storage->txn_rollback;
70 subtest 'fill() tests' => sub {
74 $schema->storage->txn_begin;
78 my $category = $builder->build_object(
80 class => 'Koha::Patron::Categories',
81 value => { reservefee => $fee }
84 my $patron = $builder->build_object(
86 class => 'Koha::Patrons',
87 value => { categorycode => $category->id }
90 my $manager = $builder->build_object( { class => 'Koha::Patrons' } );
92 my $title = 'Do what you want';
93 my $biblio = $builder->build_sample_biblio( { title => $title } );
94 my $item = $builder->build_sample_item( { biblionumber => $biblio->id } );
95 my $hold = $builder->build_object(
97 class => 'Koha::Holds',
99 biblionumber => $biblio->id,
100 borrowernumber => $patron->id,
101 itemnumber => $item->id,
107 t::lib::Mocks::mock_preference( 'HoldFeeMode', 'any_time_is_collected' );
108 t::lib::Mocks::mock_preference( 'HoldsLog', 1 );
109 t::lib::Mocks::mock_userenv(
110 { patron => $manager, branchcode => $manager->branchcode } );
112 my $interface = 'api';
113 C4::Context->interface($interface);
115 my $ret = $hold->fill;
117 is( ref($ret), 'Koha::Hold', '->fill returns the object type' );
118 is( $ret->id, $hold->id, '->fill returns the object' );
120 is( Koha::Holds->find($hold->id), undef, 'Hold no longer current' );
121 my $old_hold = Koha::Old::Holds->find( $hold->id );
123 is( $old_hold->id, $hold->id, 'reserve_id retained' );
124 is( $old_hold->priority, 0, 'priority set to 0' );
125 is( $old_hold->found, 'F', 'found set to F' );
127 subtest 'fee applied tests' => sub {
131 my $account = $patron->account;
132 is( $account->balance, $fee, 'Charge applied correctly' );
134 my $debits = $account->outstanding_debits;
135 is( $debits->count, 1, 'Only one fee charged' );
137 my $fee_debit = $debits->next;
138 is( $fee_debit->amount * 1, $fee, 'Fee amount stored correctly' );
139 is( $fee_debit->description, $title,
140 'Fee description stored correctly' );
141 is( $fee_debit->manager_id, $manager->id,
142 'Fee manager_id stored correctly' );
143 is( $fee_debit->branchcode, $manager->branchcode,
144 'Fee branchcode stored correctly' );
145 is( $fee_debit->interface, $interface,
146 'Fee interface stored correctly' );
147 is( $fee_debit->debit_type_code,
148 'RESERVE', 'Fee debit_type_code stored correctly' );
149 is( $fee_debit->itemnumber, $item->id,
150 'Fee itemnumber stored correctly' );
153 my $logs = Koha::ActionLogs->search(
161 is( $logs->count, 1, '1 log line added' );
163 # Set HoldFeeMode to something other than any_time_is_collected
164 t::lib::Mocks::mock_preference( 'HoldFeeMode', 'not_always' );
166 t::lib::Mocks::mock_preference( 'HoldsLog', 0 );
168 $hold = $builder->build_object(
170 class => 'Koha::Holds',
172 biblionumber => $biblio->id,
173 borrowernumber => $patron->id,
174 itemnumber => $item->id,
182 my $account = $patron->account;
183 is( $account->balance, $fee, 'No new charge applied' );
185 my $debits = $account->outstanding_debits;
186 is( $debits->count, 1, 'Only one fee charged, because of HoldFeeMode' );
188 $logs = Koha::ActionLogs->search(
196 is( $logs->count, 0, 'HoldsLog disabled, no logs added' );
198 subtest 'anonymization behavior tests' => sub {
202 # reduce the tests noise
203 t::lib::Mocks::mock_preference( 'HoldsLog', 0 );
204 t::lib::Mocks::mock_preference( 'HoldFeeMode', 'not_always' );
205 # unset AnonymousPatron
206 t::lib::Mocks::mock_preference( 'AnonymousPatron', undef );
209 $patron->privacy(0)->store;
210 my $hold = $builder->build_object(
212 class => 'Koha::Holds',
213 value => { borrowernumber => $patron->id, found => undef }
217 is( Koha::Old::Holds->find( $hold->id )->borrowernumber,
218 $patron->borrowernumber, 'Patron link is kept' );
220 # 1 == "default", meaning it is not protected from removal
221 $patron->privacy(1)->store;
222 $hold = $builder->build_object(
224 class => 'Koha::Holds',
225 value => { borrowernumber => $patron->id, found => undef }
229 is( Koha::Old::Holds->find( $hold->id )->borrowernumber,
230 $patron->borrowernumber, 'Patron link is kept' );
232 # 2 == delete immediately
233 $patron->privacy(2)->store;
234 $hold = $builder->build_object(
236 class => 'Koha::Holds',
237 value => { borrowernumber => $patron->id, found => undef }
244 'AnonymousPatron not set, exception thrown';
246 $hold->discard_changes; # refresh from DB
248 ok( !$hold->is_found, 'Hold is not filled' );
250 my $anonymous_patron = $builder->build_object({ class => 'Koha::Patrons' });
251 t::lib::Mocks::mock_preference( 'AnonymousPatron', $anonymous_patron->id );
253 $hold = $builder->build_object(
255 class => 'Koha::Holds',
256 value => { borrowernumber => $patron->id, found => undef }
261 Koha::Old::Holds->find( $hold->id )->borrowernumber,
262 $anonymous_patron->id,
263 'Patron link is set to the configured anonymous patron immediately'
267 subtest 'holds_queue update tests' => sub {
271 my $biblio = $builder->build_sample_biblio;
273 my $mock = Test::MockModule->new('Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue');
274 $mock->mock( 'enqueue', sub {
275 my ( $self, $args ) = @_;
279 '->fill triggers a holds queue update for the related biblio'
283 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 );
285 $builder->build_object(
287 class => 'Koha::Holds',
289 biblionumber => $biblio->id,
294 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 0 );
295 # this call shouldn't add a new test
296 $builder->build_object(
298 class => 'Koha::Holds',
300 biblionumber => $biblio->id,
306 $schema->storage->txn_rollback;
309 subtest 'patron() tests' => sub {
313 $schema->storage->txn_begin;
315 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
316 my $hold = $builder->build_object(
318 class => 'Koha::Holds',
320 borrowernumber => $patron->borrowernumber
325 my $hold_patron = $hold->patron;
326 is( ref($hold_patron), 'Koha::Patron', 'Right type' );
327 is( $hold_patron->id, $patron->id, 'Right object' );
329 $schema->storage->txn_rollback;
332 subtest 'set_pickup_location() tests' => sub {
336 $schema->storage->txn_begin;
338 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
339 my $mock_item = Test::MockModule->new('Koha::Item');
341 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
342 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
343 my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
345 # let's control what Koha::Biblio->pickup_locations returns, for testing
346 $mock_biblio->mock( 'pickup_locations', sub {
347 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
349 # let's mock what Koha::Item->pickup_locations returns, for testing
350 $mock_item->mock( 'pickup_locations', sub {
351 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
354 my $biblio = $builder->build_sample_biblio;
355 my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
357 # Test biblio-level holds
358 my $biblio_hold = $builder->build_object(
360 class => "Koha::Holds",
362 biblionumber => $biblio->biblionumber,
363 branchcode => $library_3->branchcode,
370 { $biblio_hold->set_pickup_location({ library_id => $library_1->branchcode }); }
371 'Koha::Exceptions::Hold::InvalidPickupLocation',
372 'Exception thrown on invalid pickup location';
374 $biblio_hold->discard_changes;
375 is( $biblio_hold->branchcode, $library_3->branchcode, 'branchcode remains untouched' );
377 my $ret = $biblio_hold->set_pickup_location({ library_id => $library_2->id });
378 is( ref($ret), 'Koha::Hold', 'self is returned' );
380 $biblio_hold->discard_changes;
381 is( $biblio_hold->branchcode, $library_2->id, 'Pickup location changed correctly' );
383 # Test item-level holds
384 my $item_hold = $builder->build_object(
386 class => "Koha::Holds",
388 biblionumber => $biblio->biblionumber,
389 branchcode => $library_3->branchcode,
390 itemnumber => $item->itemnumber,
396 { $item_hold->set_pickup_location({ library_id => $library_1->branchcode }); }
397 'Koha::Exceptions::Hold::InvalidPickupLocation',
398 'Exception thrown on invalid pickup location';
400 $item_hold->discard_changes;
401 is( $item_hold->branchcode, $library_3->branchcode, 'branchcode remains untouched' );
403 $item_hold->set_pickup_location({ library_id => $library_1->branchcode, force => 1 });
404 $item_hold->discard_changes;
405 is( $item_hold->branchcode, $library_1->branchcode, 'branchcode changed because of \'force\'' );
407 $ret = $item_hold->set_pickup_location({ library_id => $library_2->id });
408 is( ref($ret), 'Koha::Hold', 'self is returned' );
410 $item_hold->discard_changes;
411 is( $item_hold->branchcode, $library_2->id, 'Pickup location changed correctly' );
414 { $item_hold->set_pickup_location({ library_id => undef }); }
415 'Koha::Exceptions::MissingParameter',
416 'Exception thrown if missing parameter';
418 like( "$@", qr/The library_id parameter is mandatory/, 'Exception message is clear' );
420 $schema->storage->txn_rollback;
423 subtest 'is_pickup_location_valid() tests' => sub {
427 $schema->storage->txn_begin;
429 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
430 my $mock_item = Test::MockModule->new('Koha::Item');
432 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
433 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
434 my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
436 # let's control what Koha::Biblio->pickup_locations returns, for testing
437 $mock_biblio->mock( 'pickup_locations', sub {
438 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
440 # let's mock what Koha::Item->pickup_locations returns, for testing
441 $mock_item->mock( 'pickup_locations', sub {
442 return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
445 my $biblio = $builder->build_sample_biblio;
446 my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
448 # Test biblio-level holds
449 my $biblio_hold = $builder->build_object(
451 class => "Koha::Holds",
453 biblionumber => $biblio->biblionumber,
454 branchcode => $library_3->branchcode,
460 ok( !$biblio_hold->is_pickup_location_valid({ library_id => $library_1->branchcode }), 'Pickup location invalid');
461 ok( $biblio_hold->is_pickup_location_valid({ library_id => $library_2->id }), 'Pickup location valid');
463 # Test item-level holds
464 my $item_hold = $builder->build_object(
466 class => "Koha::Holds",
468 biblionumber => $biblio->biblionumber,
469 branchcode => $library_3->branchcode,
470 itemnumber => $item->itemnumber,
475 ok( !$item_hold->is_pickup_location_valid({ library_id => $library_1->branchcode }), 'Pickup location invalid');
476 ok( $item_hold->is_pickup_location_valid({ library_id => $library_2->id }), 'Pickup location valid' );
478 subtest 'pickup_locations() returning ->empty' => sub {
482 $schema->storage->txn_begin;
484 my $library = $builder->build_object({ class => 'Koha::Libraries' });
486 my $mock_item = Test::MockModule->new('Koha::Item');
487 $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->new->empty; } );
489 my $mock_biblio = Test::MockModule->new('Koha::Biblio');
490 $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->new->empty; } );
492 my $item = $builder->build_sample_item();
493 my $biblio = $item->biblio;
495 # Test biblio-level holds
496 my $biblio_hold = $builder->build_object(
498 class => "Koha::Holds",
500 biblionumber => $biblio->biblionumber,
506 ok( !$biblio_hold->is_pickup_location_valid({ library_id => $library->branchcode }), 'Pickup location invalid');
508 # Test item-level holds
509 my $item_hold = $builder->build_object(
511 class => "Koha::Holds",
513 biblionumber => $biblio->biblionumber,
514 itemnumber => $item->itemnumber,
519 ok( !$item_hold->is_pickup_location_valid({ library_id => $library->branchcode }), 'Pickup location invalid');
521 $schema->storage->txn_rollback;
524 $schema->storage->txn_rollback;
527 subtest 'cancel() tests' => sub {
531 $schema->storage->txn_begin;
533 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
535 # reduce the tests noise
536 t::lib::Mocks::mock_preference( 'HoldsLog', 0 );
537 t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelayCharge',
540 t::lib::Mocks::mock_preference( 'AnonymousPatron', undef );
543 $patron->privacy(0)->store;
544 my $hold = $builder->build_object(
546 class => 'Koha::Holds',
547 value => { borrowernumber => $patron->id, found => undef }
551 is( Koha::Old::Holds->find( $hold->id )->borrowernumber,
552 $patron->borrowernumber, 'Patron link is kept' );
554 # 1 == "default", meaning it is not protected from removal
555 $patron->privacy(1)->store;
556 $hold = $builder->build_object(
558 class => 'Koha::Holds',
559 value => { borrowernumber => $patron->id, found => undef }
563 is( Koha::Old::Holds->find( $hold->id )->borrowernumber,
564 $patron->borrowernumber, 'Patron link is kept' );
566 # 2 == delete immediately
567 $patron->privacy(2)->store;
568 $hold = $builder->build_object(
570 class => 'Koha::Holds',
571 value => { borrowernumber => $patron->id, found => undef }
577 'AnonymousPatron not set, exception thrown';
579 $hold->discard_changes;
581 ok( !$hold->is_found, 'Hold is not cancelled' );
583 my $anonymous_patron = $builder->build_object({ class => 'Koha::Patrons' });
584 t::lib::Mocks::mock_preference( 'AnonymousPatron', $anonymous_patron->id );
586 $hold = $builder->build_object(
588 class => 'Koha::Holds',
589 value => { borrowernumber => $patron->id, found => undef }
594 Koha::Old::Holds->find( $hold->id )->borrowernumber,
595 $anonymous_patron->id,
596 'Patron link is set to the configured anonymous patron immediately'
599 subtest 'holds_queue update tests' => sub {
603 my $biblio = $builder->build_sample_biblio;
605 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 );
607 my $mock = Test::MockModule->new('Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue');
608 $mock->mock( 'enqueue', sub {
609 my ( $self, $args ) = @_;
613 '->cancel triggers a holds queue update for the related biblio'
617 $builder->build_object(
619 class => 'Koha::Holds',
621 biblionumber => $biblio->id,
626 # If the skip_holds_queue param is not honoured, then test count will fail.
627 $builder->build_object(
629 class => 'Koha::Holds',
631 biblionumber => $biblio->id,
634 )->cancel({ skip_holds_queue => 1 });
636 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 0 );
638 $builder->build_object(
640 class => 'Koha::Holds',
642 biblionumber => $biblio->id,
645 )->cancel({ skip_holds_queue => 0 });
648 $schema->storage->txn_rollback;
651 subtest 'suspend_hold() and resume() tests' => sub {
655 $schema->storage->txn_begin;
657 my $biblio = $builder->build_sample_biblio;
660 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 );
662 my $mock = Test::MockModule->new('Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue');
663 $mock->mock( 'enqueue', sub {
664 my ( $self, $args ) = @_;
668 "->$action triggers a holds queue update for the related biblio"
672 my $hold = $builder->build_object(
674 class => 'Koha::Holds',
676 biblionumber => $biblio->id,
682 $action = 'suspend_hold';
688 $schema->storage->txn_rollback;
691 subtest 'cancellation_requests() and add_cancellation_request() tests' => sub {
695 $schema->storage->txn_begin;
697 t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 0 );
699 my $hold = $builder->build_object( { class => 'Koha::Holds', } );
701 is( $hold->cancellation_requests->count, 0 );
703 # Add two cancellation requests
704 my $request_1 = $hold->add_cancellation_request;
705 isnt( $request_1->creation_date, undef, 'creation_date is set' );
707 my $requester = $builder->build_object( { class => 'Koha::Patrons' } );
708 my $creation_date = '2021-06-25 14:05:35';
710 my $request_2 = $hold->add_cancellation_request(
712 creation_date => $creation_date,
716 is( $request_2->creation_date, $creation_date, 'Passed creation_date set' );
718 is( $hold->cancellation_requests->count, 2 );
720 $schema->storage->txn_rollback;
723 subtest 'cancellation_requestable_from_opac() tests' => sub {
727 $schema->storage->txn_begin;
730 $builder->build_object( { class => 'Koha::Patron::Categories' } );
731 my $item_home_library =
732 $builder->build_object( { class => 'Koha::Libraries' } );
733 my $patron_home_library =
734 $builder->build_object( { class => 'Koha::Libraries' } );
737 $builder->build_sample_item( { library => $item_home_library->id } );
738 my $patron = $builder->build_object(
740 class => 'Koha::Patrons',
741 value => { branchcode => $patron_home_library->id }
745 subtest 'Exception cases' => sub {
749 my $hold = $builder->build_object(
751 class => 'Koha::Holds',
755 borrowernumber => $patron->id
760 throws_ok { $hold->cancellation_requestable_from_opac; }
761 'Koha::Exceptions::InvalidStatus',
762 'Exception thrown because hold is not waiting';
764 is( $@->invalid_status, 'hold_not_waiting' );
766 $hold = $builder->build_object(
768 class => 'Koha::Holds',
772 borrowernumber => $patron->id
777 throws_ok { $hold->cancellation_requestable_from_opac; }
778 'Koha::Exceptions::InvalidStatus',
779 'Exception thrown because waiting hold has no item linked';
781 is( $@->invalid_status, 'no_item_linked' );
784 # set default rule to enabled
785 Koha::CirculationRules->set_rule(
790 rule_name => 'waiting_hold_cancellation',
795 my $hold = $builder->build_object(
797 class => 'Koha::Holds',
799 itemnumber => $item->id,
801 borrowernumber => $patron->id
806 t::lib::Mocks::mock_preference( 'ReservesControlBranch',
809 Koha::CirculationRules->set_rule(
811 categorycode => $patron->categorycode,
812 itemtype => $item->itype,
813 branchcode => $item->homebranch,
814 rule_name => 'waiting_hold_cancellation',
819 ok( !$hold->cancellation_requestable_from_opac );
821 Koha::CirculationRules->set_rule(
823 categorycode => $patron->categorycode,
824 itemtype => $item->itype,
825 branchcode => $item->homebranch,
826 rule_name => 'waiting_hold_cancellation',
832 $hold->cancellation_requestable_from_opac,
833 'Make sure it is picking the right circulation rule'
836 t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
838 Koha::CirculationRules->set_rule(
840 categorycode => $patron->categorycode,
841 itemtype => $item->itype,
842 branchcode => $patron->branchcode,
843 rule_name => 'waiting_hold_cancellation',
848 ok( !$hold->cancellation_requestable_from_opac );
850 Koha::CirculationRules->set_rule(
852 categorycode => $patron->categorycode,
853 itemtype => $item->itype,
854 branchcode => $patron->branchcode,
855 rule_name => 'waiting_hold_cancellation',
861 $hold->cancellation_requestable_from_opac,
862 'Make sure it is picking the right circulation rule'
865 $schema->storage->txn_rollback;
868 subtest 'can_update_pickup_location_opac() tests' => sub {
872 $schema->storage->txn_begin;
874 my $hold = $builder->build_object(
875 { class => 'Koha::Holds',
876 value => { found => undef, suspend => 0, suspend_until => undef, waitingdate => undef }
880 t::lib::Mocks::mock_preference( 'OPACAllowUserToChangeBranch', '' );
882 is( $hold->can_update_pickup_location_opac, 0, "Pending hold pickup can't be changed (No change allowed)" );
885 is( $hold->can_update_pickup_location_opac, 0, "In transit hold pickup can't be changed (No change allowed)" );
888 is( $hold->can_update_pickup_location_opac, 0, "Waiting hold pickup can't be changed (No change allowed)" );
891 my $dt = dt_from_string();
893 $hold->suspend_hold( $dt );
894 is( $hold->can_update_pickup_location_opac, 0, "Suspended hold pickup can't be changed (No change allowed)" );
897 t::lib::Mocks::mock_preference( 'OPACAllowUserToChangeBranch', 'pending,intransit,suspended' );
899 is( $hold->can_update_pickup_location_opac, 1, "Pending hold pickup can be changed (pending,intransit,suspended allowed)" );
902 is( $hold->can_update_pickup_location_opac, 1, "In transit hold pickup can be changed (pending,intransit,suspended allowed)" );
905 is( $hold->can_update_pickup_location_opac, 0, "Waiting hold pickup can't be changed (pending,intransit,suspended allowed)" );
908 $dt = dt_from_string();
909 $hold->suspend_hold( $dt );
910 is( $hold->can_update_pickup_location_opac, 1, "Suspended hold pickup can be changed (pending,intransit,suspended allowed)" );
912 $schema->storage->txn_rollback;
915 subtest 'Koha::Hold::item_group tests' => sub {
919 $schema->storage->txn_begin;
921 my $library = $builder->build_object( { class => 'Koha::Libraries' } );
922 my $category = $builder->build_object(
924 class => 'Koha::Patron::Categories',
925 value => { exclude_from_local_holds_priority => 0 }
928 my $patron = $builder->build_object(
930 class => "Koha::Patrons",
932 branchcode => $library->branchcode,
933 categorycode => $category->categorycode
937 my $biblio = $builder->build_sample_biblio();
940 Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store();
942 my $hold = $builder->build_object(
944 class => "Koha::Holds",
946 borrowernumber => $patron->borrowernumber,
947 biblionumber => $biblio->biblionumber,
949 item_group_id => $item_group->id,
954 is( $hold->item_group->id, $item_group->id, "Got correct item group" );
956 $schema->storage->txn_rollback;