Bug 27069: Adjust tests
[koha.git] / t / db_dependent / Koha / Item.t
1 #!/usr/bin/perl
2
3 # Copyright 2019 Koha Development team
4 #
5 # This file is part of Koha
6 #
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.
11 #
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.
16 #
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>.
19
20 use Modern::Perl;
21
22 use Test::More tests => 8;
23 use Test::Exception;
24
25 use C4::Biblio;
26 use C4::Circulation;
27
28 use Koha::Items;
29 use Koha::Database;
30 use Koha::DateUtils;
31 use Koha::Old::Items;
32
33 use List::MoreUtils qw(all);
34
35 use t::lib::TestBuilder;
36 use t::lib::Mocks;
37
38 my $schema  = Koha::Database->new->schema;
39 my $builder = t::lib::TestBuilder->new;
40
41 subtest 'hidden_in_opac() tests' => sub {
42
43     plan tests => 4;
44
45     $schema->storage->txn_begin;
46
47     my $item  = $builder->build_sample_item({ itemlost => 2 });
48     my $rules = {};
49
50     # disable hidelostitems as it interteres with OpachiddenItems for the calculation
51     t::lib::Mocks::mock_preference( 'hidelostitems', 0 );
52
53     ok( !$item->hidden_in_opac, 'No rules passed, shouldn\'t hide' );
54     ok( !$item->hidden_in_opac({ rules => $rules }), 'Empty rules passed, shouldn\'t hide' );
55
56     # enable hidelostitems to verify correct behaviour
57     t::lib::Mocks::mock_preference( 'hidelostitems', 1 );
58     ok( $item->hidden_in_opac, 'Even with no rules, item should hide because of hidelostitems syspref' );
59
60     # disable hidelostitems
61     t::lib::Mocks::mock_preference( 'hidelostitems', 0 );
62     my $withdrawn = $item->withdrawn + 1; # make sure this attribute doesn't match
63
64     $rules = { withdrawn => [$withdrawn], itype => [ $item->itype ] };
65
66     ok( $item->hidden_in_opac({ rules => $rules }), 'Rule matching itype passed, should hide' );
67
68
69
70     $schema->storage->txn_rollback;
71 };
72
73 subtest 'has_pending_hold() tests' => sub {
74
75     plan tests => 2;
76
77     $schema->storage->txn_begin;
78
79     my $dbh = C4::Context->dbh;
80     my $item  = $builder->build_sample_item({ itemlost => 0 });
81     my $itemnumber = $item->itemnumber;
82
83     $dbh->do("INSERT INTO tmp_holdsqueue (surname,borrowernumber,itemnumber) VALUES ('Clamp',42,$itemnumber)");
84     ok( $item->has_pending_hold, "Yes, we have a pending hold");
85     $dbh->do("DELETE FROM tmp_holdsqueue WHERE itemnumber=$itemnumber");
86     ok( !$item->has_pending_hold, "We don't have a pending hold if nothing in the tmp_holdsqueue");
87
88     $schema->storage->txn_rollback;
89 };
90
91 subtest "as_marc_field() tests" => sub {
92
93     my $mss = C4::Biblio::GetMarcSubfieldStructure( '' );
94
95     my @schema_columns = $schema->resultset('Item')->result_source->columns;
96     my @mapped_columns = grep { exists $mss->{'items.'.$_} } @schema_columns;
97
98     plan tests => 2 * (scalar @mapped_columns + 1) + 2;
99
100     $schema->storage->txn_begin;
101
102     my $item = $builder->build_sample_item;
103     # Make sure it has at least one undefined attribute
104     $item->set({ replacementprice => undef })->store->discard_changes;
105
106     # Tests with the mss parameter
107     my $marc_field = $item->as_marc_field({ mss => $mss });
108
109     is(
110         $marc_field->tag,
111         $mss->{'items.itemnumber'}[0]->{tagfield},
112         'Generated field set the right tag number'
113     );
114
115     foreach my $column ( @mapped_columns ) {
116         my $tagsubfield = $mss->{ 'items.' . $column }[0]->{tagsubfield};
117         is( $marc_field->subfield($tagsubfield),
118             $item->$column, "Value is mapped correctly for column $column" );
119     }
120
121     # Tests without the mss parameter
122     $marc_field = $item->as_marc_field();
123
124     is(
125         $marc_field->tag,
126         $mss->{'items.itemnumber'}[0]->{tagfield},
127         'Generated field set the right tag number'
128     );
129
130     foreach my $column (@mapped_columns) {
131         my $tagsubfield = $mss->{ 'items.' . $column }[0]->{tagsubfield};
132         is( $marc_field->subfield($tagsubfield),
133             $item->$column, "Value is mapped correctly for column $column" );
134     }
135
136     my $unmapped_subfield = Koha::MarcSubfieldStructure->new(
137         {
138             frameworkcode => '',
139             tagfield      => $mss->{'items.itemnumber'}[0]->{tagfield},
140             tagsubfield   => 'X',
141         }
142     )->store;
143
144     $mss = C4::Biblio::GetMarcSubfieldStructure( '' );
145     my @unlinked_subfields;
146     push @unlinked_subfields, X => 'Something weird';
147     $item->more_subfields_xml( C4::Items::_get_unlinked_subfields_xml( \@unlinked_subfields ) )->store;
148
149     $marc_field = $item->as_marc_field;
150
151     my @subfields = $marc_field->subfields;
152     my $result = all { defined $_->[1] } @subfields;
153     ok( $result, 'There are no undef subfields' );
154
155     is( scalar $marc_field->subfield('X'), 'Something weird', 'more_subfield_xml is considered' );
156
157     $schema->storage->txn_rollback;
158 };
159
160 subtest 'pickup_locations' => sub {
161     plan tests => 66;
162
163     $schema->storage->txn_begin;
164
165     my $dbh = C4::Context->dbh;
166
167     my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1, branchcode => undef } } );
168     my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1, branchcode => undef } } );
169     my $library1 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, } } );
170     my $library2 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, } } );
171     my $library3 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0, } } );
172     my $library4 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, } } );
173     my $group1_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } );
174     my $group1_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } );
175
176     my $group2_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } );
177     my $group2_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } );
178
179     our @branchcodes = (
180         $library1->branchcode, $library2->branchcode,
181         $library3->branchcode, $library4->branchcode
182     );
183
184     my $item1 = $builder->build_sample_item(
185         {
186             homebranch    => $library1->branchcode,
187             holdingbranch => $library2->branchcode,
188             copynumber    => 1,
189             ccode         => 'Gollum'
190         }
191     )->store;
192
193     my $item3 = $builder->build_sample_item(
194         {
195             homebranch    => $library3->branchcode,
196             holdingbranch => $library4->branchcode,
197             copynumber    => 3,
198             itype         => $item1->itype,
199         }
200     )->store;
201
202     Koha::CirculationRules->set_rules(
203         {
204             categorycode => undef,
205             itemtype     => $item1->itype,
206             branchcode   => undef,
207             rules        => {
208                 reservesallowed => 25,
209             }
210         }
211     );
212
213
214     my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library1->branchcode, firstname => '1' } } );
215     my $patron4 = $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library4->branchcode, firstname => '4' } } );
216
217     my $results = {
218         "1-1-from_home_library-any"               => 3,
219         "1-1-from_home_library-holdgroup"         => 2,
220         "1-1-from_home_library-patrongroup"       => 2,
221         "1-1-from_home_library-homebranch"        => 1,
222         "1-1-from_home_library-holdingbranch"     => 1,
223         "1-1-from_any_library-any"                => 3,
224         "1-1-from_any_library-holdgroup"          => 2,
225         "1-1-from_any_library-patrongroup"        => 2,
226         "1-1-from_any_library-homebranch"         => 1,
227         "1-1-from_any_library-holdingbranch"      => 1,
228         "1-1-from_local_hold_group-any"           => 3,
229         "1-1-from_local_hold_group-holdgroup"     => 2,
230         "1-1-from_local_hold_group-patrongroup"   => 2,
231         "1-1-from_local_hold_group-homebranch"    => 1,
232         "1-1-from_local_hold_group-holdingbranch" => 1,
233         "1-4-from_home_library-any"               => 0,
234         "1-4-from_home_library-holdgroup"         => 0,
235         "1-4-from_home_library-patrongroup"       => 0,
236         "1-4-from_home_library-homebranch"        => 0,
237         "1-4-from_home_library-holdingbranch"     => 0,
238         "1-4-from_any_library-any"                => 3,
239         "1-4-from_any_library-holdgroup"          => 2,
240         "1-4-from_any_library-patrongroup"        => 1,
241         "1-4-from_any_library-homebranch"         => 1,
242         "1-4-from_any_library-holdingbranch"      => 1,
243         "1-4-from_local_hold_group-any"           => 0,
244         "1-4-from_local_hold_group-holdgroup"     => 0,
245         "1-4-from_local_hold_group-patrongroup"   => 0,
246         "1-4-from_local_hold_group-homebranch"    => 0,
247         "1-4-from_local_hold_group-holdingbranch" => 0,
248         "3-1-from_home_library-any"               => 0,
249         "3-1-from_home_library-holdgroup"         => 0,
250         "3-1-from_home_library-patrongroup"       => 0,
251         "3-1-from_home_library-homebranch"        => 0,
252         "3-1-from_home_library-holdingbranch"     => 0,
253         "3-1-from_any_library-any"                => 3,
254         "3-1-from_any_library-holdgroup"          => 1,
255         "3-1-from_any_library-patrongroup"        => 2,
256         "3-1-from_any_library-homebranch"         => 0,
257         "3-1-from_any_library-holdingbranch"      => 1,
258         "3-1-from_local_hold_group-any"           => 0,
259         "3-1-from_local_hold_group-holdgroup"     => 0,
260         "3-1-from_local_hold_group-patrongroup"   => 0,
261         "3-1-from_local_hold_group-homebranch"    => 0,
262         "3-1-from_local_hold_group-holdingbranch" => 0,
263         "3-4-from_home_library-any"               => 0,
264         "3-4-from_home_library-holdgroup"         => 0,
265         "3-4-from_home_library-patrongroup"       => 0,
266         "3-4-from_home_library-homebranch"        => 0,
267         "3-4-from_home_library-holdingbranch"     => 0,
268         "3-4-from_any_library-any"                => 3,
269         "3-4-from_any_library-holdgroup"          => 1,
270         "3-4-from_any_library-patrongroup"        => 1,
271         "3-4-from_any_library-homebranch"         => 0,
272         "3-4-from_any_library-holdingbranch"      => 1,
273         "3-4-from_local_hold_group-any"           => 3,
274         "3-4-from_local_hold_group-holdgroup"     => 1,
275         "3-4-from_local_hold_group-patrongroup"   => 1,
276         "3-4-from_local_hold_group-homebranch"    => 0,
277         "3-4-from_local_hold_group-holdingbranch" => 1
278     };
279
280     sub _doTest {
281         my ( $item, $patron, $ha, $hfp, $results ) = @_;
282
283         Koha::CirculationRules->set_rules(
284             {
285                 branchcode => undef,
286                 itemtype   => undef,
287                 rules => {
288                     holdallowed => $ha,
289                     hold_fulfillment_policy => $hfp,
290                     returnbranch => 'any'
291                 }
292             }
293         );
294         my $ha_value =
295           $ha eq 'from_local_hold_group' ? 'holdgroup'
296           : (
297             $ha eq 'from_any_library' ? 'any'
298             : 'homebranch'
299           );
300
301         my @pl = map {
302             my $pickup_location = $_;
303             grep { $pickup_location->branchcode eq $_ } @branchcodes
304         } $item->pickup_locations( { patron => $patron } )->as_list;
305
306         ok(
307             scalar(@pl) eq $results->{
308                     $item->copynumber . '-'
309                   . $patron->firstname . '-'
310                   . $ha . '-'
311                   . $hfp
312             },
313             'item'
314               . $item->copynumber
315               . ', patron'
316               . $patron->firstname
317               . ', holdallowed: '
318               . $ha_value
319               . ', hold_fulfillment_policy: '
320               . $hfp
321               . ' should return '
322               . $results->{
323                     $item->copynumber . '-'
324                   . $patron->firstname . '-'
325                   . $ha . '-'
326                   . $hfp
327               }
328               . ' and returns '
329               . scalar(@pl)
330         );
331
332     }
333
334
335     foreach my $item ($item1, $item3) {
336         foreach my $patron ($patron1, $patron4) {
337             #holdallowed 1: homebranch, 2: any, 3: holdgroup
338             foreach my $ha ('from_home_library', 'from_any_library', 'from_local_hold_group') {
339                 foreach my $hfp ('any', 'holdgroup', 'patrongroup', 'homebranch', 'holdingbranch') {
340                     _doTest($item, $patron, $ha, $hfp, $results);
341                 }
342             }
343         }
344     }
345
346     # Now test that branchtransferlimits will further filter the pickup locations
347
348     my $item_no_ccode = $builder->build_sample_item(
349         {
350             homebranch    => $library1->branchcode,
351             holdingbranch => $library2->branchcode,
352             itype         => $item1->itype,
353         }
354     )->store;
355
356     t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1);
357     t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
358     Koha::CirculationRules->set_rules(
359         {
360             branchcode => undef,
361             itemtype   => $item1->itype,
362             rules      => {
363                 holdallowed             => 'from_home_library',
364                 hold_fulfillment_policy => 1,
365                 returnbranch            => 'any'
366             }
367         }
368     );
369     $builder->build_object(
370         {
371             class => 'Koha::Item::Transfer::Limits',
372             value => {
373                 toBranch   => $library1->branchcode,
374                 fromBranch => $library2->branchcode,
375                 itemtype   => $item1->itype,
376                 ccode      => undef,
377             }
378         }
379     );
380
381     my @pickup_locations = map {
382         my $pickup_location = $_;
383         grep { $pickup_location->branchcode eq $_ } @branchcodes
384     } $item1->pickup_locations( { patron => $patron1 } )->as_list;
385
386     is( scalar @pickup_locations, 3 - 1, "With a transfer limits we get back the libraries that are pickup locations minus 1 limited library");
387
388     $builder->build_object(
389         {
390             class => 'Koha::Item::Transfer::Limits',
391             value => {
392                 toBranch   => $library4->branchcode,
393                 fromBranch => $library2->branchcode,
394                 itemtype   => $item1->itype,
395                 ccode      => undef,
396             }
397         }
398     );
399
400     @pickup_locations = map {
401         my $pickup_location = $_;
402         grep { $pickup_location->branchcode eq $_ } @branchcodes
403     } $item1->pickup_locations( { patron => $patron1 } )->as_list;
404
405     is( scalar @pickup_locations, 3 - 2, "With 2 transfer limits we get back the libraries that are pickup locations minus 2 limited libraries");
406
407     t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'ccode');
408     @pickup_locations = map {
409         my $pickup_location = $_;
410         grep { $pickup_location->branchcode eq $_ } @branchcodes
411     } $item1->pickup_locations( { patron => $patron1 } )->as_list;
412     is( scalar @pickup_locations, 3, "With no transfer limits of type ccode we get back the libraries that are pickup locations");
413
414     @pickup_locations = map {
415         my $pickup_location = $_;
416         grep { $pickup_location->branchcode eq $_ } @branchcodes
417     } $item_no_ccode->pickup_locations( { patron => $patron1 } )->as_list;
418     is( scalar @pickup_locations, 3, "With no transfer limits of type ccode and an item with no ccode we get back the libraries that are pickup locations");
419
420     $builder->build_object(
421         {
422             class => 'Koha::Item::Transfer::Limits',
423             value => {
424                 toBranch   => $library2->branchcode,
425                 fromBranch => $library2->branchcode,
426                 itemtype   => undef,
427                 ccode      => $item1->ccode,
428             }
429         }
430     );
431
432     @pickup_locations = map {
433         my $pickup_location = $_;
434         grep { $pickup_location->branchcode eq $_ } @branchcodes
435     } $item1->pickup_locations( { patron => $patron1 } )->as_list;
436     is( scalar @pickup_locations, 3 - 1, "With a transfer limits we get back the libraries that are pickup locations minus 1 limited library");
437
438     $builder->build_object(
439         {
440             class => 'Koha::Item::Transfer::Limits',
441             value => {
442                 toBranch   => $library4->branchcode,
443                 fromBranch => $library2->branchcode,
444                 itemtype   => undef,
445                 ccode      => $item1->ccode,
446             }
447         }
448     );
449
450     @pickup_locations = map {
451         my $pickup_location = $_;
452         grep { $pickup_location->branchcode eq $_ } @branchcodes
453     } $item1->pickup_locations( { patron => $patron1 } )->as_list;
454     is( scalar @pickup_locations, 3 - 2, "With 2 transfer limits we get back the libraries that are pickup locations minus 2 limited libraries");
455
456     t::lib::Mocks::mock_preference('UseBranchTransferLimits', 0);
457
458     $schema->storage->txn_rollback;
459 };
460
461 subtest 'request_transfer' => sub {
462     plan tests => 7;
463     $schema->storage->txn_begin;
464
465     my $library1 = $builder->build_object( { class => 'Koha::Libraries' } );
466     my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
467     my $item     = $builder->build_sample_item(
468         {
469             homebranch    => $library1->branchcode,
470             holdingbranch => $library2->branchcode,
471         }
472     );
473
474     # Mandatory fields tests
475     throws_ok { $item->request_transfer( { to => $library1 } ) }
476     'Koha::Exceptions::MissingParameter',
477       'Exception thrown if `reason` parameter is missing';
478
479     throws_ok { $item->request_transfer( { reason => 'Manual' } ) }
480     'Koha::Exceptions::MissingParameter',
481       'Exception thrown if `to` parameter is missing';
482
483     # Successful request
484     my $transfer = $item->request_transfer({ to => $library1, reason => 'Manual' });
485     is( ref($transfer), 'Koha::Item::Transfer',
486         'Koha::Item->request_transfer should return a Koha::Item::Transfer object'
487     );
488
489     # Transfer already in progress
490     throws_ok { $item->request_transfer( { to => $library2, reason => 'Manual' } ) }
491     'Koha::Exceptions::Item::Transfer::InQueue',
492       'Exception thrown if transfer is already in progress';
493
494     my $exception = $@;
495     is( ref( $exception->transfer ),
496         'Koha::Item::Transfer',
497         'The exception contains the found Koha::Item::Transfer' );
498
499     $transfer->datearrived(dt_from_string)->store();
500
501     # BranchTransferLimits
502     t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1);
503     t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
504     my $limit = Koha::Item::Transfer::Limit->new({
505         fromBranch => $library2->branchcode,
506         toBranch => $library1->branchcode,
507         itemtype => $item->effective_itemtype,
508     })->store;
509
510     throws_ok { $item->request_transfer( { to => $library1, reason => 'Manual' } ) }
511     'Koha::Exceptions::Item::Transfer::Limit',
512       'Exception thrown if transfer is prevented by limits';
513
514     my $forced_transfer = $item->request_transfer( { to => $library1, reason => 'Manual', ignore_limits => 1 } );
515     is( ref($forced_transfer), 'Koha::Item::Transfer',
516         'Koha::Item->request_transfer allowed when forced'
517     );
518
519     $schema->storage->txn_rollback;
520 };
521
522 subtest 'deletion' => sub {
523     plan tests => 12;
524
525     $schema->storage->txn_begin;
526
527     my $biblio = $builder->build_sample_biblio();
528
529     my $item = $builder->build_sample_item(
530         {
531             biblionumber => $biblio->biblionumber,
532         }
533     );
534
535     is( ref( $item->move_to_deleted ), 'Koha::Schema::Result::Deleteditem', 'Koha::Item->move_to_deleted should return the Deleted item' )
536       ;    # FIXME This should be Koha::Deleted::Item
537     is( Koha::Old::Items->search({itemnumber => $item->itemnumber})->count, 1, '->move_to_deleted must have moved the item to deleteditem' );
538     $item = $builder->build_sample_item(
539         {
540             biblionumber => $biblio->biblionumber,
541         }
542     );
543     $item->delete;
544     is( Koha::Old::Items->search({itemnumber => $item->itemnumber})->count, 0, '->move_to_deleted must not have moved the item to deleteditem' );
545
546
547     my $library   = $builder->build_object({ class => 'Koha::Libraries' });
548     my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
549     t::lib::Mocks::mock_userenv({ branchcode => $library->branchcode });
550
551     my $patron = $builder->build_object({class => 'Koha::Patrons'});
552     $item = $builder->build_sample_item({ library => $library->branchcode });
553
554     # book_on_loan
555     C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
556
557     is(
558         $item->safe_to_delete,
559         'book_on_loan',
560         'Koha::Item->safe_to_delete reports item on loan',
561     );
562
563     is(
564         $item->safe_delete,
565         'book_on_loan',
566         'item that is on loan cannot be deleted',
567     );
568
569     AddReturn( $item->barcode, $library->branchcode );
570
571     # book_reserved is tested in t/db_dependent/Reserves.t
572
573     # not_same_branch
574     t::lib::Mocks::mock_preference('IndependentBranches', 1);
575     my $item_2 = $builder->build_sample_item({ library => $library_2->branchcode });
576
577     is(
578         $item_2->safe_to_delete,
579         'not_same_branch',
580         'Koha::Item->safe_to_delete reports IndependentBranches restriction',
581     );
582
583     is(
584         $item_2->safe_delete,
585         'not_same_branch',
586         'IndependentBranches prevents deletion at another branch',
587     );
588
589     # linked_analytics
590
591     { # codeblock to limit scope of $module->mock
592
593         my $module = Test::MockModule->new('C4::Items');
594         $module->mock( GetAnalyticsCount => sub { return 1 } );
595
596         $item->discard_changes;
597         is(
598             $item->safe_to_delete,
599             'linked_analytics',
600             'Koha::Item->safe_to_delete reports linked analytics',
601         );
602
603         is(
604             $item->safe_delete,
605             'linked_analytics',
606             'Linked analytics prevents deletion of item',
607         );
608
609     }
610
611     { # last_item_for_hold
612         C4::Reserves::AddReserve({ branchcode => $patron->branchcode, borrowernumber => $patron->borrowernumber, biblionumber => $item->biblionumber });
613         is( $item->safe_to_delete, 'last_item_for_hold', 'Item cannot be deleted if a biblio-level is placed on the biblio and there is only 1 item attached to the biblio' );
614
615         # With another item attached to the biblio, the item can be deleted
616         $builder->build_sample_item({ biblionumber => $item->biblionumber });
617     }
618
619     is(
620         $item->safe_to_delete,
621         1,
622         'Koha::Item->safe_to_delete shows item safe to delete'
623     );
624
625     $item->safe_delete,
626
627     my $test_item = Koha::Items->find( $item->itemnumber );
628
629     is( $test_item, undef,
630         "Koha::Item->safe_delete should delete item if safe_to_delete returns true"
631     );
632
633     $schema->storage->txn_rollback;
634 };
635
636 subtest 'renewal_branchcode' => sub {
637     plan tests => 13;
638
639     $schema->storage->txn_begin;
640
641     my $item = $builder->build_sample_item();
642     my $branch = $builder->build_object({ class => 'Koha::Libraries' });
643     my $checkout = $builder->build_object({
644         class => 'Koha::Checkouts',
645         value => {
646             itemnumber => $item->itemnumber,
647         }
648     });
649
650
651     C4::Context->interface( 'intranet' );
652     t::lib::Mocks::mock_userenv({ branchcode => $branch->branchcode });
653
654     is( $item->renewal_branchcode, $branch->branchcode, "If interface not opac, we get the branch from context");
655     is( $item->renewal_branchcode({ branch => "PANDA"}), $branch->branchcode, "If interface not opac, we get the branch from context even if we pass one in");
656     C4::Context->set_userenv(51, 'userid4tests', undef, 'firstname', 'surname', undef, undef, 0, undef, undef, undef ); #mock userenv doesn't let us set null branch
657     is( $item->renewal_branchcode({ branch => "PANDA"}), "PANDA", "If interface not opac, we get the branch we pass one in if context not set");
658
659     C4::Context->interface( 'opac' );
660
661     t::lib::Mocks::mock_preference('OpacRenewalBranch', undef);
662     is( $item->renewal_branchcode, 'OPACRenew', "If interface opac and OpacRenewalBranch undef, we get OPACRenew");
663     is( $item->renewal_branchcode({branch=>'COW'}), 'OPACRenew', "If interface opac and OpacRenewalBranch undef, we get OPACRenew even if branch passed");
664
665     t::lib::Mocks::mock_preference('OpacRenewalBranch', 'none');
666     is( $item->renewal_branchcode, '', "If interface opac and OpacRenewalBranch is none, we get blank string");
667     is( $item->renewal_branchcode({branch=>'COW'}), '', "If interface opac and OpacRenewalBranch is none, we get blank string even if branch passed");
668
669     t::lib::Mocks::mock_preference('OpacRenewalBranch', 'checkoutbranch');
670     is( $item->renewal_branchcode, $checkout->branchcode, "If interface opac and OpacRenewalBranch set to checkoutbranch, we get branch of checkout");
671     is( $item->renewal_branchcode({branch=>'MONKEY'}), $checkout->branchcode, "If interface opac and OpacRenewalBranch set to checkoutbranch, we get branch of checkout even if branch passed");
672
673     t::lib::Mocks::mock_preference('OpacRenewalBranch','patronhomebranch');
674     is( $item->renewal_branchcode, $checkout->patron->branchcode, "If interface opac and OpacRenewalBranch set to patronbranch, we get branch of patron");
675     is( $item->renewal_branchcode({branch=>'TURKEY'}), $checkout->patron->branchcode, "If interface opac and OpacRenewalBranch set to patronbranch, we get branch of patron even if branch passed");
676
677     t::lib::Mocks::mock_preference('OpacRenewalBranch','itemhomebranch');
678     is( $item->renewal_branchcode, $item->homebranch, "If interface opac and OpacRenewalBranch set to itemhomebranch, we get homebranch of item");
679     is( $item->renewal_branchcode({branch=>'MANATEE'}), $item->homebranch, "If interface opac and OpacRenewalBranch set to itemhomebranch, we get homebranch of item even if branch passed");
680
681     $schema->storage->txn_rollback;
682 };
683
684 subtest 'Tests for itemtype' => sub {
685     plan tests => 2;
686     $schema->storage->txn_begin;
687
688     my $biblio = $builder->build_sample_biblio;
689     my $itemtype = $builder->build_object({ class => 'Koha::ItemTypes' });
690     my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, itype => $itemtype->itemtype });
691
692     t::lib::Mocks::mock_preference('item-level_itypes', 1);
693     is( $item->itemtype->itemtype, $item->itype, 'Pref enabled' );
694     t::lib::Mocks::mock_preference('item-level_itypes', 0);
695     is( $item->itemtype->itemtype, $biblio->biblioitem->itemtype, 'Pref disabled' );
696
697     $schema->storage->txn_rollback;
698 };