X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=t%2Fdb_dependent%2FKoha%2FBiblio.t;h=98eac9b64f77e524b529e9e5ef28cb1b3d5bb9ac;hb=93d44d18759d43a09f6c623ffe4fa81dca4dcaa2;hp=73dcb2ab13a7636f2c0b7ad7dac85fab70c5c8ba;hpb=ca5781d795313ac484d9056ef80157f11f8266b4;p=koha-ffzg.git diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t index 73dcb2ab13..98eac9b64f 100755 --- a/t/db_dependent/Koha/Biblio.t +++ b/t/db_dependent/Koha/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 19; +use Test::More tests => 22; # +1 use Test::Warn; use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc ); @@ -29,7 +29,7 @@ use Koha::Acquisition::Orders; use Koha::AuthorisedValueCategories; use Koha::AuthorisedValues; use Koha::MarcSubfieldStructures; -use Koha::Exceptions::Exception; +use Koha::Exception; use MARC::Field; use MARC::Record; @@ -126,7 +126,7 @@ subtest 'hidden_in_opac() tests' => sub { subtest 'items() tests' => sub { - plan tests => 4; + plan tests => 3; $schema->storage->txn_begin; @@ -141,9 +141,6 @@ subtest 'items() tests' => sub { is( ref($items), 'Koha::Items', 'Returns a Koha::Items resultset' ); is( $items->count, 2, 'Two items in resultset' ); - my @items = $biblio->items->as_list; - is( scalar @items, 2, 'Same result, but in list context' ); - $schema->storage->txn_rollback; }; @@ -521,7 +518,7 @@ subtest 'get_marc_components() tests' => sub { my $host_biblio = Koha::Biblios->find($host_bibnum); t::lib::Mocks::mock_preference( 'SearchEngine', 'Zebra' ); my $search_mod = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' ); - $search_mod->mock( 'simple_search_compat', \&search_component_record2 ); + $search_mod->mock( 'search_compat', \&search_component_record2 ); my $components = $host_biblio->get_marc_components; is( ref($components), 'ARRAY', 'Return type is correct' ); @@ -532,8 +529,8 @@ subtest 'get_marc_components() tests' => sub { '->get_marc_components returns an empty ARRAY' ); - $search_mod->unmock( 'simple_search_compat'); - $search_mod->mock( 'simple_search_compat', \&search_component_record1 ); + $search_mod->unmock( 'search_compat'); + $search_mod->mock( 'search_compat', \&search_component_record1 ); my $component_record = component_record1()->as_xml(); is_deeply( @@ -541,53 +538,64 @@ subtest 'get_marc_components() tests' => sub { [$component_record], '->get_marc_components returns the related component part record' ); - $search_mod->unmock( 'simple_search_compat'); + $search_mod->unmock( 'search_compat'); - $search_mod->mock( 'simple_search_compat', - sub { Koha::Exceptions::Exception->throw("error searching analytics") } + $search_mod->mock( 'search_compat', + sub { Koha::Exception->throw("error searching analytics") } ); warning_like { $components = $host_biblio->get_marc_components } - qr{^Warning from simple_search_compat: 'error searching analytics'}; + qr{Warning from search_compat: .* 'error searching analytics'}; is_deeply( - $host_biblio->messages, + $host_biblio->object_messages, [ { type => 'error', message => 'component_search', - payload => "error searching analytics" + payload => "Exception 'Koha::Exception' thrown 'error searching analytics'\n" } ] ); - $search_mod->unmock( 'simple_search_compat'); + $search_mod->unmock( 'search_compat'); $schema->storage->txn_rollback; }; subtest 'get_components_query' => sub { - plan tests => 3; + plan tests => 6; my $biblio = $builder->build_sample_biblio(); my $biblionumber = $biblio->biblionumber; my $record = $biblio->metadata->record; t::lib::Mocks::mock_preference( 'UseControlNumber', '0' ); - is($biblio->get_components_query, "Host-item:(Some boring read)", "UseControlNumber disabled"); + t::lib::Mocks::mock_preference( 'ComponentSortField', 'author' ); + t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'za' ); + my ( $comp_q, $comp_s ) = $biblio->get_components_query; + is($comp_q, 'Host-item:("Some boring read")', "UseControlNumber disabled"); + is($comp_s, "author_za", "UseControlNumber disabled sort is correct"); t::lib::Mocks::mock_preference( 'UseControlNumber', '1' ); + t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'az' ); my $marc_001_field = MARC::Field->new('001', $biblionumber); $record->append_fields($marc_001_field); C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); $biblio = Koha::Biblios->find( $biblio->biblionumber); - is($biblio->get_components_query, "(rcn:$biblionumber AND (bib-level:a OR bib-level:b))", "UseControlNumber enabled without MarcOrgCode"); + ( $comp_q, $comp_s ) = $biblio->get_components_query; + is($comp_q, "(rcn:$biblionumber AND (bib-level:a OR bib-level:b))", "UseControlNumber enabled without MarcOrgCode"); + is($comp_s, "author_az", "UseControlNumber enabled without MarcOrgCode sort is correct"); my $marc_003_field = MARC::Field->new('003', 'OSt'); $record->append_fields($marc_003_field); C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); $biblio = Koha::Biblios->find( $biblio->biblionumber); - is($biblio->get_components_query, "(((rcn:$biblionumber AND cni:OSt) OR rcn:\"OSt $biblionumber\") AND (bib-level:a OR bib-level:b))", "UseControlNumber enabled with MarcOrgCode"); + t::lib::Mocks::mock_preference( 'ComponentSortField', 'title' ); + t::lib::Mocks::mock_preference( 'ComponentSortOrder', 'asc' ); + ( $comp_q, $comp_s ) = $biblio->get_components_query; + is($comp_q, "(((rcn:$biblionumber AND cni:OSt) OR rcn:\"OSt $biblionumber\") AND (bib-level:a OR bib-level:b))", "UseControlNumber enabled with MarcOrgCode"); + is($comp_s, "title_asc", "UseControlNumber enabled with MarcOrgCode sort if correct"); }; subtest 'orders() and active_orders() tests' => sub { @@ -671,7 +679,7 @@ subtest 'subscriptions() tests' => sub { }; subtest 'get_marc_notes() MARC21 tests' => sub { - plan tests => 13; + plan tests => 14; $schema->storage->txn_begin; @@ -684,33 +692,44 @@ subtest 'get_marc_notes() MARC21 tests' => sub { MARC::Field->new( '505', '', '', a => 'Note2', u => 'http://someserver.com' ), MARC::Field->new( '520', '', '', a => 'Note3 skipped' ), MARC::Field->new( '541', '0', '', a => 'Note4 skipped on opac' ), - MARC::Field->new( '541', '', '', a => 'Note5' ), + MARC::Field->new( '544', '', '', a => 'Note5' ), MARC::Field->new( '590', '', '', a => 'CODE' ), + MARC::Field->new( '545', '', '', a => 'Invisible on OPAC' ), ); Koha::AuthorisedValueCategory->new({ category_name => 'TEST' })->store; - Koha::AuthorisedValue->new({ category => 'TEST', authorised_value => 'CODE', lib => 'Description should show', lib_opac => 'Description should show OPAC' })->store; + Koha::AuthorisedValue->new( + { + category => 'TEST', + authorised_value => 'CODE', + lib => 'Description should show', + lib_opac => 'Description should show OPAC' + } + )->store; my $mss = Koha::MarcSubfieldStructures->find({tagfield => "590", tagsubfield => "a", frameworkcode => $biblio->frameworkcode }); $mss->update({ authorised_value => "TEST" }); + $mss = Koha::MarcSubfieldStructures->find({tagfield => "545", tagsubfield => "a", frameworkcode => $biblio->frameworkcode }); + $mss->update({ hidden => 1 }); + my $cache = Koha::Caches->get_instance; $cache->clear_from_cache("MarcStructure-0-"); $cache->clear_from_cache("MarcStructure-1-"); - $cache->clear_from_cache("default_value_for_mod_marc-"); $cache->clear_from_cache("MarcSubfieldStructure-"); C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); $biblio = Koha::Biblios->find( $biblio->biblionumber); - my $notes = $biblio->get_marc_notes({ marcflavour => 'MARC21' }); + my $notes = $biblio->get_marc_notes; is( $notes->[0]->{marcnote}, 'Note1', 'First note' ); is( $notes->[1]->{marcnote}, 'Note2', 'Second note' ); is( $notes->[2]->{marcnote}, 'http://someserver.com', 'URL separated' ); - is( $notes->[3]->{marcnote}, 'Note4 skipped on opac',"Not shows if not opac" ); + is( $notes->[3]->{marcnote}, 'Note4 skipped on opac',"Note shows if not opac (Hidden by Indicator)" ); is( $notes->[4]->{marcnote}, 'Note5', 'Fifth note' ); is( $notes->[5]->{marcnote}, 'Description should show', 'Authorised value is correctly parsed to show description rather than code' ); - is( @$notes, 6, 'No more notes' ); - $notes = $biblio->get_marc_notes({ marcflavour => 'MARC21', opac => 1 }); + is( $notes->[6]->{marcnote}, 'Invisible on OPAC', 'Note shows if not opac (Hidden by framework)' ); + is( @$notes, 7, 'No more notes' ); + $notes = $biblio->get_marc_notes({ opac => 1 }); is( $notes->[0]->{marcnote}, 'Note1', 'First note' ); is( $notes->[1]->{marcnote}, 'Note2', 'Second note' ); is( $notes->[2]->{marcnote}, 'http://someserver.com', 'URL separated' ); @@ -720,7 +739,6 @@ subtest 'get_marc_notes() MARC21 tests' => sub { $cache->clear_from_cache("MarcStructure-0-"); $cache->clear_from_cache("MarcStructure-1-"); - $cache->clear_from_cache("default_value_for_mod_marc-"); $cache->clear_from_cache("MarcSubfieldStructure-"); $schema->storage->txn_rollback; @@ -732,6 +750,7 @@ subtest 'get_marc_notes() UNIMARC tests' => sub { $schema->storage->txn_begin; t::lib::Mocks::mock_preference( 'NotesToHide', '310' ); + t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' ); my $biblio = $builder->build_sample_biblio; my $record = $biblio->metadata->record; @@ -747,6 +766,7 @@ subtest 'get_marc_notes() UNIMARC tests' => sub { is( $notes->[1]->{marcnote}, 'Note2', 'Second note' ); is( @$notes, 2, 'No more notes' ); + t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); $schema->storage->txn_rollback; }; @@ -859,6 +879,175 @@ subtest 'current_checkouts() and old_checkouts() tests' => sub { $schema->storage->txn_rollback; }; +subtest 'get_marc_contributors() tests' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + + my $biblio = $builder->build_sample_biblio({ author => 'Main author' }); + my $record = $biblio->metadata->record; + + # add author information + my $field = MARC::Field->new('700','1','','a' => 'Jefferson, Thomas'); + $record->append_fields($field); + $field = MARC::Field->new('701','1','','d' => 'Secondary author 2'); + $record->append_fields($field); + + # get record + C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); + $biblio = Koha::Biblios->find( $biblio->biblionumber ); + + is( @{$biblio->get_marc_authors}, 3, 'get_marc_authors retrieves correct number of author subfields' ); + is( @{$biblio->get_marc_contributors}, 2, 'get_marc_contributors retrieves correct number of author subfields' ); + $schema->storage->txn_rollback; +}; + +subtest 'Recalls tests' => sub { + + plan tests => 13; + + $schema->storage->txn_begin; + + my $item1 = $builder->build_sample_item; + my $biblio = $item1->biblio; + my $branchcode = $item1->holdingbranch; + my $patron1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } }); + my $patron2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } }); + my $patron3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $branchcode } }); + my $item2 = $builder->build_object({ class => 'Koha::Items', value => { holdingbranch => $branchcode, homebranch => $branchcode, biblionumber => $biblio->biblionumber, itype => $item1->effective_itemtype } }); + t::lib::Mocks::mock_userenv({ patron => $patron1 }); + + my $recall1 = Koha::Recall->new( + { patron_id => $patron1->borrowernumber, + created_date => \'NOW()', + biblio_id => $biblio->biblionumber, + pickup_library_id => $branchcode, + item_id => $item1->itemnumber, + expiration_date => undef, + item_level => 1 + } + )->store; + my $recall2 = Koha::Recall->new( + { patron_id => $patron2->borrowernumber, + created_date => \'NOW()', + biblio_id => $biblio->biblionumber, + pickup_library_id => $branchcode, + item_id => undef, + expiration_date => undef, + item_level => 0 + } + )->store; + my $recall3 = Koha::Recall->new( + { patron_id => $patron3->borrowernumber, + created_date => \'NOW()', + biblio_id => $biblio->biblionumber, + pickup_library_id => $branchcode, + item_id => $item1->itemnumber, + expiration_date => undef, + item_level => 1 + } + )->store; + + my $recalls = $biblio->recalls; + is( $recalls->count, 3, 'Correctly get number of recalls for biblio' ); + + $recall1->set_cancelled; + $recall2->set_expired({ interface => 'COMMANDLINE' }); + + is( $recalls->count, 3, 'Correctly get number of recalls for biblio' ); + is( $recalls->filter_by_current->count, 1, 'Correctly get number of active recalls for biblio' ); + + t::lib::Mocks::mock_preference('UseRecalls', 0); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with UseRecalls disabled" ); + + t::lib::Mocks::mock_preference("UseRecalls", 1); + $item1->update({ notforloan => 1 }); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall with no available items" ); + + $item1->update({ notforloan => 0 }); + Koha::CirculationRules->set_rules({ + branchcode => $branchcode, + categorycode => $patron1->categorycode, + itemtype => $item1->effective_itemtype, + rules => { + recalls_allowed => 0, + recalls_per_record => 1, + on_shelf_recalls => 'all', + }, + }); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if recalls_allowed = 0" ); + + Koha::CirculationRules->set_rules({ + branchcode => $branchcode, + categorycode => $patron1->categorycode, + itemtype => $item1->effective_itemtype, + rules => { + recalls_allowed => 1, + recalls_per_record => 1, + on_shelf_recalls => 'all', + }, + }); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has more existing recall(s) than recalls_allowed" ); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has more existing recall(s) than recalls_per_record" ); + + $recall1->set_cancelled; + C4::Circulation::AddIssue( $patron1->unblessed, $item2->barcode ); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if patron has already checked out an item attached to this biblio" ); + + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if on_shelf_recalls = all and items are still available" ); + + Koha::CirculationRules->set_rules({ + branchcode => $branchcode, + categorycode => $patron1->categorycode, + itemtype => $item1->effective_itemtype, + rules => { + recalls_allowed => 1, + recalls_per_record => 1, + on_shelf_recalls => 'any', + }, + }); + C4::Circulation::AddReturn( $item2->barcode, $branchcode ); + is( $biblio->can_be_recalled({ patron => $patron1 }), 0, "Can't recall if no items are checked out" ); + + $recall2->set_cancelled; + C4::Circulation::AddIssue( $patron2->unblessed, $item2->barcode ); + C4::Circulation::AddIssue( $patron2->unblessed, $item1->barcode ); + is( $biblio->can_be_recalled({ patron => $patron1 }), 2, "Can recall two items" ); + + $item1->update({ withdrawn => 1 }); + is( $biblio->can_be_recalled({ patron => $patron1 }), 1, "Can recall one item" ); + + $schema->storage->txn_rollback; +}; + +subtest 'item_groups() tests' => sub { + + plan tests => 6; + + $schema->storage->txn_begin; + + my $biblio = $builder->build_sample_biblio(); + + my @item_groups = $biblio->item_groups->as_list; + is( scalar(@item_groups), 0, 'Got zero item groups'); + + my $item_group_1 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); + + @item_groups = $biblio->item_groups->as_list; + is( scalar(@item_groups), 1, 'Got one item group'); + is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group'); + + my $item_group_2 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); + + @item_groups = $biblio->item_groups->as_list; + is( scalar(@item_groups), 2, 'Got two item groups'); + is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group 1'); + is( $item_groups[1]->id, $item_group_2->id, 'Got correct item group 2'); + + $schema->storage->txn_rollback; +}; + sub component_record1 { my $marc = MARC::Record->new; $marc->append_fields( @@ -870,12 +1059,12 @@ sub component_record1 { } sub search_component_record1 { my @results = ( component_record1()->as_xml() ); - return ( undef, \@results, 1 ); + return ( undef, { biblioserver => { RECORDS => \@results, hits => 1 } }, 1 ); } sub search_component_record2 { my @results; - return ( undef, \@results, 0 ); + return ( undef, { biblioserver => { RECORDS => \@results, hits => 0 } }, 0 ); } sub host_record {