3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use Test::More tests => 34;
24 use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc );
25 use C4::Circulation qw( AddIssue AddReturn );
28 use Koha::DateUtils qw( dt_from_string );
29 use Koha::Cache::Memory::Lite;
31 use Koha::Acquisition::Orders;
32 use Koha::AuthorisedValueCategories;
33 use Koha::AuthorisedValues;
34 use Koha::MarcSubfieldStructures;
40 use t::lib::TestBuilder;
45 use_ok('Koha::Biblio');
46 use_ok('Koha::Biblios');
49 my $schema = Koha::Database->new->schema;
50 my $builder = t::lib::TestBuilder->new;
52 subtest 'metadata() tests' => sub {
56 $schema->storage->txn_begin;
58 my $title = 'Oranges and Peaches';
60 my $record = MARC::Record->new();
61 my $field = MARC::Field->new('245','','','a' => $title);
62 $record->append_fields( $field );
63 my ($biblionumber) = C4::Biblio::AddBiblio($record, '');
65 my $biblio = Koha::Biblios->find( $biblionumber );
66 is( ref $biblio, 'Koha::Biblio', 'Found a Koha::Biblio object' );
68 my $metadata = $biblio->metadata;
69 is( ref $metadata, 'Koha::Biblio::Metadata', 'Method metadata() returned a Koha::Biblio::Metadata object' );
71 my $record2 = $metadata->record;
72 is( ref $record2, 'MARC::Record', 'Method record() returned a MARC::Record object' );
74 is( $record2->field('245')->subfield("a"), $title, 'Title in 245$a matches title from original record object' );
76 $schema->storage->txn_rollback;
79 subtest 'hidden_in_opac() tests' => sub {
83 $schema->storage->txn_begin;
85 my $biblio = $builder->build_sample_biblio();
86 my $rules = { withdrawn => [ 2 ] };
88 t::lib::Mocks::mock_preference( 'OpacHiddenItemsHidesRecord', 0 );
91 !$biblio->hidden_in_opac({ rules => $rules }),
92 'Biblio not hidden if there is no item attached (!OpacHiddenItemsHidesRecord)'
95 t::lib::Mocks::mock_preference( 'OpacHiddenItemsHidesRecord', 1 );
98 !$biblio->hidden_in_opac({ rules => $rules }),
99 'Biblio not hidden if there is no item attached (OpacHiddenItemsHidesRecord)'
102 my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
103 my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
105 $item_1->withdrawn( 1 )->store->discard_changes;
106 $item_2->withdrawn( 1 )->store->discard_changes;
108 ok( !$biblio->hidden_in_opac({ rules => $rules }), 'Biblio not hidden' );
110 $item_2->withdrawn( 2 )->store->discard_changes;
111 $biblio->discard_changes; # refresh
113 ok( !$biblio->hidden_in_opac({ rules => $rules }), 'Biblio not hidden' );
115 $item_1->withdrawn( 2 )->store->discard_changes;
116 $biblio->discard_changes; # refresh
118 ok( $biblio->hidden_in_opac({ rules => $rules }), 'Biblio hidden' );
120 t::lib::Mocks::mock_preference( 'OpacHiddenItemsHidesRecord', 0 );
122 !$biblio->hidden_in_opac( { rules => $rules } ),
123 'Biblio hidden (!OpacHiddenItemsHidesRecord)'
127 $schema->storage->txn_rollback;
130 subtest 'items() tests' => sub {
134 $schema->storage->txn_begin;
136 my $biblio = $builder->build_sample_biblio();
138 is( $biblio->items->count, 0, 'No items, count is 0' );
140 my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
141 my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
143 my $items = $biblio->items;
144 is( ref($items), 'Koha::Items', 'Returns a Koha::Items resultset' );
145 is( $items->count, 2, 'Two items in resultset' );
147 $schema->storage->txn_rollback;
151 subtest 'bookable_items() tests' => sub {
154 $schema->storage->txn_begin;
156 my $biblio = $builder->build_sample_biblio();
159 my $bookable_item1 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, bookable => 1 } );
162 my $non_bookable_item1 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, bookable => 0 } );
163 my $non_bookable_item2 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, bookable => 0 } );
165 is( ref( $biblio->bookable_items ), 'Koha::Items', "bookable_items returns a Koha::Items resultset" );
166 is( $biblio->bookable_items->count, 1, "bookable_items returns the correct number of items" );
168 $biblio->bookable_items->next->itemnumber, $bookable_item1->itemnumber,
169 "bookable_items returned the correct item"
172 $schema->storage->txn_rollback;
175 subtest 'get_coins and get_openurl' => sub {
179 $schema->storage->txn_begin;
181 my $builder = t::lib::TestBuilder->new;
182 my $biblio = $builder->build_sample_biblio({
188 'ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rft.genre=book&rft.btitle=Title%201&rft.au=Author%201',
189 'GetCOinsBiblio returned right metadata'
192 my $record = MARC::Record->new();
193 $record->append_fields( MARC::Field->new('100','','','a' => 'Author 2'), MARC::Field->new('880','','','a' => 'Something') );
194 my ( $biblionumber ) = C4::Biblio::AddBiblio($record, '');
195 my $biblio_no_title = Koha::Biblios->find($biblionumber);
197 $biblio_no_title->get_coins,
198 'ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rft.genre=book&rft.au=Author%202',
199 'GetCOinsBiblio returned right metadata if biblio does not have a title'
202 t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/");
204 $biblio->get_openurl,
205 'https://koha.example.com/?ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rft.genre=book&rft.btitle=Title%201&rft.au=Author%201',
206 'Koha::Biblio->get_openurl returned right URL'
209 t::lib::Mocks::mock_preference("OpenURLResolverURL", "https://koha.example.com/?client_id=ci1");
211 $biblio->get_openurl,
212 'https://koha.example.com/?client_id=ci1&ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rft.genre=book&rft.btitle=Title%201&rft.au=Author%201',
213 'Koha::Biblio->get_openurl returned right URL'
216 $schema->storage->txn_rollback;
219 subtest 'is_serial() tests' => sub {
223 $schema->storage->txn_begin;
225 my $biblio = $builder->build_sample_biblio();
227 $biblio->serial( 1 )->store->discard_changes;
228 ok( $biblio->is_serial, 'Bibliographic record is serial' );
230 $biblio->serial( 0 )->store->discard_changes;
231 ok( !$biblio->is_serial, 'Bibliographic record is not serial' );
233 my $record = $biblio->metadata->record;
234 $record->leader('00142nas a22 7a 4500');
235 ModBiblio($record, $biblio->biblionumber );
236 $biblio = Koha::Biblios->find($biblio->biblionumber);
238 ok( $biblio->is_serial, 'Bibliographic record is serial' );
240 $schema->storage->txn_rollback;
243 subtest 'pickup_locations() tests' => sub {
247 $schema->storage->txn_begin;
249 Koha::CirculationRules->search->delete;
250 Koha::CirculationRules->set_rules(
252 categorycode => undef,
256 reservesallowed => 25,
261 my $root1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
262 my $root2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
263 my $root3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { ft_local_hold_group => 1 } } );
265 my $library1 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'zzz' } } );
266 my $library2 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'AAA' } } );
267 my $library3 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0, branchname => 'FFF' } } );
268 my $library4 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'CCC' } } );
269 my $library5 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'eee' } } );
270 my $library6 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'BBB' } } );
271 my $library7 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1, branchname => 'DDD' } } );
272 my $library8 = $builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 0, branchname => 'GGG' } } );
274 our @branchcodes = map { $_->branchcode } ($library1, $library2, $library3, $library4, $library5, $library6, $library7, $library8);
276 Koha::CirculationRules->set_rules(
278 branchcode => $library1->branchcode,
281 holdallowed => 'from_home_library',
282 hold_fulfillment_policy => 'any',
283 returnbranch => 'any'
288 Koha::CirculationRules->set_rules(
290 branchcode => $library2->branchcode,
293 holdallowed => 'from_local_hold_group',
294 hold_fulfillment_policy => 'holdgroup',
295 returnbranch => 'any'
300 Koha::CirculationRules->set_rules(
302 branchcode => $library3->branchcode,
305 holdallowed => 'from_local_hold_group',
306 hold_fulfillment_policy => 'patrongroup',
307 returnbranch => 'any'
312 Koha::CirculationRules->set_rules(
314 branchcode => $library4->branchcode,
317 holdallowed => 'from_any_library',
318 hold_fulfillment_policy => 'holdingbranch',
319 returnbranch => 'any'
324 Koha::CirculationRules->set_rules(
326 branchcode => $library5->branchcode,
329 holdallowed => 'from_any_library',
330 hold_fulfillment_policy => 'homebranch',
331 returnbranch => 'any'
336 Koha::CirculationRules->set_rules(
338 branchcode => $library6->branchcode,
341 holdallowed => 'from_home_library',
342 hold_fulfillment_policy => 'holdgroup',
343 returnbranch => 'any'
348 Koha::CirculationRules->set_rules(
350 branchcode => $library7->branchcode,
353 holdallowed => 'from_local_hold_group',
354 hold_fulfillment_policy => 'holdingbranch',
355 returnbranch => 'any'
361 Koha::CirculationRules->set_rules(
363 branchcode => $library8->branchcode,
366 holdallowed => 'from_any_library',
367 hold_fulfillment_policy => 'patrongroup',
368 returnbranch => 'any'
373 my $group1_1 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library1->branchcode } } );
374 my $group1_2 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root1->id, branchcode => $library2->branchcode } } );
376 my $group2_3 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library3->branchcode } } );
377 my $group2_4 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root2->id, branchcode => $library4->branchcode } } );
379 my $group3_5 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library5->branchcode } } );
380 my $group3_6 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library6->branchcode } } );
381 my $group3_7 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library7->branchcode } } );
382 my $group3_8 = $builder->build_object( { class => 'Koha::Library::Groups', value => { parent_id => $root3->id, branchcode => $library8->branchcode } } );
384 my $biblio1 = $builder->build_sample_biblio({ title => '1' });
385 my $biblio2 = $builder->build_sample_biblio({ title => '2' });
388 { $biblio1->pickup_locations }
389 'Koha::Exceptions::MissingParameter',
390 'Exception thrown on missing parameter';
392 is( $@->parameter, 'patron', 'Exception param correctly set' );
394 my $item1_1 = $builder->build_sample_item({
395 biblionumber => $biblio1->biblionumber,
396 homebranch => $library1->branchcode,
397 holdingbranch => $library2->branchcode,
400 my $item1_3 = $builder->build_sample_item({
401 biblionumber => $biblio1->biblionumber,
402 homebranch => $library3->branchcode,
403 holdingbranch => $library4->branchcode,
406 my $item1_7 = $builder->build_sample_item({
407 biblionumber => $biblio1->biblionumber,
408 homebranch => $library7->branchcode,
409 holdingbranch => $library4->branchcode,
412 my $item2_2 = $builder->build_sample_item({
413 biblionumber => $biblio2->biblionumber,
414 homebranch => $library2->branchcode,
415 holdingbranch => $library1->branchcode,
418 my $item2_4 = $builder->build_sample_item({
419 biblionumber => $biblio2->biblionumber,
420 homebranch => $library4->branchcode,
421 holdingbranch => $library3->branchcode,
424 my $item2_6 = $builder->build_sample_item({
425 biblionumber => $biblio2->biblionumber,
426 homebranch => $library6->branchcode,
427 holdingbranch => $library4->branchcode,
430 my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'1', branchcode => $library1->branchcode } } );
431 my $patron8 = $builder->build_object( { class => 'Koha::Patrons', value => { firstname=>'8', branchcode => $library8->branchcode } } );
434 "ItemHomeLibrary-1-1" => 6,
435 "ItemHomeLibrary-1-8" => 1,
436 "ItemHomeLibrary-2-1" => 2,
437 "ItemHomeLibrary-2-8" => 0,
438 "PatronLibrary-1-1" => 6,
439 "PatronLibrary-1-8" => 3,
440 "PatronLibrary-2-1" => 0,
441 "PatronLibrary-2-8" => 3,
445 my ( $cbranch, $biblio, $patron, $results ) = @_;
446 t::lib::Mocks::mock_preference('ReservesControlBranch', $cbranch);
449 my $pickup_location = $_;
450 grep { $pickup_location->branchcode eq $_ } @branchcodes
451 } $biblio->pickup_locations( { patron => $patron } )->as_list;
454 scalar(@pl) == $results->{ $cbranch . '-'
455 . $biblio->title . '-'
456 . $patron->firstname },
457 'ReservesControlBranch: '
464 . $results->{ $cbranch . '-'
465 . $biblio->title . '-'
466 . $patron->firstname }
472 foreach my $cbranch ('ItemHomeLibrary','PatronLibrary') {
473 my $cache = Koha::Cache::Memory::Lite->get_instance();
474 $cache->flush(); # needed since we change ReservesControlBranch
475 foreach my $biblio ($biblio1, $biblio2) {
476 foreach my $patron ($patron1, $patron8) {
477 _doTest($cbranch, $biblio, $patron, $results);
482 my @pl_names = map { $_->branchname } $biblio1->pickup_locations( { patron => $patron1 } )->as_list;
483 my $pl_ori_str = join('|', @pl_names);
484 my $pl_sorted_str = join('|', sort { lc($a) cmp lc($b) } @pl_names);
486 $pl_ori_str eq $pl_sorted_str,
487 'Libraries must be sorted by name'
489 $schema->storage->txn_rollback;
492 subtest 'to_api() tests' => sub {
494 $schema->storage->txn_begin;
496 my $biblio = $builder->build_sample_biblio();
497 my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
499 my $biblioitem_api = $biblio->biblioitem->to_api;
500 my $biblio_api = $biblio->to_api;
502 plan tests => (scalar keys %{ $biblioitem_api }) + 1;
504 foreach my $key ( keys %{ $biblioitem_api } ) {
505 is( $biblio_api->{$key}, $biblioitem_api->{$key}, "$key is added to the biblio object" );
508 $biblio_api = $biblio->to_api({ embed => { items => {} } });
509 is_deeply( $biblio_api->{items}, [ $item->to_api ], 'Item correctly embedded' );
511 $schema->storage->txn_rollback;
514 subtest 'bookings() tests' => sub {
518 $schema->storage->txn_begin;
520 my $biblio = $builder->build_sample_biblio();
522 is( ref( $biblio->bookings ), 'Koha::Bookings', 'Return type is correct' );
525 $biblio->bookings->unblessed,
527 '->bookings returns an empty Koha::Bookings resultset'
530 my $booking = $builder->build_object(
532 class => 'Koha::Bookings',
533 value => { biblio_id => $biblio->biblionumber }
537 my $bookings = $biblio->bookings->unblessed;
540 $biblio->bookings->unblessed,
541 [ $booking->unblessed ],
542 '->bookings returns the related Koha::Booking objects'
545 $schema->storage->txn_rollback;
548 subtest 'merge of records' => sub {
550 $schema->storage->txn_begin;
553 my $biblio1 = $builder->build_sample_biblio( { title => 'Title number 1' } );
554 my $biblio2 = $builder->build_sample_biblio( { title => 'Title number 2' } );
555 my $biblio3 = $builder->build_sample_biblio( { title => 'Title number 3' } );
558 my $item1_1 = $builder->build_sample_item( { biblionumber => $biblio1->biblionumber, barcode => 'bar11' } );
559 my $item2_1 = $builder->build_sample_item( { biblionumber => $biblio2->biblionumber, barcode => 'bar22' } );
560 my $item3_1 = $builder->build_sample_item( { biblionumber => $biblio3->biblionumber, barcode => 'bar33' } );
562 my @to_merge = ( $biblio2->biblionumber, $biblio3->biblionumber );
564 my $pre_merged_rs = Koha::Biblios->search(
565 { biblionumber => [ $biblio1->biblionumber, $biblio2->biblionumber, $biblio3->biblionumber ] } );
566 is( $pre_merged_rs->count, 3, '3 biblios exist' );
568 eval { $results = $biblio1->merge_with( \@to_merge ); };
570 is( 0, 1, "Not working. Error: " . $@ );
572 my $items = $biblio1->items;
573 is( $items->count, 3, "After merge we have 3 items on first record" );
575 my $merged_rs = Koha::Biblios->search(
576 { biblionumber => [ $biblio1->biblionumber, $biblio2->biblionumber, $biblio3->biblionumber ] } );
577 is( $merged_rs->count, 1, 'only 1 biblio left, the merged ones are gone' );
580 $schema->storage->txn_rollback;
583 subtest 'suggestions() tests' => sub {
587 $schema->storage->txn_begin;
589 my $biblio = $builder->build_sample_biblio();
591 is( ref($biblio->suggestions), 'Koha::Suggestions', 'Return type is correct' );
594 $biblio->suggestions->unblessed,
596 '->suggestions returns an empty Koha::Suggestions resultset'
599 my $suggestion = $builder->build_object(
601 class => 'Koha::Suggestions',
602 value => { biblionumber => $biblio->biblionumber }
606 my $suggestions = $biblio->suggestions->unblessed;
609 $biblio->suggestions->unblessed,
610 [ $suggestion->unblessed ],
611 '->suggestions returns the related Koha::Suggestion objects'
614 $schema->storage->txn_rollback;
617 subtest 'get_marc_components() tests' => sub {
621 $schema->storage->txn_begin;
623 my ($host_bibnum) = C4::Biblio::AddBiblio(host_record(), '');
624 my $host_biblio = Koha::Biblios->find($host_bibnum);
625 t::lib::Mocks::mock_preference( 'SearchEngine', 'Zebra' );
626 my $search_mod = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' );
627 $search_mod->mock( 'search_compat', \&search_component_record2 );
629 my $components = $host_biblio->get_marc_components;
630 is( ref($components), 'ARRAY', 'Return type is correct' );
635 '->get_marc_components returns an empty ARRAY'
638 $search_mod->unmock( 'search_compat');
639 $search_mod->mock( 'search_compat', \&search_component_record1 );
640 my $component_record = component_record1()->as_xml();
643 $host_biblio->get_marc_components,
645 '->get_marc_components returns the related component part record'
647 $search_mod->unmock( 'search_compat');
649 $search_mod->mock( 'search_compat',
650 sub { Koha::Exception->throw("error searching analytics") }
652 warning_like { $components = $host_biblio->get_marc_components }
653 qr{Warning from search_compat: .* 'error searching analytics'};
656 $host_biblio->object_messages,
660 message => 'component_search',
661 payload => "Exception 'Koha::Exception' thrown 'error searching analytics'\n"
665 $search_mod->unmock( 'search_compat');
667 $schema->storage->txn_rollback;
670 subtest 'get_components_query' => sub {
673 my $biblio = $builder->build_sample_biblio();
674 my $biblionumber = $biblio->biblionumber;
675 my $record = $biblio->metadata->record;
677 foreach my $engine ('Zebra','Elasticsearch'){
678 t::lib::Mocks::mock_preference( 'SearchEngine', $engine );
680 t::lib::Mocks::mock_preference( 'UseControlNumber', '0' );
681 t::lib::Mocks::mock_preference( 'ComponentSortField', 'author' );
682 t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'za' );
683 my ( $comp_query, $comp_query_str, $comp_sort ) = $biblio->get_components_query;
684 is($comp_query_str, 'Host-item:("Some boring read")', "$engine: UseControlNumber disabled");
685 is($comp_sort, "author_za", "$engine: UseControlNumber disabled sort is correct");
687 t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
688 t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'az' );
689 my $marc_001_field = MARC::Field->new('001', $biblionumber);
690 $record->append_fields($marc_001_field);
691 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
692 $biblio = Koha::Biblios->find( $biblio->biblionumber);
694 ( $comp_query, $comp_query_str, $comp_sort ) = $biblio->get_components_query;
695 is($comp_query_str, "(rcn:\"$biblionumber\" AND (bib-level:a OR bib-level:b))", "$engine: UseControlNumber enabled without MarcOrgCode");
696 is($comp_sort, "author_az", "$engine: UseControlNumber enabled without MarcOrgCode sort is correct");
698 my $marc_003_field = MARC::Field->new('003', 'OSt');
699 $record->append_fields($marc_003_field);
700 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
701 $biblio = Koha::Biblios->find( $biblio->biblionumber);
703 t::lib::Mocks::mock_preference( 'ComponentSortField', 'title' );
704 t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'asc' );
705 ( $comp_query, $comp_query_str, $comp_sort ) = $biblio->get_components_query;
706 is($comp_query_str, "(((rcn:\"$biblionumber\" AND cni:\"OSt\") OR rcn:\"OSt $biblionumber\") AND (bib-level:a OR bib-level:b))", "$engine: UseControlNumber enabled with MarcOrgCode");
707 is($comp_sort, "title_asc", "$engine: UseControlNumber enabled with MarcOrgCode sort if correct");
708 $record->delete_field($marc_003_field);
712 subtest 'get_volumes_query' => sub {
715 my $biblio = $builder->build_sample_biblio();
716 my $biblionumber = $biblio->biblionumber;
717 my $record = $biblio->metadata->record;
719 # Ensure our mocked record is captured as a set or monographic series
720 my $ldr = $record->leader();
721 substr( $ldr, 19, 1 ) = 'a';
722 $record->leader($ldr);
723 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
724 $biblio = Koha::Biblios->find( $biblio->biblionumber );
726 t::lib::Mocks::mock_preference( 'UseControlNumber', '0' );
728 $biblio->get_volumes_query,
729 "(title-series,phr:(\"Some boring read\") OR Host-item,phr:(\"Some boring read\") NOT (bib-level:a OR bib-level:b))",
730 "UseControlNumber disabled"
733 t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
734 my $marc_001_field = MARC::Field->new( '001', $biblionumber );
735 $record->append_fields($marc_001_field);
736 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
737 $biblio = Koha::Biblios->find( $biblio->biblionumber );
741 $biblio->get_volumes_query, "(rcn:$biblionumber NOT (bib-level:a OR bib-level:b))",
742 "UseControlNumber enabled without MarcOrgCode"
745 my $marc_003_field = MARC::Field->new( '003', 'OSt' );
746 $record->append_fields($marc_003_field);
747 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
748 $biblio = Koha::Biblios->find( $biblio->biblionumber );
751 $biblio->get_volumes_query,
752 "(((rcn:$biblionumber AND cni:OSt) OR rcn:\"OSt $biblionumber\") NOT (bib-level:a OR bib-level:b))",
753 "UseControlNumber enabled with MarcOrgCode"
757 subtest 'orders() and active_orders() tests' => sub {
761 $schema->storage->txn_begin;
763 my $biblio = $builder->build_sample_biblio();
765 my $orders = $biblio->orders;
766 my $active_orders = $biblio->active_orders;
768 is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
769 is( $biblio->orders->count, $biblio->active_orders->count, '->orders->count returns the count for the resultset' );
771 # Add a couple orders
773 $builder->build_object(
775 class => 'Koha::Acquisition::Orders',
777 biblionumber => $biblio->biblionumber,
778 datecancellationprinted => '2019-12-31'
784 $builder->build_object(
786 class => 'Koha::Acquisition::Orders',
788 biblionumber => $biblio->biblionumber,
789 datecancellationprinted => undef
794 $orders = $biblio->orders;
795 $active_orders = $biblio->active_orders;
797 is( ref($orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
798 is( ref($active_orders), 'Koha::Acquisition::Orders', 'Result type is correct' );
799 is( $orders->count, $active_orders->count + 2, '->active_orders->count returns the rigt count' );
801 $schema->storage->txn_rollback;
804 subtest 'tickets() tests' => sub {
808 $schema->storage->txn_begin;
810 my $biblio = $builder->build_sample_biblio();
811 my $tickets = $biblio->tickets;
812 is( ref($tickets), 'Koha::Tickets', 'Koha::Biblio->tickets should return a Koha::Tickets object' );
813 is( $tickets->count, 0, 'Koha::Biblio->tickets should return a count of 0 when there are no related tickets' );
817 $builder->build_object(
819 class => 'Koha::Tickets',
820 value => { biblio_id => $biblio->biblionumber }
825 $tickets = $biblio->tickets;
826 is( ref($tickets), 'Koha::Tickets', 'Koha::Biblio->tickets should return a Koha::Tickets object' );
827 is( $tickets->count, 2, 'Koha::Biblio->tickets should return the correct number of tickets' );
829 $schema->storage->txn_rollback;
832 subtest 'subscriptions() tests' => sub {
836 $schema->storage->txn_begin;
838 my $biblio = $builder->build_sample_biblio;
840 my $subscriptions = $biblio->subscriptions;
841 is( ref($subscriptions), 'Koha::Subscriptions',
842 'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
844 is( $subscriptions->count, 0, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
846 # Add two subscriptions
848 $builder->build_object(
850 class => 'Koha::Subscriptions',
851 value => { biblionumber => $biblio->biblionumber }
856 $subscriptions = $biblio->subscriptions;
857 is( ref($subscriptions), 'Koha::Subscriptions',
858 'Koha::Biblio->subscriptions should return a Koha::Subscriptions object'
860 is( $subscriptions->count, 2, 'Koha::Biblio->subscriptions should return the correct number of subscriptions');
862 $schema->storage->txn_rollback;
865 subtest 'get_marc_notes() MARC21 tests' => sub {
868 $schema->storage->txn_begin;
870 t::lib::Mocks::mock_preference( 'NotesToHide', '520' );
872 my $av = $builder->build_object( { class => 'Koha::AuthorisedValues' } );
874 my $biblio = $builder->build_sample_biblio;
875 my $record = $biblio->metadata->record;
876 $record->append_fields(
877 MARC::Field->new( '500', '', '', a => 'Note1' ),
878 MARC::Field->new( '505', '', '', a => 'Note2', u => 'http://someserver.com' ),
879 MARC::Field->new( '520', '', '', a => 'Note3 skipped' ),
880 MARC::Field->new( '541', '0', '', a => 'Note4 skipped on opac' ),
881 MARC::Field->new( '544', '', '', a => 'Note5' ),
882 MARC::Field->new( '590', '', '', a => $av->authorised_value ),
883 MARC::Field->new( '545', '', '', a => 'Invisible on OPAC' ),
886 my $mss = Koha::MarcSubfieldStructures->find({tagfield => "590", tagsubfield => "a", frameworkcode => $biblio->frameworkcode });
887 $mss->update({ authorised_value => $av->category });
889 $mss = Koha::MarcSubfieldStructures->find({tagfield => "545", tagsubfield => "a", frameworkcode => $biblio->frameworkcode });
890 $mss->update({ hidden => 1 });
892 my $cache = Koha::Caches->get_instance;
893 $cache->clear_from_cache("MarcStructure-0-");
894 $cache->clear_from_cache("MarcStructure-1-");
895 $cache->clear_from_cache("MarcSubfieldStructure-");
896 $cache->clear_from_cache("MarcCodedFields-");
898 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
899 $biblio = Koha::Biblios->find( $biblio->biblionumber);
901 my $notes = $biblio->get_marc_notes;
902 is( $notes->[0]->{marcnote}, 'Note1', 'First note' );
903 is( $notes->[1]->{marcnote}, 'Note2', 'Second note' );
904 is( $notes->[2]->{marcnote}, 'http://someserver.com', 'URL separated' );
905 is( $notes->[3]->{marcnote}, 'Note4 skipped on opac',"Note shows if not opac (Hidden by Indicator)" );
906 is( $notes->[4]->{marcnote}, 'Note5', 'Fifth note' );
907 is( $notes->[5]->{marcnote}, $av->lib, 'Authorised value is correctly parsed to show description rather than code' );
908 is( $notes->[6]->{marcnote}, 'Invisible on OPAC', 'Note shows if not opac (Hidden by framework)' );
909 is( @$notes, 7, 'No more notes' );
910 $notes = $biblio->get_marc_notes({ opac => 1 });
911 is( $notes->[0]->{marcnote}, 'Note1', 'First note' );
912 is( $notes->[1]->{marcnote}, 'Note2', 'Second note' );
913 is( $notes->[2]->{marcnote}, 'http://someserver.com', 'URL separated' );
914 is( $notes->[3]->{marcnote}, 'Note5', 'Fifth note shows after fourth skipped' );
915 is( $notes->[4]->{marcnote}, $av->lib_opac, 'Authorised value is correctly parsed for OPAC to show description rather than code' );
916 is( @$notes, 5, 'No more notes' );
918 $cache->clear_from_cache("MarcStructure-0-");
919 $cache->clear_from_cache("MarcStructure-1-");
920 $cache->clear_from_cache("MarcSubfieldStructure-");
921 $cache->clear_from_cache("MarcCodedFields-");
923 $schema->storage->txn_rollback;
926 subtest 'get_marc_notes() UNIMARC tests' => sub {
929 $schema->storage->txn_begin;
931 t::lib::Mocks::mock_preference( 'NotesToHide', '310' );
932 t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
934 my $biblio = $builder->build_sample_biblio;
935 my $record = $biblio->metadata->record;
936 $record->append_fields(
937 MARC::Field->new( '300', '', '', a => 'Note1' ),
938 MARC::Field->new( '300', '', '', a => 'Note2' ),
939 MARC::Field->new( '310', '', '', a => 'Note3 skipped' ),
941 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
942 $biblio = Koha::Biblios->find( $biblio->biblionumber);
943 my $notes = $biblio->get_marc_notes({ marcflavour => 'UNIMARC' });
944 is( $notes->[0]->{marcnote}, 'Note1', 'First note' );
945 is( $notes->[1]->{marcnote}, 'Note2', 'Second note' );
946 is( @$notes, 2, 'No more notes' );
948 t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
949 $schema->storage->txn_rollback;
952 subtest 'host_items() tests' => sub {
955 $schema->storage->txn_begin;
957 my $biblio = $builder->build_sample_biblio( { frameworkcode => '' } );
959 t::lib::Mocks::mock_preference( 'EasyAnalyticalRecords', 1 );
960 my $host_items = $biblio->host_items;
961 is( ref($host_items), 'Koha::Items' );
962 is( $host_items->count, 0 );
965 $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
966 my $host_item_1 = $builder->build_sample_item;
967 my $host_item_2 = $builder->build_sample_item;
969 my $record = $biblio->metadata->record;
970 $record->append_fields(
973 9 => $host_item_1->itemnumber,
974 9 => $host_item_2->itemnumber
977 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
978 $biblio = $biblio->get_from_storage;
979 $host_items = $biblio->host_items;
980 is( $host_items->count, 2 );
981 is_deeply( [ $host_items->get_column('itemnumber') ],
982 [ $host_item_1->itemnumber, $host_item_2->itemnumber ] );
984 t::lib::Mocks::mock_preference( 'EasyAnalyticalRecords', 0 );
985 $host_items = $biblio->host_items;
986 is( ref($host_items), 'Koha::Items' );
987 is( $host_items->count, 0 );
989 subtest 'test host_items param in items()' => sub {
992 my $items = $biblio->items;
993 is( $items->count, 1, "Without host_items param we only get the items on the biblio");
994 $items = $biblio->items({ host_items => 1 });
995 is( $items->count, 3, "With param host_items we get the biblio items plus analytics");
996 is( ref($items), 'Koha::Items', "We correctly get an Items object");
997 is_deeply( [ $items->get_column('itemnumber') ],
998 [ $item_1->itemnumber, $host_item_1->itemnumber, $host_item_2->itemnumber ] );
1001 $schema->storage->txn_rollback;
1004 subtest 'article_requests() tests' => sub {
1008 $schema->storage->txn_begin;
1010 my $item = $builder->build_sample_item;
1011 my $biblio = $item->biblio;
1013 my $article_requests = $biblio->article_requests;
1014 is( ref($article_requests), 'Koha::ArticleRequests',
1015 'In scalar context, type is correct' );
1016 is( $article_requests->count, 0, 'No article requests' );
1018 foreach my $i ( 0 .. 3 ) {
1020 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
1022 Koha::ArticleRequest->new(
1024 borrowernumber => $patron->id,
1025 biblionumber => $biblio->id,
1026 itemnumber => $item->id,
1027 title => $biblio->title,
1032 $article_requests = $biblio->article_requests;
1033 is( $article_requests->count, 4, '4 article requests' );
1035 $schema->storage->txn_rollback;
1038 subtest 'current_checkouts() and old_checkouts() tests' => sub {
1042 $schema->storage->txn_begin;
1044 my $library = $builder->build_object({ class => 'Koha::Libraries' });
1046 my $patron_1 = $builder->build_object({ class => 'Koha::Patrons' });
1047 my $patron_2 = $builder->build_object({ class => 'Koha::Patrons' });
1049 my $item_1 = $builder->build_sample_item;
1050 my $item_2 = $builder->build_sample_item({ biblionumber => $item_1->biblionumber });
1052 t::lib::Mocks::mock_userenv({ branchcode => $library->id });
1054 AddIssue( $patron_1, $item_1->barcode );
1055 AddIssue( $patron_1, $item_2->barcode );
1057 AddReturn( $item_1->barcode );
1058 AddIssue( $patron_2, $item_1->barcode );
1060 my $biblio = $item_1->biblio;
1061 my $current_checkouts = $biblio->current_checkouts;
1062 my $old_checkouts = $biblio->old_checkouts;
1064 is( ref($current_checkouts), 'Koha::Checkouts', 'Type is correct' );
1065 is( ref($old_checkouts), 'Koha::Old::Checkouts', 'Type is correct' );
1067 is( $current_checkouts->count, 2, 'Count is correct for current checkouts' );
1068 is( $old_checkouts->count, 1, 'Count is correct for old checkouts' );
1070 $schema->storage->txn_rollback;
1073 subtest 'get_marc_contributors() tests' => sub {
1077 $schema->storage->txn_begin;
1079 my $biblio = $builder->build_sample_biblio({ author => 'Main author' });
1080 my $record = $biblio->metadata->record;
1082 # add author information
1083 my $field = MARC::Field->new('700','1','','a' => 'Jefferson, Thomas');
1084 $record->append_fields($field);
1085 $field = MARC::Field->new('701','1','','d' => 'Secondary author 2');
1086 $record->append_fields($field);
1089 C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
1090 $biblio = Koha::Biblios->find( $biblio->biblionumber );
1092 is( @{$biblio->get_marc_authors}, 3, 'get_marc_authors retrieves correct number of author subfields' );
1093 is( @{$biblio->get_marc_contributors}, 2, 'get_marc_contributors retrieves correct number of author subfields' );
1094 $schema->storage->txn_rollback;
1097 subtest 'Recalls tests' => sub {
1101 $schema->storage->txn_begin;
1103 my $item1 = $builder->build_sample_item;
1104 my $biblio = $item1->biblio;
1105 my $branchcode = $item1->holdingbranch;
1106 my $patron1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1107 my $patron2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1108 my $patron3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } });
1109 my $item2 = $builder->build_object({ class => 'Koha::Items', value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype } });
1110 t::lib::Mocks::mock_userenv({ patron => $patron1 });
1112 my $recall1 = Koha::Recall->new(
1113 { patron_id => $patron1->borrowernumber,
1114 created_date => \'NOW()',
1115 biblio_id => $biblio->biblionumber,
1116 pickup_library_id => $branchcode,
1117 item_id => $item1->itemnumber,
1118 expiration_date => undef,
1122 my $recall2 = Koha::Recall->new(
1123 { patron_id => $patron2->borrowernumber,
1124 created_date => \'NOW()',
1125 biblio_id => $biblio->biblionumber,
1126 pickup_library_id => $branchcode,
1128 expiration_date => undef,
1132 my $recall3 = Koha::Recall->new(
1133 { patron_id => $patron3->borrowernumber,
1134 created_date => \'NOW()',
1135 biblio_id => $biblio->biblionumber,
1136 pickup_library_id => $branchcode,
1137 item_id => $item1->itemnumber,
1138 expiration_date => undef,
1143 my $recalls = $biblio->recalls;
1144 is( $recalls->count, 3, 'Correctly get number of recalls for biblio' );
1146 $recall1->set_cancelled;
1147 $recall2->set_expired({ interface => 'COMMANDLINE' });
1149 is( $recalls->count, 3, 'Correctly get number of recalls for biblio' );
1150 is( $recalls->filter_by_current->count, 1, 'Correctly get number of active recalls for biblio' );
1152 t::lib::Mocks::mock_preference('UseRecalls', 0);
1153 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with UseRecalls disabled" );
1155 t::lib::Mocks::mock_preference("UseRecalls", 1);
1156 $item1->update({ notforloan => 1 });
1157 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with no available items" );
1159 $item1->update({ notforloan => 0 });
1160 Koha::CirculationRules->set_rules({
1161 branchcode => $branchcode,
1162 categorycode => $patron1->categorycode,
1163 itemtype => $item1->effective_itemtype,
1165 recalls_allowed => 0,
1166 recalls_per_record => 1,
1167 on_shelf_recalls => 'all',
1170 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if recalls_allowed = 0" );
1172 Koha::CirculationRules->set_rules({
1173 branchcode => $branchcode,
1174 categorycode => $patron1->categorycode,
1175 itemtype => $item1->effective_itemtype,
1177 recalls_allowed => 1,
1178 recalls_per_record => 1,
1179 on_shelf_recalls => 'all',
1182 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has more existing recall(s) than recalls_allowed" );
1183 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has more existing recall(s) than recalls_per_record" );
1185 $recall1->set_cancelled;
1186 C4::Circulation::AddIssue( $patron1, $item2->barcode );
1187 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has already checked out an item attached to this biblio" );
1189 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if on_shelf_recalls = all and items are still available" );
1191 Koha::CirculationRules->set_rules({
1192 branchcode => $branchcode,
1193 categorycode => $patron1->categorycode,
1194 itemtype => $item1->effective_itemtype,
1196 recalls_allowed => 1,
1197 recalls_per_record => 1,
1198 on_shelf_recalls => 'any',
1201 C4::Circulation::AddReturn( $item2->barcode, $branchcode );
1202 is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if no items are checked out" );
1204 $recall2->set_cancelled;
1205 C4::Circulation::AddIssue( $patron2, $item2->barcode );
1206 C4::Circulation::AddIssue( $patron2, $item1->barcode );
1207 is( $biblio->can_be_recalled({ patron => $patron1 }), 2, "Can recall two items" );
1209 $item1->update({ withdrawn => 1 });
1210 is( $biblio->can_be_recalled({ patron => $patron1 }), 1, "Can recall one item" );
1212 $schema->storage->txn_rollback;
1215 subtest 'ill_requests() tests' => sub {
1219 $schema->storage->txn_begin;
1221 my $biblio = $builder->build_sample_biblio;
1223 my $rs = $biblio->ill_requests;
1224 is( ref($rs), 'Koha::Illrequests' );
1225 is( $rs->count, 0, 'No linked requests' );
1228 $builder->build_object(
1230 class => 'Koha::Illrequests',
1231 value => { biblio_id => $biblio->id }
1236 is( $biblio->ill_requests->count, 10, 'Linked requests are present' );
1238 $schema->storage->txn_rollback;
1241 subtest 'item_groups() tests' => sub {
1245 $schema->storage->txn_begin;
1247 my $biblio = $builder->build_sample_biblio();
1249 my @item_groups = $biblio->item_groups->as_list;
1250 is( scalar(@item_groups), 0, 'Got zero item groups');
1252 my $item_group_1 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store();
1254 @item_groups = $biblio->item_groups->as_list;
1255 is( scalar(@item_groups), 1, 'Got one item group');
1256 is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group');
1258 my $item_group_2 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store();
1260 @item_groups = $biblio->item_groups->as_list;
1261 is( scalar(@item_groups), 2, 'Got two item groups');
1262 is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group 1');
1263 is( $item_groups[1]->id, $item_group_2->id, 'Got correct item group 2');
1265 $schema->storage->txn_rollback;
1268 subtest 'normalized_isbn' => sub {
1271 # We will move the tests from GetNormalizedISBN here when it will get replaced
1272 my $biblio = $builder->build_sample_biblio();
1273 $biblio->biblioitem->set( { isbn => '9781250067128 | 125006712X' } )->store;
1275 $biblio->normalized_isbn, C4::Koha::GetNormalizedISBN( $biblio->biblioitem->isbn ),
1276 'normalized_isbn is a wrapper around C4::Koha::GetNormalizedISBN'
1280 subtest 'normalized_upc' => sub {
1283 # We will move the tests from GetNormalizedUPC here when it will get replaced
1284 # Note that only a single test exist and it's not really meaningful...
1285 my $biblio = $builder->build_sample_biblio();
1287 $biblio->normalized_upc, C4::Koha::GetNormalizedUPC( $biblio->metadata->record ),
1288 'normalized_upc is a wrapper around C4::Koha::GetNormalizedUPC'
1292 subtest 'normalized_oclc' => sub {
1295 # We will move the tests from GetNormalizedOCLC here when it will get replaced
1296 # Note that only a single test exist and it's not really meaningful...
1297 my $biblio = $builder->build_sample_biblio();
1299 $biblio->normalized_oclc, C4::Koha::GetNormalizedOCLCNumber( $biblio->metadata->record ),
1300 'normalized_oclc is a wrapper around C4::Koha::GetNormalizedOCLCNumber'
1304 subtest 'ratings' => sub {
1306 # See t/db_dependent/Koha/Ratings.t
1310 subtest 'opac_summary_html' => sub {
1314 my $author = 'my author';
1315 my $title = 'my title';
1316 my $isbn = '9781250067128 | 125006712X';
1317 my $biblio = $builder->build_sample_biblio( { author => $author, title => $title } );
1318 $biblio->biblioitem->set( { isbn => '9781250067128 | 125006712X' } )->store;
1320 t::lib::Mocks::mock_preference( 'OPACMySummaryHTML', '' );
1321 is( $biblio->opac_summary_html, '', 'opac_summary_html returns empty string if pref is off' );
1323 t::lib::Mocks::mock_preference(
1324 'OPACMySummaryHTML',
1325 'Replace {AUTHOR}, {TITLE}, {ISBN} AND {BIBLIONUMBER} please'
1328 $biblio->opac_summary_html,
1329 sprintf( 'Replace %s, %s, %s AND %s please', $author, $title, $biblio->normalized_isbn, $biblio->biblionumber ),
1330 'opac_summary_html replaces the different patterns'
1334 sub component_record1 {
1335 my $marc = MARC::Record->new;
1336 $marc->append_fields(
1337 MARC::Field->new( '001', '3456' ),
1338 MARC::Field->new( '245', '', '', a => 'Some title 1' ),
1339 MARC::Field->new( '773', '', '', w => '(FIRST)1234' ),
1343 sub search_component_record1 {
1344 my @results = ( component_record1()->as_xml() );
1345 return ( undef, { biblioserver => { RECORDS => \@results, hits => 1 } }, 1 );
1348 sub search_component_record2 {
1350 return ( undef, { biblioserver => { RECORDS => \@results, hits => 0 } }, 0 );
1354 my $marc = MARC::Record->new;
1355 $marc->append_fields(
1356 MARC::Field->new( '001', '1234' ),
1357 MARC::Field->new( '003', 'FIRST' ),
1358 MARC::Field->new( '245', '', '', a => 'Some title' ),
1363 subtest 'check_booking tests' => sub {
1366 $schema->storage->txn_begin;
1368 my $biblio = $builder->build_sample_biblio();
1371 my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, bookable => 1 } );
1375 my $can_book = $biblio->check_booking(
1377 start_date => dt_from_string(),
1378 end_date => dt_from_string()->add( days => 7 )
1384 "True returned from Koha::Biblio->check_booking if there are no bookings"
1387 my $start_1 = dt_from_string()->subtract( days => 7 );
1388 my $end_1 = dt_from_string()->subtract( days => 1 );
1389 my $start_2 = dt_from_string();
1390 my $end_2 = dt_from_string()->add( days => 7 );
1394 for my $item (@items) {
1396 my $booking = $builder->build_object(
1398 class => 'Koha::Bookings',
1400 biblio_id => $biblio->biblionumber,
1401 item_id => $item->itemnumber,
1402 start_date => $start_1,
1407 push @bookings, $booking;
1410 $can_book = $biblio->check_booking(
1412 start_date => dt_from_string(),
1413 end_date => dt_from_string()->add( days => 7 ),
1420 "Koha::Biblio->check_booking returns true when we all existing bookings are in the past"
1424 my @current_bookings;
1425 for my $item (@items) {
1426 my $booking = $builder->build_object(
1428 class => 'Koha::Bookings',
1430 biblio_id => $biblio->biblionumber,
1431 item_id => $item->itemnumber,
1432 start_date => $start_2,
1437 push @current_bookings, $booking;
1440 $can_book = $biblio->check_booking(
1442 start_date => dt_from_string(),
1443 end_date => dt_from_string()->add( days => 7 ),
1449 "Koha::Biblio->check_booking returns false if the booking would conflict with existing bookings"
1452 $can_book = $biblio->check_booking(
1454 start_date => dt_from_string(),
1455 end_date => dt_from_string()->add( days => 7 ),
1456 booking_id => $current_bookings[0]->booking_id
1462 "Koha::Biblio->check_booking returns true if we pass the booking_id of one of the bookings that we would conflict with"
1465 $schema->storage->txn_rollback;