1095 lines
36 KiB
Perl
Executable File
1095 lines
36 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
# This file is part of Koha.
|
|
#
|
|
# 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 <https://www.gnu.org/licenses>.
|
|
|
|
use Modern::Perl;
|
|
use Try::Tiny;
|
|
use POSIX qw(floor);
|
|
|
|
use MARC::Record;
|
|
|
|
use C4::Context;
|
|
use C4::Biblio qw( AddBiblio ModBiblio DelBiblio );
|
|
use Koha::Database;
|
|
use Koha::Biblios;
|
|
|
|
use Test::NoWarnings;
|
|
use Test::More tests => 25;
|
|
use Test::MockModule;
|
|
|
|
use Koha::MarcOverlayRules;
|
|
|
|
use t::lib::Mocks;
|
|
|
|
my $schema = Koha::Database->schema;
|
|
$schema->storage->txn_begin;
|
|
|
|
t::lib::Mocks::mock_preference( 'MARCOverlayRules', '1' );
|
|
|
|
Koha::MarcOverlayRules->search->delete;
|
|
|
|
sub build_record {
|
|
my ($fields) = @_;
|
|
my $record = MARC::Record->new;
|
|
my @marc_fields;
|
|
for my $f (@$fields) {
|
|
my $tag = $f->[0];
|
|
my @subfields;
|
|
for my $i ( 1 .. ( scalar(@$f) / 2 ) ) {
|
|
my $ii = floor( $i * 2 );
|
|
push @subfields, $f->[ $ii - 1 ], $f->[$ii];
|
|
}
|
|
push @marc_fields, MARC::Field->new( $tag, '', '', @subfields );
|
|
}
|
|
|
|
$record->append_fields(@marc_fields);
|
|
return $record;
|
|
}
|
|
|
|
# Create a record
|
|
my $orig_record = build_record(
|
|
[
|
|
[ '250', 'a', '250 bottles of beer on the wall' ],
|
|
[ '250', 'a', '256 bottles of beer on the wall' ],
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ],
|
|
]
|
|
);
|
|
|
|
my $incoming_record = build_record(
|
|
[
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # Unchanged
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # Appended
|
|
# ['250', 'a', '250 bottles of beer on the wall'], # Removed
|
|
# ['500', 'a', 'One bottle of beer in the fridge'], # Deleted
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # Added
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # Added
|
|
]
|
|
);
|
|
|
|
# Test default behavior when MARCOverlayRules is enabled, but no rules defined (overwrite)
|
|
subtest 'No rule defined' => sub {
|
|
plan tests => 1;
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Incoming record used as it with no rules defined'
|
|
);
|
|
|
|
};
|
|
|
|
my $rule = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '*',
|
|
module => 'source',
|
|
filter => '*',
|
|
add => 0,
|
|
append => 0,
|
|
remove => 0,
|
|
delete => 0
|
|
}
|
|
);
|
|
|
|
subtest 'Record fields has been protected when matched merge all rule operations are set to "0"' => sub {
|
|
plan tests => 1;
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$orig_record->as_formatted,
|
|
'Record not modified if all op=0'
|
|
);
|
|
|
|
};
|
|
|
|
subtest '"Add new" - Only new fields has been added when add = 1, append = 0, remove = 0, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 0,
|
|
'remove' => 0,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Add fields from the incoming record that are not in the original record'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Only appended fields has been added when add = 0, append = 1, remove = 0, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 1,
|
|
'remove' => 0,
|
|
'delete' => 0,
|
|
}
|
|
)->store;
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
# "251" field has been appended
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
]
|
|
);
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Add fields from the incoming record that are in the original record'
|
|
);
|
|
|
|
};
|
|
|
|
subtest '"Add and append" - add = 1, append = 1, remove = 0, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 1,
|
|
'remove' => 0,
|
|
'delete' => 0,
|
|
}
|
|
)->store;
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
# "251" field has been appended
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Appended and added fields have been added'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been only removed when add = 0, append = 0, remove = 1, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 0,
|
|
'remove' => 1,
|
|
'delete' => 0,
|
|
}
|
|
)->store;
|
|
|
|
# Warning - not obvious as the 500 is untouched
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields not in the incoming record are removed'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been added and removed when add = 1, append = 0, remove = 1, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 0,
|
|
'remove' => 1,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields not in the incoming record are removed, fields not in the original record have been added'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been appended and removed when add = 0, append = 1, remove = 1, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 1,
|
|
'remove' => 1,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended and removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields in the incoming record replace fields from the original record, fields only in the original record has been kept, fields not in the original record have been skipped'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been added, appended and removed when add = 0, append = 1, remove = 1, delete = 0' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 1,
|
|
'remove' => 1,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended and removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields in the incoming record replace fields from the original record, fields only in the original record has been kept, fields not in the original record have been added'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been deleted when add = 0, append = 0, remove = 0, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 0,
|
|
'remove' => 0,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
# FIXME the tooltip for delete is saying
|
|
# "If the original record has fields matching the rule tag, but no fields with this are found in the incoming record"
|
|
# But it does not seem to do that
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" fields have retained their original value
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Only fields in original and incoming are kept, but incoming values are ignored'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been added and deleted when add = 1, append = 0, remove = 0, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 0,
|
|
'remove' => 0,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
# Warning - is there a use case in real-life for this combination?
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field have retained their original value
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
# "500" field has been removed
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields from the incoming records are kept, but keep the value from the original record if they already existed'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been appended and deleted when add = 0, append = 1, remove = 0, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 1,
|
|
'remove' => 0,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has been removed
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Only fields that already existed are appended'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been added, appended and deleted when add = 1, append = 1, remove = 0, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 1,
|
|
'remove' => 0,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has been removed
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields in the incoming record are added and appended, fields not in the original record are removed'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been removed and deleted when add = 0, append = 0, remove = 1, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 0,
|
|
'remove' => 1,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
# "500" field has been removed
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Union'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been added, removed and deleted when add = 1, append = 0, remove = 1, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 0,
|
|
'remove' => 1,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original and incoming
|
|
# "500" field has been removed
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Union for existing fields, new fields are added'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been appended, removed and deleted when add = 0, append = 1, remove = 1, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 1,
|
|
'remove' => 1,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended and removed
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has been removed
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields from incoming replace original record. Existing fields not in incoming are removed'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'Record fields has been overwritten when add = 1, append = 1, remove = 1, delete = 1' => sub {
|
|
plan tests => 1;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 1,
|
|
'remove' => 1,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Incoming record erase original record'
|
|
);
|
|
|
|
};
|
|
|
|
subtest 'subfields order' => sub {
|
|
plan tests => 2;
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 0,
|
|
'append' => 0,
|
|
'remove' => 0,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $incoming_record = build_record(
|
|
[
|
|
[ '250', 'a', '256 bottles of beer on the wall' ],
|
|
[ '250', 'a', '250 bottles of beer on the wall' ],
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ],
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$orig_record->as_formatted,
|
|
'Original record not modified - order of subfields not modified'
|
|
);
|
|
|
|
$rule->set(
|
|
{
|
|
'add' => 1,
|
|
'append' => 1,
|
|
'remove' => 1,
|
|
'delete' => 1,
|
|
}
|
|
)->store();
|
|
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Original record modified - order of subfields has been modified'
|
|
);
|
|
|
|
};
|
|
|
|
# Test rule tag specificity
|
|
|
|
# Protect field 500 with more specific tag value
|
|
my $skip_all_rule = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '500',
|
|
module => 'source',
|
|
filter => '*',
|
|
add => 0,
|
|
append => 0,
|
|
remove => 0,
|
|
delete => 0
|
|
}
|
|
);
|
|
|
|
subtest
|
|
'"500" field has been protected when rule matching on tag "500" is add = 0, append = 0, remove = 0, delete = 0' =>
|
|
sub {
|
|
plan tests => 1;
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
# "501" fields have been added
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # incoming
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'All fields are erased by incoming record but 500 is protected'
|
|
);
|
|
|
|
};
|
|
|
|
# Test regexp matching
|
|
subtest
|
|
'"5XX" fields has been protected when rule matching on regexp "5\d{2}" is add = 0, append = 0, remove = 0, delete = 0'
|
|
=> sub {
|
|
plan tests => 1;
|
|
|
|
$skip_all_rule->set(
|
|
{
|
|
'tag' => '5\d{2}',
|
|
}
|
|
)->store;
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # incoming
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # incoming
|
|
# "500" field has retained its original value
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
]
|
|
);
|
|
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Fields are erased by incoming record but 500 is protected and 501 is not added'
|
|
);
|
|
|
|
};
|
|
|
|
$skip_all_rule->delete();
|
|
|
|
# Test module filter specificity
|
|
subtest 'Module filter precedence tests' => sub {
|
|
plan tests => 9;
|
|
|
|
$rule->set(
|
|
{
|
|
tag => '*',
|
|
module => 'source',
|
|
filter => '*',
|
|
add => 0,
|
|
append => 0,
|
|
remove => 0,
|
|
delete => 0,
|
|
}
|
|
)->store();
|
|
|
|
my $matching_filter_rule_overwrite = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '*',
|
|
module => 'source',
|
|
filter => 'test',
|
|
add => 1,
|
|
append => 1,
|
|
remove => 1,
|
|
delete => 1
|
|
}
|
|
);
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: test, tag: *, add: 1, append: 1, remove: 1, delete: 1
|
|
my $merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Non wildcard rule with wildcard tag matches and overrides wildcard rule with wildcard tag'
|
|
);
|
|
|
|
$rule->set( { tag => '5\d{2}' } )->store();
|
|
|
|
# Current rules:
|
|
# source: *, tag: 5\d{2}, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: test, tag: *, add: 1, append: 1, remove: 1, delete: 1
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Non wildcard rule with wildcard tag matches and overrides wildcard rules with regexp tags'
|
|
);
|
|
|
|
$rule->set( { tag => '501' } )->store();
|
|
|
|
# Current rules:
|
|
# source: *, tag: 501, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: test, tag: *, add: 1, append: 1, remove: 1, delete: 1
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'Non wildcard rule with wildcard tag matches and overrides wildcard rules with specific tags'
|
|
);
|
|
|
|
$rule->set( { tag => '*' } )->store();
|
|
|
|
my $wildcard_filter_rule_overwrite = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '501',
|
|
module => 'source',
|
|
filter => '*',
|
|
add => 1,
|
|
append => 1,
|
|
remove => 1,
|
|
delete => 1,
|
|
}
|
|
);
|
|
|
|
$matching_filter_rule_overwrite->set( { tag => '250' } )->store();
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 501, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # Unchanged
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # Appended
|
|
#['250', 'a', '250 bottles of beer on the wall'], # Removed
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # Protected
|
|
[ '501', 'a', 'One cold bottle of beer in the fridge' ], # Added
|
|
[ '501', 'a', 'Two cold bottles of beer in the fridge' ], # Added
|
|
]
|
|
);
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Rules have been merged when non wildcard filter context does not contain any wildcard tag rules'
|
|
);
|
|
|
|
my $matching_filter_rule_protect = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '501',
|
|
module => 'source',
|
|
filter => 'test',
|
|
add => 0,
|
|
append => 0,
|
|
remove => 0,
|
|
delete => 0
|
|
}
|
|
);
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 501, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 501, add: 0, append: 0, remove: 0, delete: 0
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
$expected_record = build_record(
|
|
[
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # Unchanged
|
|
[ '250', 'a', '251 bottles of beer on the wall' ], # Appended
|
|
#['250', 'a', '250 bottles of beer on the wall'], # Removed
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # Protected
|
|
#['501', 'a', 'One cold bottle of beer in the fridge'], # Protected
|
|
#['501', 'a', 'Two cold bottles of beer in the fridge'], # Protected
|
|
]
|
|
);
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Wildcard filter rule has been overridden by non wildcard filter rule with same tag'
|
|
);
|
|
|
|
$matching_filter_rule_protect->set(
|
|
{
|
|
tag => '5\d{2}',
|
|
}
|
|
)->store();
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 501, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 5\d{2}, add: 0, append: 0, remove: 0, delete: 0
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Wildcard filter rules with tags that matches tag regexps for non wildcard filter rules has been overridden'
|
|
);
|
|
|
|
$wildcard_filter_rule_overwrite->set(
|
|
{
|
|
tag => '5\d{2}',
|
|
}
|
|
)->store();
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 5\d{2}, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 5\d{2}, add: 0, append: 0, remove: 0, delete: 0
|
|
$merged_record = Koha::MarcOverlayRules->merge_records( $orig_record, $incoming_record, { 'source' => 'test' } );
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
'Wildcard filter rules with tags with tag regexps matching the same tag as regexps for non wildcard filter rules has been overridden'
|
|
);
|
|
|
|
my $categorycode_matching_filter_rule_protect = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '*',
|
|
module => 'categorycode',
|
|
filter => 'C',
|
|
add => 0,
|
|
append => 0,
|
|
remove => 0,
|
|
delete => 0
|
|
}
|
|
);
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 5\d{2}, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 5\d{2}, add: 0, append: 0, remove: 0, delete: 0
|
|
# categorycode: C, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
$merged_record = Koha::MarcOverlayRules->merge_records(
|
|
$orig_record,
|
|
$incoming_record,
|
|
{ 'source' => 'test', 'categorycode' => 'C' }
|
|
);
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$orig_record->as_formatted,
|
|
'If both categorycode and source module contexts matches, rules from categorycode module context are used'
|
|
);
|
|
|
|
my $userid_matching_filter_rule_protect = Koha::MarcOverlayRules->find_or_create(
|
|
{
|
|
tag => '*',
|
|
module => 'userid',
|
|
filter => '123',
|
|
add => 1,
|
|
append => 1,
|
|
remove => 1,
|
|
delete => 1
|
|
}
|
|
);
|
|
|
|
# Current rules:
|
|
# source: *, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# source: *, tag: 5\d{2}, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 250, add: 1, append: 1, remove: 1, delete: 1
|
|
# source: test, tag: 5\d{2}, add: 0, append: 0, remove: 0, delete: 0
|
|
# categorycode: C, tag: *, add: 0, append: 0, remove: 0, delete: 0
|
|
# userid: 123, tag: *, add: 1, append: 1, remove: 1, delete: 1
|
|
$merged_record = Koha::MarcOverlayRules->merge_records(
|
|
$orig_record,
|
|
$incoming_record,
|
|
{ 'source' => 'test', 'categorycode' => 'C', 'userid' => '123' }
|
|
);
|
|
|
|
is(
|
|
$merged_record->as_formatted,
|
|
$incoming_record->as_formatted,
|
|
'If both userid, categorycode and source module contexts matches, rules from userid module context are used'
|
|
);
|
|
|
|
$categorycode_matching_filter_rule_protect->delete();
|
|
$userid_matching_filter_rule_protect->delete();
|
|
$wildcard_filter_rule_overwrite->delete();
|
|
$matching_filter_rule_overwrite->delete();
|
|
$matching_filter_rule_protect->delete();
|
|
};
|
|
|
|
subtest 'An exception is thrown when append = 1, remove = 0 is set for control field rule' => sub {
|
|
plan tests => 2;
|
|
my $exception = try {
|
|
Koha::MarcOverlayRules->validate(
|
|
{
|
|
'tag' => '008',
|
|
'append' => 1,
|
|
'remove' => 0,
|
|
}
|
|
);
|
|
} catch {
|
|
return $_;
|
|
};
|
|
ok( defined $exception, "Exception was caught" );
|
|
ok(
|
|
$exception->isa('Koha::Exceptions::MarcOverlayRule::InvalidControlFieldActions'),
|
|
"Exception is of correct class"
|
|
);
|
|
};
|
|
|
|
subtest 'An exception is thrown when rule tag is set to invalid regexp' => sub {
|
|
plan tests => 2;
|
|
|
|
my $exception = try {
|
|
Koha::MarcOverlayRules->validate( { 'tag' => '**' } );
|
|
} catch {
|
|
return $_;
|
|
};
|
|
ok( defined $exception, "Exception was caught" );
|
|
ok( $exception->isa('Koha::Exceptions::MarcOverlayRule::InvalidTagRegExp'), "Exception is of correct class" );
|
|
};
|
|
|
|
subtest 'context option in ModBiblio is handled correctly' => sub {
|
|
plan tests => 2;
|
|
|
|
$rule->set(
|
|
{
|
|
tag => '250',
|
|
module => 'source',
|
|
filter => '*',
|
|
'add' => 0,
|
|
'append' => 0,
|
|
'remove' => 0,
|
|
'delete' => 0,
|
|
}
|
|
)->store();
|
|
|
|
my ( $biblionumber, $biblioitemnumber ) = AddBiblio( $orig_record, '' );
|
|
|
|
# Since marc merc rules are not run on save, only update
|
|
# saved record should be identical to orig_record
|
|
my $biblio = Koha::Biblios->find($biblionumber);
|
|
my $saved_record = $biblio->metadata->record;
|
|
|
|
my @all_fields = $saved_record->fields();
|
|
|
|
# Koha also adds 999c field, therefore 4 not 3
|
|
|
|
my $expected_record = build_record(
|
|
[
|
|
# "250" field has been appended
|
|
[ '250', 'a', '250 bottles of beer on the wall' ], # original
|
|
[ '250', 'a', '256 bottles of beer on the wall' ], # original
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ], # original
|
|
[ '999', 'c', $biblionumber, 'd', $biblioitemnumber ], # created by AddBiblio
|
|
]
|
|
);
|
|
|
|
# Remove timestamp from saved record when comparing
|
|
$saved_record->delete_fields( $saved_record->field('005') );
|
|
|
|
# Make sure leader is equal after AddBiblio
|
|
$expected_record->leader( $saved_record->leader() );
|
|
|
|
is(
|
|
$saved_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
);
|
|
|
|
$saved_record->append_fields(
|
|
MARC::Field->new( '250', '', '', 'a' => '251 bottles of beer on the wall' ), # Appended
|
|
MARC::Field->new( '500', '', '', 'a' => 'One cold bottle of beer in the fridge' ), # Appended
|
|
);
|
|
|
|
ModBiblio( $saved_record, $biblionumber, '', { overlay_context => { 'source' => 'test' } } );
|
|
|
|
my $updated_record = $biblio->get_from_storage->metadata->record;
|
|
|
|
$expected_record = build_record(
|
|
[
|
|
# "250" field has been protected
|
|
[ '250', 'a', '250 bottles of beer on the wall' ],
|
|
[ '250', 'a', '256 bottles of beer on the wall' ],
|
|
[ '500', 'a', 'One bottle of beer in the fridge' ],
|
|
|
|
# "500" field has been appended
|
|
[ '500', 'a', 'One cold bottle of beer in the fridge' ],
|
|
[ '999', 'c', $biblionumber, 'd', $biblioitemnumber ], # created by AddBiblio
|
|
]
|
|
);
|
|
|
|
# Remove timestamp from saved record when comparing
|
|
$updated_record->delete_fields( $updated_record->field('005') );
|
|
|
|
# Make sure leader is equal after ModBiblio
|
|
$expected_record->leader( $updated_record->leader() );
|
|
|
|
is(
|
|
$updated_record->as_formatted,
|
|
$expected_record->as_formatted,
|
|
);
|
|
|
|
# To trigger removal from search index etc
|
|
DelBiblio($biblionumber);
|
|
};
|
|
|
|
# Explicitly delete rule to trigger clearing of cache
|
|
$rule->delete();
|
|
|
|
$schema->storage->txn_rollback;
|