Lines 64-77
my $itemnumber = $builder->build_sample_item({ library => $branch_1, biblionumbe
Link Here
|
64 |
|
64 |
|
65 |
# Create some borrowers |
65 |
# Create some borrowers |
66 |
my @borrowernumbers; |
66 |
my @borrowernumbers; |
|
|
67 |
my @patrons; |
67 |
foreach (1..$borrowers_count) { |
68 |
foreach (1..$borrowers_count) { |
68 |
my $borrowernumber = Koha::Patron->new({ |
69 |
my $patron = Koha::Patron->new({ |
69 |
firstname => 'my firstname', |
70 |
firstname => 'my firstname', |
70 |
surname => 'my surname ' . $_, |
71 |
surname => 'my surname ' . $_, |
71 |
categorycode => $category->{categorycode}, |
72 |
categorycode => $category->{categorycode}, |
72 |
branchcode => $branch_1, |
73 |
branchcode => $branch_1, |
73 |
})->store->borrowernumber; |
74 |
})->store; |
74 |
push @borrowernumbers, $borrowernumber; |
75 |
push @patrons, $patron; |
|
|
76 |
push @borrowernumbers, $patron->borrowernumber; |
75 |
} |
77 |
} |
76 |
|
78 |
|
77 |
# Create five item level holds |
79 |
# Create five item level holds |
Lines 233-239
is( $hold->priority, '6', "Test AlterPriority(), move to bottom" );
Link Here
|
233 |
# IndependentBranches is OFF. |
235 |
# IndependentBranches is OFF. |
234 |
|
236 |
|
235 |
my $foreign_biblio = $builder->build_sample_biblio({ itemtype => 'DUMMY' }); |
237 |
my $foreign_biblio = $builder->build_sample_biblio({ itemtype => 'DUMMY' }); |
236 |
my $foreign_itemnumber = $builder->build_sample_item({ library => $branch_2, biblionumber => $foreign_biblio->biblionumber })->itemnumber; |
238 |
my $foreign_item = $builder->build_sample_item({ library => $branch_2, biblionumber => $foreign_biblio->biblionumber }); |
237 |
Koha::CirculationRules->set_rules( |
239 |
Koha::CirculationRules->set_rules( |
238 |
{ |
240 |
{ |
239 |
categorycode => undef, |
241 |
categorycode => undef, |
Lines 265-271
t::lib::Mocks::mock_preference('item-level_itypes', 1);
Link Here
|
265 |
t::lib::Mocks::mock_preference('IndependentBranches', 0); |
267 |
t::lib::Mocks::mock_preference('IndependentBranches', 0); |
266 |
|
268 |
|
267 |
is( |
269 |
is( |
268 |
CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status}, 'OK', |
270 |
CanItemBeReserved($patrons[0], $foreign_item)->{status}, 'OK', |
269 |
'$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)' |
271 |
'$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)' |
270 |
); |
272 |
); |
271 |
|
273 |
|
Lines 273-286
is(
Link Here
|
273 |
t::lib::Mocks::mock_preference('IndependentBranches', 1); |
275 |
t::lib::Mocks::mock_preference('IndependentBranches', 1); |
274 |
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0); |
276 |
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0); |
275 |
ok( |
277 |
ok( |
276 |
CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'cannotReserveFromOtherBranches', |
278 |
CanItemBeReserved($patrons[0], $foreign_item)->{status} eq 'cannotReserveFromOtherBranches', |
277 |
'$branch_1 patron NOT allowed to reserve $branch_2 item with IndependentBranches ON ... (bug 2394)' |
279 |
'$branch_1 patron NOT allowed to reserve $branch_2 item with IndependentBranches ON ... (bug 2394)' |
278 |
); |
280 |
); |
279 |
|
281 |
|
280 |
# ... unless canreservefromotherbranches is ON |
282 |
# ... unless canreservefromotherbranches is ON |
281 |
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1); |
283 |
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1); |
282 |
ok( |
284 |
ok( |
283 |
CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'OK', |
285 |
CanItemBeReserved($patrons[0], $foreign_item)->{status} eq 'OK', |
284 |
'... unless canreservefromotherbranches is ON (bug 2394)' |
286 |
'... unless canreservefromotherbranches is ON (bug 2394)' |
285 |
); |
287 |
); |
286 |
|
288 |
|
Lines 325-333
ok(
Link Here
|
325 |
is( $hold3->discard_changes->priority, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" ); |
327 |
is( $hold3->discard_changes->priority, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" ); |
326 |
} |
328 |
} |
327 |
|
329 |
|
328 |
Koha::Items->find($itemnumber)->damaged(1)->store; # FIXME The $itemnumber is a bit confusing here |
330 |
my $damaged_item = Koha::Items->find($itemnumber)->damaged(1)->store; # FIXME The $itemnumber is a bit confusing here |
329 |
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 ); |
331 |
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 ); |
330 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" ); |
332 |
is( CanItemBeReserved( $patrons[0], $damaged_item)->{status}, 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" ); |
331 |
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" ); |
333 |
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" ); |
332 |
|
334 |
|
333 |
$hold = Koha::Hold->new( |
335 |
$hold = Koha::Hold->new( |
Lines 337-356
$hold = Koha::Hold->new(
Link Here
|
337 |
biblionumber => $biblio->biblionumber, |
339 |
biblionumber => $biblio->biblionumber, |
338 |
} |
340 |
} |
339 |
)->store(); |
341 |
)->store(); |
340 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, |
342 |
is( CanItemBeReserved( $patrons[0], $damaged_item )->{status}, |
341 |
'itemAlreadyOnHold', |
343 |
'itemAlreadyOnHold', |
342 |
"Patron cannot place a second item level hold for a given item" ); |
344 |
"Patron cannot place a second item level hold for a given item" ); |
343 |
$hold->delete(); |
345 |
$hold->delete(); |
344 |
|
346 |
|
345 |
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 0 ); |
347 |
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 0 ); |
346 |
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" ); |
348 |
ok( CanItemBeReserved( $patrons[0], $damaged_item)->{status} eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" ); |
347 |
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" ); |
349 |
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" ); |
348 |
|
350 |
|
349 |
# Items that are not for loan, but holdable should not be trapped until they are available for loan |
351 |
# Items that are not for loan, but holdable should not be trapped until they are available for loan |
350 |
t::lib::Mocks::mock_preference( 'TrapHoldsOnOrder', 0 ); |
352 |
t::lib::Mocks::mock_preference( 'TrapHoldsOnOrder', 0 ); |
351 |
Koha::Items->find($itemnumber)->damaged(0)->notforloan(-1)->store; |
353 |
my $nfl_item = Koha::Items->find($itemnumber)->damaged(0)->notforloan(-1)->store; |
352 |
Koha::Holds->search({ biblionumber => $biblio->id })->delete(); |
354 |
Koha::Holds->search({ biblionumber => $biblio->id })->delete(); |
353 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'OK', "Patron can place hold on item that is not for loan but holdable ( notforloan < 0 )" ); |
355 |
is( CanItemBeReserved( $patrons[0], $nfl_item)->{status}, 'OK', "Patron can place hold on item that is not for loan but holdable ( notforloan < 0 )" ); |
354 |
$hold = Koha::Hold->new( |
356 |
$hold = Koha::Hold->new( |
355 |
{ |
357 |
{ |
356 |
borrowernumber => $borrowernumbers[0], |
358 |
borrowernumber => $borrowernumbers[0], |
Lines 370-380
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for i
Link Here
|
370 |
t::lib::Mocks::mock_preference( 'SkipHoldTrapOnNotForLoanValue', '-1|1' ); |
372 |
t::lib::Mocks::mock_preference( 'SkipHoldTrapOnNotForLoanValue', '-1|1' ); |
371 |
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for item with notforloan value matching SkipHoldTrapOnNotForLoanValue" ); |
373 |
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for item with notforloan value matching SkipHoldTrapOnNotForLoanValue" ); |
372 |
is( |
374 |
is( |
373 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'itemAlreadyOnHold', |
375 |
CanItemBeReserved( $patrons[0], $nfl_item)->{status}, 'itemAlreadyOnHold', |
374 |
"cannot request item that you have already reservedd" |
376 |
"cannot request item that you have already reservedd" |
375 |
); |
377 |
); |
376 |
is( |
378 |
is( |
377 |
CanItemBeReserved( $borrowernumbers[0], $item->itemnumber, undef, { ignore_hold_counts => 1 })->{status}, 'OK', |
379 |
CanItemBeReserved( $patrons[0], $item, undef, { ignore_hold_counts => 1 })->{status}, 'OK', |
378 |
"can request item if we are not checking holds counts, but only if policy allows or forbids it" |
380 |
"can request item if we are not checking holds counts, but only if policy allows or forbids it" |
379 |
); |
381 |
); |
380 |
$hold->delete(); |
382 |
$hold->delete(); |
Lines 391-401
AddReserve(
Link Here
|
391 |
} |
393 |
} |
392 |
); |
394 |
); |
393 |
is( |
395 |
is( |
394 |
CanItemBeReserved( $borrowernumbers[0], $item->itemnumber)->{status}, 'noReservesAllowed', |
396 |
CanItemBeReserved( $patrons[0], $item)->{status}, 'noReservesAllowed', |
395 |
"cannot request item if policy that matches on item-level item type forbids it" |
397 |
"cannot request item if policy that matches on item-level item type forbids it" |
396 |
); |
398 |
); |
397 |
is( |
399 |
is( |
398 |
CanItemBeReserved( $borrowernumbers[0], $item->itemnumber, undef, { ignore_hold_counts => 1 })->{status}, 'noReservesAllowed', |
400 |
CanItemBeReserved( $patrons[0], $item, undef, { ignore_hold_counts => 1 })->{status}, 'noReservesAllowed', |
399 |
"cannot request item if policy that matches on item-level item type forbids it even if ignoring counts" |
401 |
"cannot request item if policy that matches on item-level item type forbids it even if ignoring counts" |
400 |
); |
402 |
); |
401 |
|
403 |
|
Lines 468-501
subtest 'CanItemBeReserved' => sub {
Link Here
|
468 |
my $biblionumber_can = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
470 |
my $biblionumber_can = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
469 |
my $biblionumber_record_cannot = $builder->build_sample_biblio({ itemtype => $itemtype_cant_record })->biblionumber; |
471 |
my $biblionumber_record_cannot = $builder->build_sample_biblio({ itemtype => $itemtype_cant_record })->biblionumber; |
470 |
|
472 |
|
471 |
my $itemnumber_1_can = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_cannot })->itemnumber; |
473 |
my $item_1_can = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_cannot }); |
472 |
my $itemnumber_1_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant, biblionumber => $biblionumber_cannot })->itemnumber; |
474 |
my $item_1_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant, biblionumber => $biblionumber_cannot }); |
473 |
my $itemnumber_2_can = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_can })->itemnumber; |
475 |
my $item_2_can = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_can }); |
474 |
my $itemnumber_2_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant, biblionumber => $biblionumber_can })->itemnumber; |
476 |
my $item_2_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant, biblionumber => $biblionumber_can }); |
475 |
my $itemnumber_3_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant_record, biblionumber => $biblionumber_record_cannot })->itemnumber; |
477 |
my $item_3_cannot = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_cant_record, biblionumber => $biblionumber_record_cannot }); |
476 |
|
478 |
|
477 |
Koha::Holds->search({borrowernumber => $borrowernumbers[0]})->delete; |
479 |
Koha::Holds->search({borrowernumber => $borrowernumbers[0]})->delete; |
478 |
|
480 |
|
479 |
t::lib::Mocks::mock_preference('item-level_itypes', 1); |
481 |
t::lib::Mocks::mock_preference('item-level_itypes', 1); |
480 |
is( |
482 |
is( |
481 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_2_cannot)->{status}, 'noReservesAllowed', |
483 |
CanItemBeReserved( $patrons[0], $item_2_cannot)->{status}, 'noReservesAllowed', |
482 |
"With item level set, rule from item must be picked (CANNOT)" |
484 |
"With item level set, rule from item must be picked (CANNOT)" |
483 |
); |
485 |
); |
484 |
is( |
486 |
is( |
485 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_1_can)->{status}, 'OK', |
487 |
CanItemBeReserved( $patrons[0], $item_1_can)->{status}, 'OK', |
486 |
"With item level set, rule from item must be picked (CAN)" |
488 |
"With item level set, rule from item must be picked (CAN)" |
487 |
); |
489 |
); |
488 |
t::lib::Mocks::mock_preference('item-level_itypes', 0); |
490 |
t::lib::Mocks::mock_preference('item-level_itypes', 0); |
489 |
is( |
491 |
is( |
490 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_1_can)->{status}, 'noReservesAllowed', |
492 |
CanItemBeReserved( $patrons[0], $item_1_can)->{status}, 'noReservesAllowed', |
491 |
"With biblio level set, rule from biblio must be picked (CANNOT)" |
493 |
"With biblio level set, rule from biblio must be picked (CANNOT)" |
492 |
); |
494 |
); |
493 |
is( |
495 |
is( |
494 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_2_cannot)->{status}, 'OK', |
496 |
CanItemBeReserved( $patrons[0], $item_2_cannot)->{status}, 'OK', |
495 |
"With biblio level set, rule from biblio must be picked (CAN)" |
497 |
"With biblio level set, rule from biblio must be picked (CAN)" |
496 |
); |
498 |
); |
497 |
is( |
499 |
is( |
498 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_3_cannot)->{status}, 'noReservesAllowed', |
500 |
CanItemBeReserved( $patrons[0], $item_3_cannot)->{status}, 'noReservesAllowed', |
499 |
"When no holds allowed and no holds per record allowed should return noReservesAllowed" |
501 |
"When no holds allowed and no holds per record allowed should return noReservesAllowed" |
500 |
); |
502 |
); |
501 |
}; |
503 |
}; |
Lines 504-514
subtest 'CanItemBeReserved' => sub {
Link Here
|
504 |
plan tests => 7; |
506 |
plan tests => 7; |
505 |
|
507 |
|
506 |
my $biblionumber_1 = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
508 |
my $biblionumber_1 = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
507 |
my $itemnumber_11 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_1 })->itemnumber; |
509 |
my $item_11 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_1 }); |
508 |
my $itemnumber_12 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_1 })->itemnumber; |
510 |
my $item_12 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_1 }); |
509 |
my $biblionumber_2 = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
511 |
my $biblionumber_2 = $builder->build_sample_biblio({ itemtype => $itemtype_can })->biblionumber; |
510 |
my $itemnumber_21 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_2 })->itemnumber; |
512 |
my $item_21 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_2 }); |
511 |
my $itemnumber_22 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_2 })->itemnumber; |
513 |
my $item_22 = $builder->build_sample_item({ homebranch => $branch_1, holdingbranch => $branch_1, itype => $itemtype_can, biblionumber => $biblionumber_2 }); |
512 |
|
514 |
|
513 |
Koha::Holds->search({borrowernumber => $borrowernumbers[0]})->delete; |
515 |
Koha::Holds->search({borrowernumber => $borrowernumbers[0]})->delete; |
514 |
|
516 |
|
Lines 522-528
subtest 'CanItemBeReserved' => sub {
Link Here
|
522 |
t::lib::Mocks::mock_preference('item-level_itypes', $item_level); |
524 |
t::lib::Mocks::mock_preference('item-level_itypes', $item_level); |
523 |
is( |
525 |
is( |
524 |
# FIXME This is not really correct, but CanItemBeReserved does not check if biblio-level holds already exist |
526 |
# FIXME This is not really correct, but CanItemBeReserved does not check if biblio-level holds already exist |
525 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_11)->{status}, 'OK', |
527 |
CanItemBeReserved( $patrons[0], $item_11)->{status}, 'OK', |
526 |
"A biblio-level hold already exists - another hold can be placed on a specific item item" |
528 |
"A biblio-level hold already exists - another hold can be placed on a specific item item" |
527 |
); |
529 |
); |
528 |
} |
530 |
} |
Lines 533-539
subtest 'CanItemBeReserved' => sub {
Link Here
|
533 |
branch => $branch_1, |
535 |
branch => $branch_1, |
534 |
borrowernumber => $borrowernumbers[0], |
536 |
borrowernumber => $borrowernumbers[0], |
535 |
biblionumber => $biblionumber_1, |
537 |
biblionumber => $biblionumber_1, |
536 |
itemnumber => $itemnumber_11, |
538 |
itemnumber => $item_11->itemnumber, |
537 |
}); |
539 |
}); |
538 |
|
540 |
|
539 |
$dbh->do('DELETE FROM circulation_rules'); |
541 |
$dbh->do('DELETE FROM circulation_rules'); |
Lines 549-555
subtest 'CanItemBeReserved' => sub {
Link Here
|
549 |
} |
551 |
} |
550 |
); |
552 |
); |
551 |
is( |
553 |
is( |
552 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_12)->{status}, 'tooManyHoldsForThisRecord', |
554 |
CanItemBeReserved( $patrons[0], $item_12)->{status}, 'tooManyHoldsForThisRecord', |
553 |
"A item-level hold already exists and holds_per_record=1, another hold cannot be placed on this record" |
555 |
"A item-level hold already exists and holds_per_record=1, another hold cannot be placed on this record" |
554 |
); |
556 |
); |
555 |
Koha::CirculationRules->set_rules( |
557 |
Koha::CirculationRules->set_rules( |
Lines 564-570
subtest 'CanItemBeReserved' => sub {
Link Here
|
564 |
} |
566 |
} |
565 |
); |
567 |
); |
566 |
is( |
568 |
is( |
567 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_12)->{status}, 'tooManyHoldsForThisRecord', |
569 |
CanItemBeReserved( $patrons[0], $item_12)->{status}, 'tooManyHoldsForThisRecord', |
568 |
"A item-level hold already exists and holds_per_record=1 - tooManyHoldsForThisRecord has priority over tooManyReserves" |
570 |
"A item-level hold already exists and holds_per_record=1 - tooManyHoldsForThisRecord has priority over tooManyReserves" |
569 |
); |
571 |
); |
570 |
Koha::CirculationRules->set_rules( |
572 |
Koha::CirculationRules->set_rules( |
Lines 579-585
subtest 'CanItemBeReserved' => sub {
Link Here
|
579 |
} |
581 |
} |
580 |
); |
582 |
); |
581 |
is( |
583 |
is( |
582 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_12)->{status}, 'OK', |
584 |
CanItemBeReserved( $patrons[0], $item_12)->{status}, 'OK', |
583 |
"A item-level hold already exists but holds_per_record=2- another item-level hold can be placed on this record" |
585 |
"A item-level hold already exists but holds_per_record=2- another item-level hold can be placed on this record" |
584 |
); |
586 |
); |
585 |
|
587 |
|
Lines 587-593
subtest 'CanItemBeReserved' => sub {
Link Here
|
587 |
branch => $branch_1, |
589 |
branch => $branch_1, |
588 |
borrowernumber => $borrowernumbers[0], |
590 |
borrowernumber => $borrowernumbers[0], |
589 |
biblionumber => $biblionumber_2, |
591 |
biblionumber => $biblionumber_2, |
590 |
itemnumber => $itemnumber_21 |
592 |
itemnumber => $item_21->itemnumber |
591 |
}); |
593 |
}); |
592 |
Koha::CirculationRules->set_rules( |
594 |
Koha::CirculationRules->set_rules( |
593 |
{ |
595 |
{ |
Lines 601-611
subtest 'CanItemBeReserved' => sub {
Link Here
|
601 |
} |
603 |
} |
602 |
); |
604 |
); |
603 |
is( |
605 |
is( |
604 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_21)->{status}, 'itemAlreadyOnHold', |
606 |
CanItemBeReserved( $patrons[0], $item_21)->{status}, 'itemAlreadyOnHold', |
605 |
"A item-level holds already exists on this item, itemAlreadyOnHold should be raised" |
607 |
"A item-level holds already exists on this item, itemAlreadyOnHold should be raised" |
606 |
); |
608 |
); |
607 |
is( |
609 |
is( |
608 |
CanItemBeReserved( $borrowernumbers[0], $itemnumber_22)->{status}, 'tooManyReserves', |
610 |
CanItemBeReserved( $patrons[0], $item_22)->{status}, 'tooManyReserves', |
609 |
"This patron has already placed reservesallowed holds, tooManyReserves should be raised" |
611 |
"This patron has already placed reservesallowed holds, tooManyReserves should be raised" |
610 |
); |
612 |
); |
611 |
}; |
613 |
}; |
Lines 647-668
Koha::CirculationRules->set_rules(
Link Here
|
647 |
} |
649 |
} |
648 |
); |
650 |
); |
649 |
$biblio = $builder->build_sample_biblio({ itemtype => 'CANNOT' }); |
651 |
$biblio = $builder->build_sample_biblio({ itemtype => 'CANNOT' }); |
650 |
$itemnumber = $builder->build_sample_item({ library => $branch_1, itype => 'CANNOT', biblionumber => $biblio->biblionumber})->itemnumber; |
652 |
my $branch_rule_item = $builder->build_sample_item({ library => $branch_1, itype => 'CANNOT', biblionumber => $biblio->biblionumber}); |
651 |
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, 'notReservable', |
653 |
is(CanItemBeReserved($patrons[0], $branch_rule_item)->{status}, 'notReservable', |
652 |
"CanItemBeReserved should return 'notReservable'"); |
654 |
"CanItemBeReserved should return 'notReservable'"); |
653 |
|
655 |
|
654 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' ); |
656 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' ); |
655 |
$itemnumber = $builder->build_sample_item({ library => $branch_2, itype => 'CAN', biblionumber => $biblio->biblionumber})->itemnumber; |
657 |
$branch_rule_item = $builder->build_sample_item({ library => $branch_2, itype => 'CAN', biblionumber => $biblio->biblionumber}); |
656 |
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, |
658 |
is(CanItemBeReserved($patrons[0], $branch_rule_item)->{status}, |
657 |
'cannotReserveFromOtherBranches', |
659 |
'cannotReserveFromOtherBranches', |
658 |
"CanItemBeReserved should use PatronLibrary rule when ReservesControlBranch set to 'PatronLibrary'"); |
660 |
"CanItemBeReserved should use PatronLibrary rule when ReservesControlBranch set to 'PatronLibrary'"); |
659 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' ); |
661 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' ); |
660 |
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, |
662 |
is(CanItemBeReserved($patrons[0], $branch_rule_item)->{status}, |
661 |
'OK', |
663 |
'OK', |
662 |
"CanItemBeReserved should use item home library rule when ReservesControlBranch set to 'ItemsHomeLibrary'"); |
664 |
"CanItemBeReserved should use item home library rule when ReservesControlBranch set to 'ItemsHomeLibrary'"); |
663 |
|
665 |
|
664 |
$itemnumber = $builder->build_sample_item({ library => $branch_1, itype => 'CAN', biblionumber => $biblio->biblionumber})->itemnumber; |
666 |
$branch_rule_item = $builder->build_sample_item({ library => $branch_1, itype => 'CAN', biblionumber => $biblio->biblionumber}); |
665 |
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, 'OK', |
667 |
is(CanItemBeReserved($patrons[0], $branch_rule_item)->{status}, 'OK', |
666 |
"CanItemBeReserved should return 'OK'"); |
668 |
"CanItemBeReserved should return 'OK'"); |
667 |
|
669 |
|
668 |
# Bug 12632 |
670 |
# Bug 12632 |
Lines 675-681
$dbh->do('DELETE FROM items');
Link Here
|
675 |
$dbh->do('DELETE FROM biblio'); |
677 |
$dbh->do('DELETE FROM biblio'); |
676 |
|
678 |
|
677 |
$biblio = $builder->build_sample_biblio({ itemtype => 'ONLY1' }); |
679 |
$biblio = $builder->build_sample_biblio({ itemtype => 'ONLY1' }); |
678 |
$itemnumber = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber})->itemnumber; |
680 |
my $limit_count_item = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber}); |
679 |
|
681 |
|
680 |
Koha::CirculationRules->set_rules( |
682 |
Koha::CirculationRules->set_rules( |
681 |
{ |
683 |
{ |
Lines 688-694
Koha::CirculationRules->set_rules(
Link Here
|
688 |
} |
690 |
} |
689 |
} |
691 |
} |
690 |
); |
692 |
); |
691 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, |
693 |
is( CanItemBeReserved( $patrons[0], $limit_count_item )->{status}, |
692 |
'OK', 'Patron can reserve item with hold limit of 1, no holds placed' ); |
694 |
'OK', 'Patron can reserve item with hold limit of 1, no holds placed' ); |
693 |
|
695 |
|
694 |
my $res_id = AddReserve( |
696 |
my $res_id = AddReserve( |
Lines 700-713
my $res_id = AddReserve(
Link Here
|
700 |
} |
702 |
} |
701 |
); |
703 |
); |
702 |
|
704 |
|
703 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, |
705 |
is( CanItemBeReserved( $patrons[0], $limit_count_item )->{status}, |
704 |
'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' ); |
706 |
'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' ); |
705 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber, undef, { ignore_hold_counts => 1 } )->{status}, |
707 |
is( CanItemBeReserved( $patrons[0], $limit_count_item, undef, { ignore_hold_counts => 1 } )->{status}, |
706 |
'OK', 'Patron can reserve item if checking policy but not counts' ); |
708 |
'OK', 'Patron can reserve item if checking policy but not counts' ); |
707 |
|
709 |
|
708 |
#results should be the same for both ReservesControlBranch settings |
710 |
#results should be the same for both ReservesControlBranch settings |
709 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' ); |
711 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' ); |
710 |
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, |
712 |
is( CanItemBeReserved( $patrons[0], $limit_count_item )->{status}, |
711 |
'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' ); |
713 |
'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' ); |
712 |
#reset for further tests |
714 |
#reset for further tests |
713 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' ); |
715 |
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' ); |
Lines 718-724
subtest 'Test max_holds per library/patron category' => sub {
Link Here
|
718 |
$dbh->do('DELETE FROM reserves'); |
720 |
$dbh->do('DELETE FROM reserves'); |
719 |
|
721 |
|
720 |
$biblio = $builder->build_sample_biblio; |
722 |
$biblio = $builder->build_sample_biblio; |
721 |
$itemnumber = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber})->itemnumber; |
723 |
my $max_holds_item = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber}); |
722 |
Koha::CirculationRules->set_rules( |
724 |
Koha::CirculationRules->set_rules( |
723 |
{ |
725 |
{ |
724 |
categorycode => undef, |
726 |
categorycode => undef, |
Lines 746-752
subtest 'Test max_holds per library/patron category' => sub {
Link Here
|
746 |
Koha::Holds->search( { borrowernumber => $borrowernumbers[0] } )->count(); |
748 |
Koha::Holds->search( { borrowernumber => $borrowernumbers[0] } )->count(); |
747 |
is( $count, 3, 'Patron now has 3 holds' ); |
749 |
is( $count, 3, 'Patron now has 3 holds' ); |
748 |
|
750 |
|
749 |
my $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber ); |
751 |
my $ret = CanItemBeReserved( $patrons[0], $max_holds_item ); |
750 |
is( $ret->{status}, 'OK', 'Patron can place hold with no borrower circ rules' ); |
752 |
is( $ret->{status}, 'OK', 'Patron can place hold with no borrower circ rules' ); |
751 |
|
753 |
|
752 |
my $rule_all = Koha::CirculationRules->set_rule( |
754 |
my $rule_all = Koha::CirculationRules->set_rule( |
Lines 767-785
subtest 'Test max_holds per library/patron category' => sub {
Link Here
|
767 |
} |
769 |
} |
768 |
); |
770 |
); |
769 |
|
771 |
|
770 |
$ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber ); |
772 |
$ret = CanItemBeReserved( $patrons[0], $max_holds_item ); |
771 |
is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 3' ); |
773 |
is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 3' ); |
772 |
|
774 |
|
773 |
$rule_branch->delete(); |
775 |
$rule_branch->delete(); |
774 |
|
776 |
|
775 |
$ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber ); |
777 |
$ret = CanItemBeReserved( $patrons[0], $max_holds_item ); |
776 |
is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a category rule of 3' ); |
778 |
is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a category rule of 3' ); |
777 |
|
779 |
|
778 |
$rule_all->delete(); |
780 |
$rule_all->delete(); |
779 |
$rule_branch->rule_value(3); |
781 |
$rule_branch->rule_value(3); |
780 |
$rule_branch->store(); |
782 |
$rule_branch->store(); |
781 |
|
783 |
|
782 |
$ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber ); |
784 |
$ret = CanItemBeReserved( $patrons[0], $max_holds_item ); |
783 |
is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a branch/category rule of 3' ); |
785 |
is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a branch/category rule of 3' ); |
784 |
|
786 |
|
785 |
$rule_branch->rule_value(5); |
787 |
$rule_branch->rule_value(5); |
Lines 787-793
subtest 'Test max_holds per library/patron category' => sub {
Link Here
|
787 |
$rule_branch->rule_value(5); |
789 |
$rule_branch->rule_value(5); |
788 |
$rule_branch->store(); |
790 |
$rule_branch->store(); |
789 |
|
791 |
|
790 |
$ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber ); |
792 |
$ret = CanItemBeReserved( $patrons[0], $max_holds_item ); |
791 |
is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 5' ); |
793 |
is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 5' ); |
792 |
}; |
794 |
}; |
793 |
|
795 |
|
Lines 795-801
subtest 'Pickup location availability tests' => sub {
Link Here
|
795 |
plan tests => 4; |
797 |
plan tests => 4; |
796 |
|
798 |
|
797 |
$biblio = $builder->build_sample_biblio({ itemtype => 'ONLY1' }); |
799 |
$biblio = $builder->build_sample_biblio({ itemtype => 'ONLY1' }); |
798 |
$itemnumber = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber})->itemnumber; |
800 |
my $pickup_item = $builder->build_sample_item({ library => $branch_1, biblionumber => $biblio->biblionumber}); |
799 |
#Add a default rule to allow some holds |
801 |
#Add a default rule to allow some holds |
800 |
|
802 |
|
801 |
Koha::CirculationRules->set_rules( |
803 |
Koha::CirculationRules->set_rules( |
Lines 809-840
subtest 'Pickup location availability tests' => sub {
Link Here
|
809 |
} |
811 |
} |
810 |
} |
812 |
} |
811 |
); |
813 |
); |
812 |
my $item = Koha::Items->find($itemnumber); |
|
|
813 |
my $branch_to = $builder->build({ source => 'Branch' })->{ branchcode }; |
814 |
my $branch_to = $builder->build({ source => 'Branch' })->{ branchcode }; |
814 |
my $library = Koha::Libraries->find($branch_to); |
815 |
my $library = Koha::Libraries->find($branch_to); |
815 |
$library->pickup_location('1')->store; |
816 |
$library->pickup_location('1')->store; |
816 |
my $patron = $builder->build({ source => 'Borrower' })->{ borrowernumber }; |
817 |
my $patron = $builder->build_object({ class => 'Koha::Patrons' }); |
817 |
|
818 |
|
818 |
t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1); |
819 |
t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1); |
819 |
t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype'); |
820 |
t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype'); |
820 |
|
821 |
|
821 |
$library->pickup_location('1')->store; |
822 |
$library->pickup_location('1')->store; |
822 |
is(CanItemBeReserved($patron, $item->itemnumber, $branch_to)->{status}, |
823 |
is(CanItemBeReserved($patron, $pickup_item, $branch_to)->{status}, |
823 |
'OK', 'Library is a pickup location'); |
824 |
'OK', 'Library is a pickup location'); |
824 |
|
825 |
|
825 |
my $limit = Koha::Item::Transfer::Limit->new({ |
826 |
my $limit = Koha::Item::Transfer::Limit->new({ |
826 |
fromBranch => $item->holdingbranch, |
827 |
fromBranch => $pickup_item->holdingbranch, |
827 |
toBranch => $branch_to, |
828 |
toBranch => $branch_to, |
828 |
itemtype => $item->effective_itemtype, |
829 |
itemtype => $pickup_item->effective_itemtype, |
829 |
})->store; |
830 |
})->store; |
830 |
is(CanItemBeReserved($patron, $item->itemnumber, $branch_to)->{status}, |
831 |
is(CanItemBeReserved($patron, $pickup_item, $branch_to)->{status}, |
831 |
'cannotBeTransferred', 'Item cannot be transferred'); |
832 |
'cannotBeTransferred', 'Item cannot be transferred'); |
832 |
$limit->delete; |
833 |
$limit->delete; |
833 |
|
834 |
|
834 |
$library->pickup_location('0')->store; |
835 |
$library->pickup_location('0')->store; |
835 |
is(CanItemBeReserved($patron, $item->itemnumber, $branch_to)->{status}, |
836 |
is(CanItemBeReserved($patron, $pickup_item, $branch_to)->{status}, |
836 |
'libraryNotPickupLocation', 'Library is not a pickup location'); |
837 |
'libraryNotPickupLocation', 'Library is not a pickup location'); |
837 |
is(CanItemBeReserved($patron, $item->itemnumber, 'nonexistent')->{status}, |
838 |
is(CanItemBeReserved($patron, $pickup_item, 'nonexistent')->{status}, |
838 |
'libraryNotFound', 'Cannot set unknown library as pickup location'); |
839 |
'libraryNotFound', 'Cannot set unknown library as pickup location'); |
839 |
}; |
840 |
}; |
840 |
|
841 |
|
Lines 852-862
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
852 |
|
853 |
|
853 |
# Create 3 biblios with items |
854 |
# Create 3 biblios with items |
854 |
my $biblio_1 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
855 |
my $biblio_1 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
855 |
my $itemnumber_1 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_1->biblionumber})->itemnumber; |
856 |
my $item_1 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_1->biblionumber}); |
856 |
my $biblio_2 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
857 |
my $biblio_2 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
857 |
my $itemnumber_2 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_2->biblionumber})->itemnumber; |
858 |
my $item_2 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_2->biblionumber}); |
858 |
my $biblio_3 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
859 |
my $biblio_3 = $builder->build_sample_biblio({ itemtype => $itemtype->itemtype }); |
859 |
my $itemnumber_3 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_3->biblionumber})->itemnumber; |
860 |
my $item_3 = $builder->build_sample_item({ library => $library->branchcode, biblionumber => $biblio_3->biblionumber}); |
860 |
|
861 |
|
861 |
Koha::CirculationRules->set_rules( |
862 |
Koha::CirculationRules->set_rules( |
862 |
{ |
863 |
{ |
Lines 872-878
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
872 |
); |
873 |
); |
873 |
|
874 |
|
874 |
is_deeply( |
875 |
is_deeply( |
875 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ), |
876 |
CanItemBeReserved( $patron, $item_1 ), |
876 |
{ status => 'OK' }, |
877 |
{ status => 'OK' }, |
877 |
'Patron can reserve item with hold limit of 1, no holds placed' |
878 |
'Patron can reserve item with hold limit of 1, no holds placed' |
878 |
); |
879 |
); |
Lines 887-893
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
887 |
); |
888 |
); |
888 |
|
889 |
|
889 |
is_deeply( |
890 |
is_deeply( |
890 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_1 ), |
891 |
CanItemBeReserved( $patron, $item_1 ), |
891 |
{ status => 'tooManyReserves', limit => 1 }, |
892 |
{ status => 'tooManyReserves', limit => 1 }, |
892 |
'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' |
893 |
'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' |
893 |
); |
894 |
); |
Lines 905-911
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
905 |
); |
906 |
); |
906 |
|
907 |
|
907 |
is_deeply( |
908 |
is_deeply( |
908 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_2 ), |
909 |
CanItemBeReserved( $patron, $item_2 ), |
909 |
{ status => 'OK' }, |
910 |
{ status => 'OK' }, |
910 |
'Patron can reserve item with 2 reserves daily cap' |
911 |
'Patron can reserve item with 2 reserves daily cap' |
911 |
); |
912 |
); |
Lines 920-926
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
920 |
} |
921 |
} |
921 |
); |
922 |
); |
922 |
is_deeply( |
923 |
is_deeply( |
923 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_2 ), |
924 |
CanItemBeReserved( $patron, $item_2 ), |
924 |
{ status => 'tooManyReservesToday', limit => 2 }, |
925 |
{ status => 'tooManyReservesToday', limit => 2 }, |
925 |
'Patron cannot a third item with 2 reserves daily cap' |
926 |
'Patron cannot a third item with 2 reserves daily cap' |
926 |
); |
927 |
); |
Lines 931-937
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
931 |
$hold->reservedate($yesterday)->store; |
932 |
$hold->reservedate($yesterday)->store; |
932 |
|
933 |
|
933 |
is_deeply( |
934 |
is_deeply( |
934 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_2 ), |
935 |
CanItemBeReserved( $patron, $item_2 ), |
935 |
{ status => 'OK' }, |
936 |
{ status => 'OK' }, |
936 |
'Patron can reserve item with 2 bib level hold placed on different days, 2 reserves daily cap' |
937 |
'Patron can reserve item with 2 bib level hold placed on different days, 2 reserves daily cap' |
937 |
); |
938 |
); |
Lines 952-958
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
952 |
# Delete existing holds |
953 |
# Delete existing holds |
953 |
Koha::Holds->search->delete; |
954 |
Koha::Holds->search->delete; |
954 |
is_deeply( |
955 |
is_deeply( |
955 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_2 ), |
956 |
CanItemBeReserved( $patron, $item_2 ), |
956 |
{ status => 'tooManyReservesToday', limit => 0 }, |
957 |
{ status => 'tooManyReservesToday', limit => 0 }, |
957 |
'Patron cannot reserve if holds_per_day is 0 (i.e. 0 is 0)' |
958 |
'Patron cannot reserve if holds_per_day is 0 (i.e. 0 is 0)' |
958 |
); |
959 |
); |
Lines 970-976
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
970 |
|
971 |
|
971 |
Koha::Holds->search->delete; |
972 |
Koha::Holds->search->delete; |
972 |
is_deeply( |
973 |
is_deeply( |
973 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_2 ), |
974 |
CanItemBeReserved( $patron, $item_2 ), |
974 |
{ status => 'OK' }, |
975 |
{ status => 'OK' }, |
975 |
'Patron can reserve if holds_per_day is undef (i.e. undef is unlimited daily cap)' |
976 |
'Patron can reserve if holds_per_day is undef (i.e. undef is unlimited daily cap)' |
976 |
); |
977 |
); |
Lines 992-998
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
992 |
); |
993 |
); |
993 |
|
994 |
|
994 |
is_deeply( |
995 |
is_deeply( |
995 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_3 ), |
996 |
CanItemBeReserved( $patron, $item_3 ), |
996 |
{ status => 'OK' }, |
997 |
{ status => 'OK' }, |
997 |
'Patron can reserve if holds_per_day is undef (i.e. undef is unlimited daily cap)' |
998 |
'Patron can reserve if holds_per_day is undef (i.e. undef is unlimited daily cap)' |
998 |
); |
999 |
); |
Lines 1005-1018
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
1005 |
} |
1006 |
} |
1006 |
); |
1007 |
); |
1007 |
is_deeply( |
1008 |
is_deeply( |
1008 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_3 ), |
1009 |
CanItemBeReserved( $patron, $item_3 ), |
1009 |
{ status => 'tooManyReserves', limit => 3 }, |
1010 |
{ status => 'tooManyReserves', limit => 3 }, |
1010 |
'Unlimited daily holds, but reached reservesallowed' |
1011 |
'Unlimited daily holds, but reached reservesallowed' |
1011 |
); |
1012 |
); |
1012 |
#results should be the same for both ReservesControlBranch settings |
1013 |
#results should be the same for both ReservesControlBranch settings |
1013 |
t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary'); |
1014 |
t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary'); |
1014 |
is_deeply( |
1015 |
is_deeply( |
1015 |
CanItemBeReserved( $patron->borrowernumber, $itemnumber_3 ), |
1016 |
CanItemBeReserved( $patron, $item_3 ), |
1016 |
{ status => 'tooManyReserves', limit => 3 }, |
1017 |
{ status => 'tooManyReserves', limit => 3 }, |
1017 |
'Unlimited daily holds, but reached reservesallowed' |
1018 |
'Unlimited daily holds, but reached reservesallowed' |
1018 |
); |
1019 |
); |
Lines 1079-1085
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1079 |
|
1080 |
|
1080 |
# Test 1: Patron 3 can place hold |
1081 |
# Test 1: Patron 3 can place hold |
1081 |
is_deeply( |
1082 |
is_deeply( |
1082 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1083 |
CanItemBeReserved( $patron3, $item_2 ), |
1083 |
{ status => 'OK' }, |
1084 |
{ status => 'OK' }, |
1084 |
'Patron can place hold if no circ_rules where defined' |
1085 |
'Patron can place hold if no circ_rules where defined' |
1085 |
); |
1086 |
); |
Lines 1099-1112
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1099 |
|
1100 |
|
1100 |
# Test 2: Patron 1 can place hold |
1101 |
# Test 2: Patron 1 can place hold |
1101 |
is_deeply( |
1102 |
is_deeply( |
1102 |
CanItemBeReserved( $patron1->borrowernumber, $itemnumber_2 ), |
1103 |
CanItemBeReserved( $patron1, $item_2 ), |
1103 |
{ status => 'OK' }, |
1104 |
{ status => 'OK' }, |
1104 |
'Patron can place hold because patron\'s home library is part of hold group' |
1105 |
'Patron can place hold because patron\'s home library is part of hold group' |
1105 |
); |
1106 |
); |
1106 |
|
1107 |
|
1107 |
# Test 3: Patron 3 cannot place hold |
1108 |
# Test 3: Patron 3 cannot place hold |
1108 |
is_deeply( |
1109 |
is_deeply( |
1109 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1110 |
CanItemBeReserved( $patron3, $item_2 ), |
1110 |
{ status => 'branchNotInHoldGroup' }, |
1111 |
{ status => 'branchNotInHoldGroup' }, |
1111 |
'Patron cannot place hold because patron\'s home library is not part of hold group' |
1112 |
'Patron cannot place hold because patron\'s home library is not part of hold group' |
1112 |
); |
1113 |
); |
Lines 1126-1132
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1126 |
|
1127 |
|
1127 |
# Test 4: Patron 3 can place hold |
1128 |
# Test 4: Patron 3 can place hold |
1128 |
is_deeply( |
1129 |
is_deeply( |
1129 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1130 |
CanItemBeReserved( $patron3, $item_2 ), |
1130 |
{ status => 'OK' }, |
1131 |
{ status => 'OK' }, |
1131 |
'Patron can place hold if holdallowed is set to "any" for library 2' |
1132 |
'Patron can place hold if holdallowed is set to "any" for library 2' |
1132 |
); |
1133 |
); |
Lines 1146-1152
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1146 |
|
1147 |
|
1147 |
# Test 5: Patron 3 cannot place hold |
1148 |
# Test 5: Patron 3 cannot place hold |
1148 |
is_deeply( |
1149 |
is_deeply( |
1149 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1150 |
CanItemBeReserved( $patron3, $item_2 ), |
1150 |
{ status => 'branchNotInHoldGroup' }, |
1151 |
{ status => 'branchNotInHoldGroup' }, |
1151 |
'Patron cannot place hold if holdallowed is set to "hold group" for library 2' |
1152 |
'Patron cannot place hold if holdallowed is set to "hold group" for library 2' |
1152 |
); |
1153 |
); |
Lines 1166-1172
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1166 |
|
1167 |
|
1167 |
# Test 6: Patron 3 can place hold |
1168 |
# Test 6: Patron 3 can place hold |
1168 |
is_deeply( |
1169 |
is_deeply( |
1169 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1170 |
CanItemBeReserved( $patron3, $item_2 ), |
1170 |
{ status => 'OK' }, |
1171 |
{ status => 'OK' }, |
1171 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2' |
1172 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2' |
1172 |
); |
1173 |
); |
Lines 1186-1192
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1186 |
|
1187 |
|
1187 |
# Test 7: Patron 3 cannot place hold |
1188 |
# Test 7: Patron 3 cannot place hold |
1188 |
is_deeply( |
1189 |
is_deeply( |
1189 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1190 |
CanItemBeReserved( $patron3, $item_2 ), |
1190 |
{ status => 'branchNotInHoldGroup' }, |
1191 |
{ status => 'branchNotInHoldGroup' }, |
1191 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2' |
1192 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2' |
1192 |
); |
1193 |
); |
Lines 1206-1212
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1206 |
|
1207 |
|
1207 |
# Test 8: Patron 3 can place hold |
1208 |
# Test 8: Patron 3 can place hold |
1208 |
is_deeply( |
1209 |
is_deeply( |
1209 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1210 |
CanItemBeReserved( $patron3, $item_2 ), |
1210 |
{ status => 'OK' }, |
1211 |
{ status => 'OK' }, |
1211 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2 and library 2' |
1212 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2 and library 2' |
1212 |
); |
1213 |
); |
Lines 1226-1232
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub {
Link Here
|
1226 |
|
1227 |
|
1227 |
# Test 9: Patron 3 cannot place hold |
1228 |
# Test 9: Patron 3 cannot place hold |
1228 |
is_deeply( |
1229 |
is_deeply( |
1229 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
1230 |
CanItemBeReserved( $patron3, $item_2 ), |
1230 |
{ status => 'branchNotInHoldGroup' }, |
1231 |
{ status => 'branchNotInHoldGroup' }, |
1231 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2 and library 2' |
1232 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2 and library 2' |
1232 |
); |
1233 |
); |
Lines 1293-1299
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1293 |
|
1294 |
|
1294 |
# Test 1: Patron 3 can place hold |
1295 |
# Test 1: Patron 3 can place hold |
1295 |
is_deeply( |
1296 |
is_deeply( |
1296 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1297 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1297 |
{ status => 'OK' }, |
1298 |
{ status => 'OK' }, |
1298 |
'Patron can place hold if no circ_rules where defined' |
1299 |
'Patron can place hold if no circ_rules where defined' |
1299 |
); |
1300 |
); |
Lines 1313-1326
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1313 |
|
1314 |
|
1314 |
# Test 2: Patron 1 can place hold |
1315 |
# Test 2: Patron 1 can place hold |
1315 |
is_deeply( |
1316 |
is_deeply( |
1316 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library1->branchcode ), |
1317 |
CanItemBeReserved( $patron3, $item_2, $library1->branchcode ), |
1317 |
{ status => 'OK' }, |
1318 |
{ status => 'OK' }, |
1318 |
'Patron can place hold because pickup location is part of hold group' |
1319 |
'Patron can place hold because pickup location is part of hold group' |
1319 |
); |
1320 |
); |
1320 |
|
1321 |
|
1321 |
# Test 3: Patron 3 cannot place hold |
1322 |
# Test 3: Patron 3 cannot place hold |
1322 |
is_deeply( |
1323 |
is_deeply( |
1323 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1324 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1324 |
{ status => 'pickupNotInHoldGroup' }, |
1325 |
{ status => 'pickupNotInHoldGroup' }, |
1325 |
'Patron cannot place hold because pickup location is not part of hold group' |
1326 |
'Patron cannot place hold because pickup location is not part of hold group' |
1326 |
); |
1327 |
); |
Lines 1340-1346
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1340 |
|
1341 |
|
1341 |
# Test 4: Patron 3 can place hold |
1342 |
# Test 4: Patron 3 can place hold |
1342 |
is_deeply( |
1343 |
is_deeply( |
1343 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1344 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1344 |
{ status => 'OK' }, |
1345 |
{ status => 'OK' }, |
1345 |
'Patron can place hold if default_branch_circ_rules is set to "any" for library 2' |
1346 |
'Patron can place hold if default_branch_circ_rules is set to "any" for library 2' |
1346 |
); |
1347 |
); |
Lines 1360-1366
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1360 |
|
1361 |
|
1361 |
# Test 5: Patron 3 cannot place hold |
1362 |
# Test 5: Patron 3 cannot place hold |
1362 |
is_deeply( |
1363 |
is_deeply( |
1363 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1364 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1364 |
{ status => 'pickupNotInHoldGroup' }, |
1365 |
{ status => 'pickupNotInHoldGroup' }, |
1365 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for library 2' |
1366 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for library 2' |
1366 |
); |
1367 |
); |
Lines 1380-1386
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1380 |
|
1381 |
|
1381 |
# Test 6: Patron 3 can place hold |
1382 |
# Test 6: Patron 3 can place hold |
1382 |
is_deeply( |
1383 |
is_deeply( |
1383 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1384 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1384 |
{ status => 'OK' }, |
1385 |
{ status => 'OK' }, |
1385 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2' |
1386 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2' |
1386 |
); |
1387 |
); |
Lines 1400-1406
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1400 |
|
1401 |
|
1401 |
# Test 7: Patron 3 cannot place hold |
1402 |
# Test 7: Patron 3 cannot place hold |
1402 |
is_deeply( |
1403 |
is_deeply( |
1403 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1404 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1404 |
{ status => 'pickupNotInHoldGroup' }, |
1405 |
{ status => 'pickupNotInHoldGroup' }, |
1405 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2' |
1406 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2' |
1406 |
); |
1407 |
); |
Lines 1420-1426
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1420 |
|
1421 |
|
1421 |
# Test 8: Patron 3 can place hold |
1422 |
# Test 8: Patron 3 can place hold |
1422 |
is_deeply( |
1423 |
is_deeply( |
1423 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1424 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1424 |
{ status => 'OK' }, |
1425 |
{ status => 'OK' }, |
1425 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2 and library 2' |
1426 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2 and library 2' |
1426 |
); |
1427 |
); |
Lines 1440-1446
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub {
Link Here
|
1440 |
|
1441 |
|
1441 |
# Test 9: Patron 3 cannot place hold |
1442 |
# Test 9: Patron 3 cannot place hold |
1442 |
is_deeply( |
1443 |
is_deeply( |
1443 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
1444 |
CanItemBeReserved( $patron3, $item_2, $library3->branchcode ), |
1444 |
{ status => 'pickupNotInHoldGroup' }, |
1445 |
{ status => 'pickupNotInHoldGroup' }, |
1445 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2 and library 2' |
1446 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2 and library 2' |
1446 |
); |
1447 |
); |
Lines 1574-1580
subtest 'CanItemBeReserved rule precedence tests' => sub {
Link Here
|
1574 |
} |
1575 |
} |
1575 |
); |
1576 |
); |
1576 |
is_deeply( |
1577 |
is_deeply( |
1577 |
CanItemBeReserved( $patron->borrowernumber, $item->itemnumber, $library->branchcode ), |
1578 |
CanItemBeReserved( $patron, $item, $library->branchcode ), |
1578 |
{ status => 'OK' }, |
1579 |
{ status => 'OK' }, |
1579 |
'Patron of specified category can place 1 hold on specified itemtype' |
1580 |
'Patron of specified category can place 1 hold on specified itemtype' |
1580 |
); |
1581 |
); |
Lines 1587-1593
subtest 'CanItemBeReserved rule precedence tests' => sub {
Link Here
|
1587 |
borrowernumber => $patron->borrowernumber, |
1588 |
borrowernumber => $patron->borrowernumber, |
1588 |
}}); |
1589 |
}}); |
1589 |
is_deeply( |
1590 |
is_deeply( |
1590 |
CanItemBeReserved( $patron->borrowernumber, $item->itemnumber, $library->branchcode ), |
1591 |
CanItemBeReserved( $patron, $item, $library->branchcode ), |
1591 |
{ status => 'tooManyReserves', limit => 1 }, |
1592 |
{ status => 'tooManyReserves', limit => 1 }, |
1592 |
'Patron of specified category can place 1 hold on specified itemtype, cannot place a second' |
1593 |
'Patron of specified category can place 1 hold on specified itemtype, cannot place a second' |
1593 |
); |
1594 |
); |
Lines 1602-1608
subtest 'CanItemBeReserved rule precedence tests' => sub {
Link Here
|
1602 |
} |
1603 |
} |
1603 |
); |
1604 |
); |
1604 |
is_deeply( |
1605 |
is_deeply( |
1605 |
CanItemBeReserved( $patron->borrowernumber, $item->itemnumber, $library->branchcode ), |
1606 |
CanItemBeReserved( $patron, $item, $library->branchcode ), |
1606 |
{ status => 'OK' }, |
1607 |
{ status => 'OK' }, |
1607 |
'Patron of specified category can place 1 hold on specified itemtype if library rule for all types and categories set to 2' |
1608 |
'Patron of specified category can place 1 hold on specified itemtype if library rule for all types and categories set to 2' |
1608 |
); |
1609 |
); |