From 103e682f3ab937318069db2971f170282e6d63ed Mon Sep 17 00:00:00 2001 From: Mark Tompsett Date: Wed, 6 Jul 2016 21:37:21 -0400 Subject: [PATCH] Bug 16868: Silence error t/db_dependent/Linker_FirstMatch.t When the auth_header table has records which exclude 1xx and 2xx tags, the $bibfield doesn't match anything. This in turn sets it to undef, which triggers an error on the next line killing the test. This was completely refactored to provide the data necessary for the tests to pass, and to be more comprehensive (both MARC and UNIMARC are tested). The tests are then run. C4::Headings::authorities is mocked, so that this test is not dependent on a search engine. TEST PLAN --------- 1) back up DB 2) DELETE FROM auth_header; 3) SOURCE auth_header.sql; -- the provided file 4) prove t/db_dependent/Linker_FirstMatch.t -- should barf before running all the tests 5) apply all patches 6) prove t/db_dependent/Linker_FirstMatch.t -- should work happy 7) run koha qa test tools 8) restore your backup Followed test plan, behaves as expected. Signed-off-by: Marc --- t/db_dependent/Linker_FirstMatch.t | 155 +++++++++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 32 deletions(-) diff --git a/t/db_dependent/Linker_FirstMatch.t b/t/db_dependent/Linker_FirstMatch.t index 66c03ba..04cc6a6 100755 --- a/t/db_dependent/Linker_FirstMatch.t +++ b/t/db_dependent/Linker_FirstMatch.t @@ -1,52 +1,143 @@ #!/usr/bin/perl # -# This Koha test module is a stub! -# Add more tests here!!! +# This file is part of Koha. +# +# Copyright (C) 2011 Jared Camins-Esakov +# Copyright (C) 2016 Mark Tompsett +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use Test::More tests => 3; -use C4::Context; -use C4::Heading; + use MARC::Record; use MARC::Field; +use MARC::File::XML; +use C4::Heading; use C4::Linker::FirstMatch; - +use Test::MockModule; +use t::lib::Mocks qw( mock_preference ); +use t::lib::TestBuilder; BEGIN { - use_ok('C4::Linker'); + use_ok('C4::Linker'); } -my $dbh = C4::Context->dbh; - -my $query = "SELECT authid, marc FROM auth_header LIMIT 1;"; -my $sth = $dbh->prepare($query); -$sth->execute(); -my ($authid, $marc) = $sth->fetchrow_array(); -SKIP: { - skip "No authorities", 2 unless defined $authid; - my $linker = C4::Linker::FirstMatch->new(); - my $auth = MARC::Record->new_from_usmarc($marc); + +# Mock C4::Heading->authorities() so tests will all pass. +# This completely bypasses any search engine calls. +my $authid; +my $mock_heading = Test::MockModule->new('C4::Heading'); +$mock_heading->mock( authorities => sub { return [ { authid => $authid } ]; } ); + +# Run tests for both logic cases (UNIMARC / non-UNIMARC) +subtest 'MARC21' => sub { + plan tests => 2; + t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); + run_tests(); +}; + +subtest 'UNIMARC' => sub { + plan tests => 2; + t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' ); + run_tests(); +}; + +sub run_tests { + + # Set up just a single authority record to find and use. + my $builder = t::lib::TestBuilder->new(); + my $schema = $builder->schema(); + $schema->storage->txn_begin; + + $builder->delete( { source => 'AuthHeader' } ); + + my $auth_header = $builder->build( + { + source => 'AuthHeader' + } + ); + + $authid = $auth_header->{authid}; + + # Set the data up to match nicely. + my $marc_flavour = C4::Context->preference('MARCFlavour'); + my $auth = get_authority_record( $marc_flavour, $authid ); + my $fake_marc = $auth->as_usmarc(); + my $fake_xml = $auth->as_xml($authid); + + my $auth_header_record = $schema->resultset('AuthHeader')->find( + { + authid => $authid + } + ); + $auth_header_record->marcxml($fake_xml); + $auth_header_record->marc($fake_marc); + $auth_header_record->update; + + # Find a particular series field. my $fieldmatch; - if (C4::Context->preference('MARCFlavour') eq 'UNIMARC') { + if ( C4::Context->preference('MARCFlavour') eq 'UNIMARC' ) { $fieldmatch = '2..'; - } else { + } + else { $fieldmatch = '1..'; } my $bibfield = $auth->field($fieldmatch); - my $tag = $bibfield->tag(); - $tag =~ s/^./6/; - $bibfield->update(tag => $tag); - my $heading; - ok(defined ($heading = C4::Heading->new_from_bib_field($bibfield, '')), "Creating heading from bib field"); - # If Zebra is not running, or authorities have not been indexed, test 3 - # will fail. Skip it if we are unable to retrieve a list of headings from - # Zebra. - my @authids = $heading->authorities(1); - skip "Unable to search Zebra", 1 unless $#authids > 0; + # Convert it to a 6xx series field. + my $tag = $bibfield->tag(); + my $new_tag = $tag; + $new_tag =~ s/^./6/xsm; + my @subfields = $bibfield->subfields(); + my $new_bibfield = MARC::Field->new( + $new_tag, + $bibfield->indicator(1), + $bibfield->indicator(2), @subfields + ); + # Can we build a heading from it? + my $heading; + ok( + defined( + $heading = C4::Heading->new_from_bib_field( $new_bibfield, q{} ) + ), + 'Creating heading from bib field' + ); + + # Now test to see if C4::Linker can find it. my $authmatch; my $fuzzy; - ($authmatch, $fuzzy) = $linker->get_link($heading); - is($authmatch, $authid, "Matched existing heading"); + my $linker = C4::Linker::FirstMatch->new(); + ( $authmatch, $fuzzy ) = $linker->get_link($heading); + is( $authmatch, $authid, 'Matched existing heading' ); + + $schema->storage->txn_rollback; + + return; +} + +sub get_authority_record { + my ( $marc_flavour, $auth_id ) = @_; + my $main_heading_field = ( $marc_flavour eq 'UNIMARC' ) ? '200' : '100'; + my $auth = MARC::Record->new(); + $auth->append_fields( + MARC::Field->new( '001', $auth_id ), + MARC::Field->new( + $main_heading_field, q{ }, q{ }, + a => 'Geisel, Theodor Seuss,', + d => '1904-1991' + ) + ); + return $auth; } -- 2.1.4