Bug 34549: Strip non-XML chars during TransformHtmlToMarc
[koha.git] / t / db_dependent / Biblio / TransformHtmlToMarc.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use CGI;
5 use Encode qw( encode );
6 use Test::More tests => 2;
7
8 use Koha::Caches;
9 use Koha::Database;
10 use Koha::MarcSubfieldStructures;
11 use C4::Biblio qw( GetMarcFromKohaField TransformHtmlToMarc );
12
13 our ( $biblionumbertagfield, $biblionumbertagsubfield );
14 my $schema  = Koha::Database->new->schema;
15 $schema->storage->txn_begin;
16
17 # Move field for biblionumber to imaginary 399
18 Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'biblio.biblionumber' })->delete;
19 Koha::MarcSubfieldStructures->search({ frameworkcode => '', tagfield => '399', tagsubfield => 'a' })->delete;
20 Koha::MarcSubfieldStructure->new({ frameworkcode => '', tagfield => '399', tagsubfield => 'a', kohafield => "biblio.biblionumber" })->store;
21 Koha::Caches->get_instance->clear_from_cache( "MarcSubfieldStructure-" );
22 ( $biblionumbertagfield, $biblionumbertagsubfield ) = C4::Biblio::GetMarcFromKohaField( "biblio.biblionumber" );
23
24 subtest 'Biblio record' => sub {
25     plan tests => 20;
26     my $leader = '00203nam a2200097   4500';
27     my $input  = CGI->new;
28     $input->param( -name => 'biblionumber',                                        -value => '42' );
29     $input->param( -name => 'tag_000_indicator1_570367553534',                     -value => '' );
30     $input->param( -name => 'tag_000_indicator2_570367553534',                     -value => '' );
31     $input->param( -name => 'tag_000_code_00_570367_810561',                       -value => '' );
32     $input->param( -name => 'tag_000_subfield_00_570367_810561',                   -value => $leader );
33     $input->param( -name => 'tag_010_indicator1_493056',                           -value => '' );
34     $input->param( -name => 'tag_010_indicator2_493056',                           -value => '' );
35     $input->param( -name => 'tag_010_code_a_493056_296409',                        -value => 'a' );
36     $input->param( -name => 'tag_010_subfield_a_493056_296409',                    -value => Encode::encode( 'utf-8', "first isbn é" ) );
37     $input->param( -name => 'tag_010_indicator1_49305613979',                      -value => '' );
38     $input->param( -name => 'tag_010_indicator2_49305613979',                      -value => '' );
39     $input->param( -name => 'tag_010_code_a_493056_29640913979',                   -value => 'a' );
40     $input->param( -name => 'tag_010_subfield_a_493056_29640913979',               -value => Encode::encode( 'utf-8', "second isbn à" ) );    # 2 010 fields
41     $input->param( -name => 'tag_100_indicator1_588794844868',                     -value => '' );
42     $input->param( -name => 'tag_100_indicator2_588794844868',                     -value => '' );
43     $input->param( -name => 'tag_100_code_a_588794_15537',                         -value => 'a' );
44     $input->param( -name => 'tag_100_subfield_a_588794_15537',                     -value => '20160112d        u||y0frey5050    ba' );
45     $input->param( -name => 'tag_200_indicator1_593269251146',                     -value => '' );
46     $input->param( -name => 'tag_200_indicator2_593269251146',                     -value => '' );
47     $input->param( -name => 'tag_200_code_a_593269_944056',                        -value => 'a' );
48     $input->param( -name => 'tag_200_subfield_a_593269_944056',                    -value => 'first title' );                                  # 2 200$a in the same field
49     $input->param( -name => 'tag_200_code_a_593269_94405618065',                   -value => 'a' );
50     $input->param( -name => 'tag_200_subfield_a_593269_94405618065',               -value => 'second title' );
51     $input->param( -name => 'tag_200_code_b_593269_250538',                        -value => 'b' );
52     $input->param( -name => 'tag_200_subfield_b_593269_250538',                    -value => 'DVD' );
53     $input->param( -name => 'tag_200_code_f_593269_445603',                        -value => 'f' );
54     $input->param( -name => 'tag_200_subfield_f_593269_445603',                    -value => 'author' );
55     $input->param( -name => 'tag_200_code_h_593269_616594',                        -value => 'h' );                                            # Empty field
56     $input->param( -name => 'tag_200_subfield_h_593269_616594',                    -value => '' );
57
58     # Add a field 390 before our 399
59     $input->param( -name => "tag_390_indicator1_123", -value => "" );
60     $input->param( -name => "tag_390_indicator2_123", -value => "" );
61     $input->param( -name => "tag_390_code_a_123", -value => 'a' );
62     $input->param( -name => "tag_390_subfield_a_123", -value => '390a' );
63
64     # Our imaginary biblionumber field in 399
65     $input->param( -name => "tag_${biblionumbertagfield}_indicator1_588794844868", -value => "" );
66     $input->param( -name => "tag_${biblionumbertagfield}_indicator2_588794844868", -value => "" );
67     $input->param( -name => "tag_${biblionumbertagfield}_code_${biblionumbertagsubfield}_588794_784323",     -value => $biblionumbertagsubfield );
68     $input->param( -name => "tag_${biblionumbertagfield}_subfield_${biblionumbertagsubfield}_588794_784323", -value => $biblionumbertagfield );
69
70     # A field (490) after 399
71     $input->param( -name => "tag_490_indicator1_1123", -value => "" );
72     $input->param( -name => "tag_490_indicator2_1123", -value => "" );
73     $input->param( -name => "tag_490_code_b_1123", -value => 'b' );
74     $input->param( -name => "tag_490_subfield_b_1123", -value => '490b' );
75
76     # A field (900) after 490
77     $input->param( -name => "tag_900_indicator1_1123", -value => "" );
78     $input->param( -name => "tag_900_indicator2_1123", -value => "" );
79     $input->param( -name => "tag_900_code_a_1123",     -value => 'a' );
80     $input->param( -name => "tag_900_subfield_a_1123", -value => "This string has bad \x{1B}characters in it" );
81
82     my $record = C4::Biblio::TransformHtmlToMarc($input, 1);
83
84     my @all_fields = $record->fields;
85     is( @all_fields, 8, 'The record should have been created with 8 fields' );
86         # biblionumber + 2x010 + 100 + 200 + 390 + 490
87     my @fields_010 = $record->field('010');
88     is( @fields_010, 2, 'The record should have been created with 2 010' );
89     my @fields_100 = $record->field('100');
90     is( @fields_100, 1, 'The record should have been created with 1 100' );
91     my @fields_200 = $record->field('200');
92     is( @fields_200, 1, 'The record should have been created with 1 200' );
93
94     is_deeply( $fields_010[0]->subfields(), [ 'a', 'first isbn é' ],  'The first isbn should be correct' );
95     is_deeply( $fields_010[1]->subfields(), [ 'a', 'second isbn à' ], 'The second isbn should be correct' );
96
97     my @subfields_200_a = $record->subfield( 200, 'a' );
98     is( @subfields_200_a, 2, 'The record should have been created with 2 200$a' );
99     is_deeply( \@subfields_200_a, [ 'first title', 'second title' ], 'The 2 titles should have been kept in the correct order' );
100
101     my @fields_900 = $record->field('900');
102     is( @fields_900, 1, 'The record should have been created with 1 900' );
103     is_deeply(
104         $fields_900[0]->subfields(), [ 'a', 'This string has bad characters in it' ],
105         'Field 900 had its non-XML characters stripped'
106     );
107
108     my @subfields_biblionumber = $record->subfield( $biblionumbertagfield, $biblionumbertagsubfield );
109     is( @subfields_biblionumber, 1, 'The record should contain only one biblionumber field' );
110
111     is( $record->leader, $leader, 'The leader should have been kept' );
112
113     # Check the order of some fields
114     is( $all_fields[0]->tag, '010', 'First field expected 010' );
115     is( $all_fields[1]->tag, '010', 'Second field also 010' );
116     is( $all_fields[2]->tag, '100', 'Third field is 100' );
117     is( $all_fields[3]->tag, '200', 'Fourth field is 200' );
118     is( $all_fields[4]->tag, '390', 'Fifth field is 390' );
119     is( $all_fields[5]->subfield('a'), 42, 'Sixth field contains bibnumber' );
120     is( $all_fields[6]->tag, '490', 'Last field is 490' );
121
122     my $new_record   = eval { MARC::Record::new_from_xml( $record->as_xml(), 'UTF-8' ); };
123     my $record_error = $@;
124     ok( !$record_error, 'No errors parsing MARCXML generated by TransformHtmlToMarc' );
125
126 };
127
128 subtest 'Add authority record' => sub {
129     plan tests => 1;
130
131     my $input = CGI->new;
132     $input->param( -name => 'tag_200_indicator1_906288',                                                     -value => '' );
133     $input->param( -name => 'tag_200_indicator2_906288',                                                     -value => '' );
134     $input->param( -name => 'tag_200_code_a_906288_722171',                                                  -value => 'a' );
135     $input->param( -name => 'tag_200_subfield_a_906288_722171',                                              -value => 'a 200$a' );
136     $input->param( -name => 'tag_200_code_b_906288_611549',                                                  -value => 'b' );
137     $input->param( -name => 'tag_200_subfield_b_906288_611549',                                              -value => 'a 200$b' );
138     $input->param( -name => "tag_${biblionumbertagfield}_indicator1_198510",                                 -value => "" );
139     $input->param( -name => "tag_${biblionumbertagfield}_indicator2_198510",                                 -value => "" );
140     $input->param( -name => "tag_${biblionumbertagfield}_code_${biblionumbertagsubfield}_198510_886205",     -value => $biblionumbertagsubfield );
141     $input->param( -name => "tag_${biblionumbertagfield}_subfield_${biblionumbertagsubfield}_198510_886205", -value => "a biblionumber which is not a biblionumber" );
142
143     my $record = C4::Biblio::TransformHtmlToMarc($input, 0);
144
145     my @subfields_biblionumber = $record->subfield( $biblionumbertagfield, $biblionumbertagsubfield );
146     is( @subfields_biblionumber, 1, 'The record should contain the field which are mapped to biblio.biblionumber' );
147 };
148
149 Koha::Caches->get_instance->clear_from_cache( "MarcSubfieldStructure-" );
150 $schema->storage->txn_rollback;