View | Details | Raw Unified | Return to bug 35104
Collapse All | Expand All

(-)a/t/db_dependent/Biblio.t (-13 / +22 lines)
Lines 1204-1232 subtest 'GetFrameworkCode' => sub { Link Here
1204
1204
1205
};
1205
};
1206
1206
1207
subtest 'ModBiblio on invalid record' => sub {
1207
subtest 'ModBiblio on record with strippable non-XML characters' => sub {
1208
    plan tests => 3;
1208
    plan tests => 4;
1209
1209
1210
    t::lib::Mocks::mock_preference( "CataloguingLog", 1 );
1210
    t::lib::Mocks::mock_preference( "CataloguingLog", 1 );
1211
1211
1212
    # We create a record with an onvalid control character in the MARC
1212
    # We create a record with an invalid control character (chr(31)) in the MARC
1213
    my $record = MARC::Record->new();
1213
    my $record = MARC::Record->new();
1214
    my $field  = MARC::Field->new( '650', '', '', 'a' => '00aD000015937' );
1214
    my $field  = MARC::Field->new( '650', '', '', 'a' => '00' . chr(31) . 'aD000015937' );
1215
    $record->append_fields($field);
1215
    $record->append_fields($field);
1216
1216
1217
    my ($biblionumber) = C4::Biblio::AddBiblio( $record, '' );
1217
    my ($biblionumber) = C4::Biblio::AddBiblio( $record, '' );
1218
1218
1219
    warning_like { C4::Biblio::ModBiblio( $record, $biblionumber, '' ); }
1219
    # New behaviour: strippable non-XML characters are silently fixed; the
1220
    qr/parser error : PCDATA invalid Char value 31/,
1220
    # stripping event is reported via the warnings arrayref, not Perl warn()
1221
        'Modding the biblio warns about the encoding issues';
1221
    my @warnings;
1222
    my $action_logs =
1222
    C4::Biblio::ModBiblio( $record, $biblionumber, '', { warnings => \@warnings } );
1223
        Koha::ActionLogs->search( { object => $biblionumber, module => 'Cataloguing', action => 'MODIFY' } );
1223
    like(
1224
    is( $action_logs->count, 1, "Modification of biblio was successful and recorded" );
1224
        $warnings[0]{message}, qr/650\$a: invalid char value 31 \(U\+001F\) at position \d+/,
1225
    my $action_log = $action_logs->next;
1225
        'Non-XML character stripping reported via warnings arrayref with field and char context'
1226
    );
1227
1228
    my $metadata      = Koha::Biblios->find($biblionumber)->metadata;
1229
    my @nonxml_errors = $metadata->metadata_errors->search( { error_type => 'nonxml_stripped' } )->as_list;
1230
    ok( scalar @nonxml_errors, 'nonxml_stripped errors persisted in biblio_metadata_errors after ModBiblio' );
1226
    like(
1231
    like(
1227
        $action_log->info, qr/parser error : PCDATA invalid Char value 31/,
1232
        $nonxml_errors[0]->message, qr/650\$a: invalid char value 31 \(U\+001F\) at position \d+/,
1228
        "Metadata issue successfully logged in action logs"
1233
        'error message identifies field, char value, and position'
1229
    );
1234
    );
1235
1236
    my $action_logs =
1237
        Koha::ActionLogs->search( { object => $biblionumber, module => 'Cataloguing', action => 'MODIFY' } );
1238
    is( $action_logs->count, 1, "Modification of biblio was successfully recorded in action logs" );
1230
};
1239
};
1231
1240
1232
subtest 'UpdateTotalIssues on Invalid record' => sub {
1241
subtest 'UpdateTotalIssues on Invalid record' => sub {
(-)a/t/db_dependent/Exporter/Record.t (-4 / +2 lines)
Lines 77-86 if ( $marcflavour eq 'UNIMARC' ) { Link Here
77
    $homebranch_subfield_code = 'a';
77
    $homebranch_subfield_code = 'a';
78
}
78
}
79
79
80
my $bad_biblio = Koha::Biblio->new()->store();
80
my $bad_biblio = $builder->build_sample_biblio;
81
Koha::Biblio::Metadata->new(
81
$bad_biblio->metadata->_result->update( { metadata => 'something wrong' } );
82
    { biblionumber => $bad_biblio->id, format => 'marcxml', metadata => 'something wrong', schema => $marcflavour } )
83
    ->store();
84
my $bad_biblionumber = $bad_biblio->id;
82
my $bad_biblionumber = $bad_biblio->id;
85
83
86
my $item_1_1 = $builder->build_sample_item(
84
my $item_1_1 = $builder->build_sample_item(
(-)a/t/db_dependent/Koha/Biblio/Metadata.t (-21 / +35 lines)
Lines 18-24 Link Here
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::NoWarnings;
20
use Test::NoWarnings;
21
use Test::More tests => 6;
21
use Test::More tests => 7;
22
use Test::Exception;
22
use Test::Exception;
23
use Test::MockModule;
23
use Test::MockModule;
24
use Test::Warn;
24
use Test::Warn;
Lines 28-33 use t::lib::Mocks; Link Here
28
28
29
use C4::Biblio qw( AddBiblio );
29
use C4::Biblio qw( AddBiblio );
30
use Koha::Database;
30
use Koha::Database;
31
use MARC::Record;
32
use MARC::Field;
31
33
32
BEGIN {
34
BEGIN {
33
    use_ok('Koha::Biblio::Metadatas');
35
    use_ok('Koha::Biblio::Metadatas');
Lines 73-112 EOX Link Here
73
75
74
        lives_ok { $record->store }
76
        lives_ok { $record->store }
75
        'Valid MARCXML record stores successfully';
77
        'Valid MARCXML record stores successfully';
78
        is(
79
            $record->metadata_errors->search( { error_type => 'nonxml_stripped' } )->count,
80
            0, 'No nonxml_stripped error for clean record'
81
        );
76
82
77
        $schema->storage->txn_rollback;
83
        $schema->storage->txn_rollback;
78
    };
84
    };
79
85
80
    subtest 'Invalid MARCXML handling' => sub {
86
    subtest 'MARCXML with strippable non-XML characters' => sub {
87
        plan tests => 4;
81
        $schema->storage->txn_begin;
88
        $schema->storage->txn_begin;
82
        my $invalid_marcxml = <<'EOX';
89
83
<?xml version="1.0" encoding="UTF-8"?>
90
        # Build MARCXML containing a non-XML control character (chr(31) = Unit Separator)
84
<record xmlns="http://www.loc.gov/MARC21/slim">
91
        my $bad_title   = 'Title with' . chr(31) . ' bad character';
85
  <leader>00925nam a22002411a 4500</leader>
92
        my $clean_title = 'Title with bad character';
86
  <controlfield tag="001">1234567</controlfield>
93
87
  <datafield tag="245" ind1="1" ind2="0">
94
        # Generate the MARCXML string with the embedded bad character
88
    <subfield code="a">This string will  break your record</subfield>
95
        my $marc_record = MARC::Record->new;
89
  </datafield>
96
        $marc_record->append_fields( MARC::Field->new( '245', '', '', 'a' => $bad_title ) );
90
  <!-- Invalid XML structure -->
97
        my $marcxml_with_bad_char = $marc_record->as_xml_record('MARC21');
91
</record>
92
EOX
93
98
94
        my $record = Koha::Biblio::Metadata->new(
99
        my $record = Koha::Biblio::Metadata->new(
95
            {
100
            {
96
                format       => 'marcxml',
101
                format       => 'marcxml',
97
                metadata     => $invalid_marcxml,
102
                metadata     => $marcxml_with_bad_char,
98
                biblionumber => $biblio->{biblionumber},
103
                biblionumber => $biblio->{biblionumber},
99
                schema       => 'MARC21',
104
                schema       => 'MARC21',
100
            }
105
            }
101
        );
106
        );
102
107
103
        throws_ok { $record->store }
108
        lives_ok { $record->store } 'MARCXML with strippable characters stores successfully';
104
        'Koha::Exceptions::Metadata::Invalid',
109
105
            'Invalid MARCXML throws expected exception';
110
        my @errors = $record->metadata_errors->search( { error_type => 'nonxml_stripped' } )->as_list;
111
        ok( scalar @errors, 'nonxml_stripped error(s) recorded after stripping' );
112
        like(
113
            $errors[0]->message,
114
            qr/245\$a: invalid char value 31 \(U\+001F\) at position \d+/,
115
            'error message identifies field, char value, and position'
116
        );
117
118
        my $stored = Koha::Biblio::Metadatas->find( { biblionumber => $biblio->{biblionumber}, format => 'marcxml' } );
119
        is(
120
            $stored->record->field('245')->subfield('a'),
121
            $clean_title,
122
            'Stored record has control character removed'
123
        );
106
124
107
        my $thrown = $@;
108
        ok( $thrown->decoding_error, 'Exception contains decoding error message' );
109
        is( $thrown->biblionumber, $biblio->{biblionumber}, 'Exception contains correct biblionumber' );
110
        $schema->storage->txn_rollback;
125
        $schema->storage->txn_rollback;
111
    };
126
    };
112
127
113
- 

Return to bug 35104