From 933579858ab38cf3872ff5c0539484944539587a Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Wed, 15 Feb 2017 15:48:17 +0100 Subject: [PATCH] Bug 9988: Add get_usage_count and linked_biblionumbers to Koha::Authority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When replacing the Zebra code in sub merge, we actually need CountUsage as well as the results it gets from SearchEngine. In order to get count and/or results, we now create: [1] instance methods get_usage_count and linked_biblionumbers in Koha::Authority, [2] class methods of the same name in Koha::Authorities. The instance method calls the class method. The class method can be used for deleted authority records, and in 'legacy calls' before refactoring. Note: On BZ 18149 we will replace all CountUsage calls. Test plan: Run t/db_dependent/Koha/Authorities.t Signed-off-by: Marcel de Rooy Signed-off-by: Marc VĂ©ron Signed-off-by: Jacek Ablewicz --- Koha/Authorities.pm | 57 ++++++++++++++++++++ Koha/Authority.pm | 32 ++++++++++- t/db_dependent/Koha/Authorities.t | 106 ++++++++++++++++++++++++++++++++++++- 3 files changed, 192 insertions(+), 3 deletions(-) diff --git a/Koha/Authorities.pm b/Koha/Authorities.pm index 22ce7a2..ca150c4 100644 --- a/Koha/Authorities.pm +++ b/Koha/Authorities.pm @@ -35,8 +35,65 @@ Koha::Authorities - Koha Authority object set class =head2 Class Methods +=head3 get_usage_count + + $count = Koha::Authorities->get_usage_count({ authid => $i }); + + Returns the number of linked biblio records. + + Note: Code originates from C4::AuthoritiesMarc::CountUsage. + + This is a class method, since the authid may refer to a deleted record. + =cut +sub get_usage_count { + my ( $class, $params ) = @_; + my $authid = $params->{authid} || return; + + my $searcher = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); + my ( $err, $result, $count ) = $searcher->simple_search_compat( 'an:' . $authid, 0, 0 ); + if( $err ) { + warn "Error: $err from search for " . $authid; + return; + } + return $count; +} + +=head3 linked_biblionumbers + + my @biblios = Koha::Authorities->linked_biblionumbers({ + authid => $id, [ max_results => $max ], [ offset => $offset ], + }); + + Returns array of biblionumbers, as extracted from the result records of + the search engine. + + This is a class method, since the authid may refer to a deleted record. + +=cut + +sub linked_biblionumbers { + my ( $self, $params ) = @_; + my $authid = $params->{authid} || return; + + my $searcher = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); + # if max_results is undefined, we will get all results + my ( $err, $result, $count ) = $searcher->simple_search_compat( 'an:' . $authid, $params->{offset} // 0, $params->{max_results} ); + + if( $err ) { + warn "Error: $err from search for " . $authid; + return; + } + + my @biblionumbers; + foreach my $res ( @$result ) { + my $bibno = $searcher->extract_biblionumber( $res ); + push @biblionumbers, $bibno if $bibno; + } + return @biblionumbers; +} + =head3 type =cut diff --git a/Koha/Authority.pm b/Koha/Authority.pm index b94d560..ac2b25c 100644 --- a/Koha/Authority.pm +++ b/Koha/Authority.pm @@ -20,6 +20,7 @@ package Koha::Authority; use Modern::Perl; use base qw(Koha::Object); +use Koha::SearchEngine::Search; =head1 NAME @@ -27,10 +28,39 @@ Koha::Authority - Koha Authority Object class =head1 API -=head2 Class Methods +=head2 Instance Methods + +=head3 get_usage_count + + $count = $self->get_usage_count; + + Returns the number of linked biblio records. =cut +sub get_usage_count { + my ( $self ) = @_; + return Koha::Authorities->get_usage_count({ authid => $self->authid }); +} + +=head3 linked_biblionumbers + + my @biblios = $self->linked_biblionumbers({ + [ max_results => $max ], [ offset => $offset ], + }); + + Returns an array of biblionumbers. + +=cut + +sub linked_biblionumbers { + my ( $self, $params ) = @_; + $params->{authid} = $self->authid; + return Koha::Authorities->linked_biblionumbers( $params ); +} + +=head2 Class Methods + =head3 type =cut diff --git a/t/db_dependent/Koha/Authorities.t b/t/db_dependent/Koha/Authorities.t index 8bc98fd..a690663 100644 --- a/t/db_dependent/Koha/Authorities.t +++ b/t/db_dependent/Koha/Authorities.t @@ -19,12 +19,16 @@ use Modern::Perl; -use Test::More tests => 5; +use Test::More tests => 6; use MARC::Field; use MARC::File::XML; use MARC::Record; use Test::Deep; +use Test::MockModule; +use Test::MockObject; +use Test::Warn; +use C4::Context; use Koha::Authority; use Koha::Authorities; use Koha::Authority::MergeRequest; @@ -33,12 +37,22 @@ use Koha::Authority::Type; use Koha::Authority::Types; use Koha::Database; +use t::lib::Mocks; use t::lib::TestBuilder; +BEGIN { + #TODO Helpful as long as we have issues here + my $mock = Test::MockObject->new(); + $mock->fake_module( 'Catmandu::Store::ElasticSearch' ); +} + my $schema = Koha::Database->new->schema; $schema->storage->txn_begin; -my $builder = t::lib::TestBuilder->new; +# Globals +our $search_compat_pars; +our $builder = t::lib::TestBuilder->new; + my $nb_of_authorities = Koha::Authorities->search->count; my $nb_of_authority_types = Koha::Authority::Types->search->count; my $new_authority_type_1 = Koha::Authority::Type->new( @@ -110,4 +124,92 @@ subtest 'Testing reporting_tag_xml in MergeRequests' => sub { ); }; +subtest 'Trivial tests for get_count_usage and linked_biblionumbers' => sub { + plan tests => 5; + + # NOTE: We are not testing $searcher->simple_search_compat here. Suppose + # that should be done in t/db../Koha/SearchEngine? + # So we're just testing the 'wrapper' here. + + my ( $mods, $koha_fields ); + t::lib::Mocks::mock_preference('SearchEngine', 'Zebra'); + $mods->{zebra} = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' ); + $mods->{elastic} = Test::MockModule->new( 'Koha::SearchEngine::Elasticsearch::Search' ); + $mods->{biblio} = Test::MockModule->new( 'C4::Biblio' ); + $mods->{zebra}->mock( 'simple_search_compat', \&simple_search_compat ); + $mods->{elastic}->mock( 'simple_search_compat', \&simple_search_compat ); + $mods->{biblio}->mock( 'GetMarcFromKohaField', sub { return @$koha_fields; }); + + my $auth1 = $builder->build({ source => 'AuthHeader' }); + $auth1 = Koha::Authorities->find( $auth1->{authid} ); + + # Test error condition + my $count; + $search_compat_pars = [ 0, 'some_error' ]; + warning_like { $count = $auth1->get_usage_count } + qr/some_error/, 'Catch warn of simple_search_compat'; + is( $count, undef, 'Undef returned when error encountered' ); + + # Simple test with some results; one result discarded in the 2nd test + $search_compat_pars = [ 1 ]; + $koha_fields = [ '001', '' ]; + is( $auth1->get_usage_count, 3, 'Three results expected (Zebra)' ); + cmp_deeply( [ $auth1->linked_biblionumbers ], [ 1001, 3003 ], + 'linked_biblionumbers should ignore record without biblionumber' ); + + # And a simple test with Elastic + t::lib::Mocks::mock_preference('SearchEngine', 'Elasticsearch'); + cmp_deeply( [ $auth1->linked_biblionumbers ], [ 2001 ], + 'linked_biblionumbers with Elasticsearch' ); +}; + +sub simple_search_compat { + if( $search_compat_pars->[0] == 0 ) { + return ( $search_compat_pars->[1], [], 0 ); + } elsif( $search_compat_pars->[0] == 1 ) { + my $records = C4::Context->preference('SearchEngine') eq 'Zebra' + ? few_marcxml_records() + : few_marc_records(); + return ( undef, $records, scalar @$records ); + } +} + +sub few_marcxml_records { + return [ +q| + + 1001 + + 102 + My Corporation + +|, +q| + + + + 112 + Another Corporation + +|, +q| + + 3003 + + 102 + My Corporation + +| + ]; +} + +sub few_marc_records { + my $marc = MARC::Record->new; + $marc->append_fields( + MARC::Field->new( '001', '2001' ), + MARC::Field->new( '245', '', '', a => 'Title' ), + ); + return [ $marc ]; +} + $schema->storage->txn_rollback; -- 1.7.10.4