Koha/t/db_dependent/AuthoritiesMarc.t
Ere Maijala 016bb29b60 Bug 21958: Fix bibliographic record field comparison with authority
This makes the comparison between bibliographic field and authority field more robust and per subfield. This makes the comparison not consider the same e.g. the following fields:

$a Test User
$a Test $b User

The actual issue cannot be as easily reproduced with the patches for bug 21826 applied, but here's a test plan anyway:

1. Make sure tests pass (especially t/db_dependent/AuthoritiesMarc*)
2. Make sure authority linking still works properly
3. Make sure authority and biblio frameworks allow subfield i
4. Make sure that even if you add subfield i to 700 in biblio, authority link is kept the same
5. Make sure that even if you add subfield i to the authority record, the authority link is kept the same

Signed-off-by: Frank Hansen <frank.hansen@ub.lu.se>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
2021-04-01 17:13:56 +02:00

309 lines
9.4 KiB
Perl
Executable file

#!/usr/bin/perl
#
# This Koha test module is a stub!
# Add more tests here!!!
use Modern::Perl;
use Test::More tests => 12;
use Test::MockModule;
use Test::Warn;
use MARC::Field;
use MARC::Record;
use t::lib::Mocks;
use t::lib::TestBuilder;
use Koha::Database;
use Koha::Authority::Types;
BEGIN {
use_ok('C4::AuthoritiesMarc');
}
# We are now going to be testing the authorities hierarchy code, and
# therefore need to pretend that we have consistent data in our database
my $module = Test::MockModule->new('C4::AuthoritiesMarc');
$module->mock('GetHeaderAuthority', sub {
return {'authtrees' => ''};
});
$module->mock('AddAuthorityTrees', sub {
return;
});
$module->mock('GetAuthority', sub {
my ($authid) = @_;
my $record = MARC::Record->new();
if ($authid eq '1') {
$record->add_fields(
[ '001', '1' ],
[ '151', ' ', ' ', a => 'United States' ]
);
} elsif ($authid eq '2') {
$record->add_fields(
[ '001', '2' ],
[ '151', ' ', ' ', a => 'New York (State)' ],
[ '551', ' ', ' ', a => 'United States', w => 'g', 9 => '1' ]
);
} elsif ($authid eq '3') {
$record->add_fields(
[ '001', '3' ],
[ '151', ' ', ' ', a => 'New York (City)' ],
[ '551', ' ', ' ', a => 'New York (State)', w => 'g', 9 => '2' ]
);
} elsif ($authid eq '4') {
$record->add_fields(
[ '001', '4' ],
[ '151', ' ', ' ', a => 'New York (City)' ],
[ '551', ' ', ' ', a => 'New York (State)', w => 'g' ]
);
} elsif ($authid eq '5') {
$record->add_fields(
[ '001', '5' ],
[ '100', ' ', ' ', a => 'Lastname, Firstname', b => 'b', c => 'c', i => 'i' ]
);
} else {
undef $record;
}
return $record;
});
my $schema = Koha::Database->new->schema;
$schema->storage->txn_begin;
my $dbh = C4::Context->dbh;
my $builder = t::lib::TestBuilder->new;
t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
# Authority type GEOGR_NAME is hardcoded here
if( ! Koha::Authority::Types->find('GEOGR_NAME') ) {
$builder->build({ source => 'AuthType', value => { authtypecode => 'GEOGR_NAME' }});
};
is(BuildAuthHierarchies(3, 1), '1,2,3', "Built linked authtrees hierarchy string");
my $expectedhierarchy = [ [ {
'authid' => '1',
'value' => 'United States',
'class' => 'child0',
'children' => [ {
'authid' => '2',
'value' => 'New York (State)',
'class' => 'child1',
'children' => [ {
'authid' => '3',
'current_value' => 1,
'value' => 'New York (City)',
'class' => 'child2',
'children' => [],
'parents' => [ {
'authid' => '2',
'value' => 'New York (State)'
} ]
} ],
'parents' => [ {
'authid' => '1',
'value' => 'United States'
} ]
} ],
'parents' => []
} ] ];
is_deeply(GenerateHierarchy(3), $expectedhierarchy, "Generated hierarchy data structure for linked hierarchy");
is(BuildAuthHierarchies(4, 1), '4', "Built unlinked authtrees hierarchy string");
$expectedhierarchy = [ [ {
'authid' => '4',
'current_value' => 1,
'value' => 'New York (City)',
'class' => 'child0',
'children' => [],
'parents' => []
} ] ];
is_deeply(GenerateHierarchy(4), $expectedhierarchy, "Generated hierarchy data structure for unlinked hierarchy");
# set up auth_types for next tests
$dbh->do('DELETE FROM auth_types');
$dbh->do(q{
INSERT INTO auth_types (authtypecode, authtypetext, auth_tag_to_report, summary)
VALUES ('GEOGR_NAME', 'Geographic Name', '151', 'Geographic Name')
});
t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
my $expected_marc21_summary = {
'authorized' => [
{
'field' => '151',
'heading' => 'New York (State)',
'hemain' => 'New York (State)'
}
],
'authtypecode' => 'GEOGR_NAME',
'mainentry' => 'New York (State)',
'mainmainentry' => 'New York (State)',
'notes' => [],
'otherscript' => [],
'seealso' => [
{
'authid' => '1',
'field' => '551',
'heading' => 'United States',
'hemain' => 'United States',
'search' => 'United States',
'type' => 'broader'
}
],
'seefrom' => [],
'label' => 'Geographic Name',
'type' => 'Geographic Name'
};
is_deeply(
BuildSummary(C4::AuthoritiesMarc::GetAuthority(2), 2, 'GEOGR_NAME'),
$expected_marc21_summary,
'test BuildSummary for MARC21'
);
my $marc21_subdiv = MARC::Record->new();
$marc21_subdiv->add_fields(
[ '181', ' ', ' ', x => 'Political aspects' ]
);
warning_is { BuildSummary($marc21_subdiv, 99999, 'GEN_SUBDIV') } [],
'BuildSummary does not generate warning if main heading subfield not present';
t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
$dbh->do(q{
INSERT INTO auth_types (authtypecode, authtypetext, auth_tag_to_report, summary)
VALUES ('NP', 'Auteur', '200', '[200a][, 200b][ 200d][ ; 200c][ (200f)]')
});
my $unimarc_name_auth = MARC::Record->new();
$unimarc_name_auth->add_fields(
['100', ' ', ' ', a => '20121025 frey50 '],
['200', ' ', ' ', a => 'Fossey', b => 'Brigitte' ],
['152', ' ', ' ', a => 'NP'],
);
my $expected_unimarc_name_summary = {
'authorized' => [
{
'field' => '200',
'heading' => 'Fossey Brigitte',
'hemain' => 'Fossey'
}
],
'authtypecode' => 'NP',
'mainentry' => 'Fossey Brigitte',
'mainmainentry' => 'Fossey',
'notes' => [],
'otherscript' => [],
'seealso' => [],
'seefrom' => [],
'summary' => 'Fossey, Brigitte',
'type' => 'Auteur'
};
is_deeply(
BuildSummary($unimarc_name_auth, 99999, 'NP'),
$expected_unimarc_name_summary,
'test BuildSummary for UNIMARC'
);
subtest 'AddAuthority should respect AUTO_INCREMENT (BZ 18104)' => sub {
plan tests => 3;
t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
my $record = C4::AuthoritiesMarc::GetAuthority(1);
my $id1 = AddAuthority( $record, undef, 'GEOGR_NAME' );
DelAuthority({ authid => $id1 });
my $id2 = AddAuthority( $record, undef, 'GEOGR_NAME' );
isnt( $id1, $id2, 'Do not return the same id again' );
t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
my $id3 = AddAuthority( $record, undef, 'GEOGR_NAME' );
ok( $id3 > 0, 'Tested AddAuthority with UNIMARC' );
is( $record->field('001')->data, $id3, 'Check updated 001' );
};
subtest 'CompareFieldWithAuthority tests' => sub {
plan tests => 3;
t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
$builder->build({ source => 'AuthType', value => { authtypecode => 'PERSO_NAME' }});
my $field = MARC::Field->new('100', 0, 0, a => 'Lastname, Firstname', b => 'b', c => 'c');
ok(C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Authority matches');
$field->add_subfields(i => 'X');
ok(C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Compare ignores unlisted subfields');
$field->add_subfields(d => 'd');
ok(!C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Authority does not match');
};
$schema->storage->txn_rollback;
$module->unmock('GetAuthority');
subtest 'ModAuthority() tests' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $auth_type = 'GEOGR_NAME';
my $record = MARC::Record->new;
$record->add_fields(
[ '001', '1' ],
[ '151', ' ', ' ', a => 'United States' ]
);
;
my $auth_id = AddAuthority( $record, undef, $auth_type );
my $mocked_authorities_marc = Test::MockModule->new('C4::AuthoritiesMarc');
$mocked_authorities_marc->mock( 'merge', sub { warn 'merge called'; } );
warning_is
{ ModAuthority( $auth_id, $record, $auth_type ); }
'merge called',
'No param, merge called';
warning_is
{ ModAuthority( $auth_id, $record, $auth_type, { skip_merge => 1 } ); }
undef,
'skip_merge passed, merge not called';
$schema->storage->txn_rollback;
};
subtest 'DelAuthority() tests' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $auth_type = 'GEOGR_NAME';
my $record = MARC::Record->new;
$record->add_fields(
[ '001', '1' ],
[ '151', ' ', ' ', a => 'United States' ]
);
;
my $auth_id = AddAuthority( $record, undef, $auth_type );
my $mocked_authorities_marc = Test::MockModule->new('C4::AuthoritiesMarc');
$mocked_authorities_marc->mock( 'merge', sub { warn 'merge called'; } );
warning_is
{ DelAuthority({ authid => $auth_id }); }
'merge called',
'No param, merge called';
$auth_id = AddAuthority( $record, undef, $auth_type );
warning_is
{ DelAuthority({ authid => $auth_id, skip_merge => 1 }); }
undef,
'skip_merge passed, merge not called';
$schema->storage->txn_rollback;
};