Bug 16960 - Patron::Modifications should be fixed
[koha.git] / t / db_dependent / XSLT_Handler.t
1 #!/usr/bin/perl
2
3 # Copyright 2014 Rijksmuseum
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use Modern::Perl;
21
22 use FindBin;
23 use File::Slurp;
24 use Test::More tests => 40;
25 use Test::Warn;
26
27 use Koha::XSLT_Handler;
28
29 my $engine=Koha::XSLT_Handler->new;
30 is( ref $engine, 'Koha::XSLT_Handler', 'Testing creation of handler object' );
31
32 warning_is { $engine->transform('') } #we passed no file at first time
33             "No XSLT file passed.",
34             "No XSLT warning correctly displayed";
35 is( $engine->err, 1, 'Engine returns error on no file' );
36
37 warning_is { $engine->transform( '', 'thisfileshouldnotexist.%$#@' ) }
38             "XSLT file not found.",
39             "No XSLT warning correctly displayed";
40 is( $engine->err, 2, 'Engine returns error on bad file' );
41 is( $engine->refresh( 'asdjhaskjh'), 0, 'Test on invalid refresh' );
42
43 #check first test xsl
44 my $path= $FindBin::Bin.'/XSLT_Handler/';
45 my $xsltfile_1 = 'test01.xsl';
46 is( -e $path.$xsltfile_1, 1, "Found my test stylesheet $xsltfile_1" );
47 exit if !-e $path.$xsltfile_1;
48 $xsltfile_1= $path.$xsltfile_1;
49
50 #Testing not-xml strings (undef, empty, some text, malformed xml
51 my $output;
52
53 # Undefined text tests
54 warning_is { $output = $engine->transform( undef, $xsltfile_1 ) }
55            "No string to transform.",
56            "No string warning correctly displayed";
57 is( $engine->err, 7, 'Engine returns error on undefined text' );
58
59 # Empty string tests
60 warning_is { $output = $engine->transform( '', $xsltfile_1 ) }
61            "Error while parsing input: Empty String",
62            "Empty string warning correctly displayed";
63 is( $engine->err, 5, 'Engine returns error on empty string' );
64
65 # Non-XML tests
66 warning_like { $output = $engine->transform( 'abcdef', $xsltfile_1 ) }
67            qr{^Error while parsing input: :1: parser error : Start tag expected, '<' not found},
68            "Non-XML warning correctly displayed";
69 is( $engine->err, 5, 'Engine returns error on non-xml' );
70
71 # Malformed XML tests
72 warning_like { $output = $engine->transform( '<a></b>', $xsltfile_1 ) }
73              qr{^Error while parsing input: :1: parser error : Opening and ending tag mismatch: a line 1 and b},
74              "Malformed XML warning correctly displayed";
75 is( $engine->err, 5, 'Engine returns error on malformed xml' );
76
77 #Test not returning source on failure when asked for
78 #Include passing do_not_return via constructor on second engine
79 my $secondengine=Koha::XSLT_Handler->new( {
80     do_not_return_source => 'very_true',
81     some_unknown_attrib  => 'just_for_fun',
82 });
83 $engine->do_not_return_source(1);
84 warning_like { $output = $engine->transform( '<a></b>', $xsltfile_1 ) }
85              qr{^Error while parsing input: :1: parser error : Opening and ending tag mismatch: a line 1 and b},
86              "Malformed XML warning correctly displayed";
87 is( defined $output? 1: 0, 0, 'Engine respects do_not_return_source==1');
88 warning_like { $output = $secondengine->transform( '<a></b>', $xsltfile_1 ) }
89              qr{^Error while parsing input: :1: parser error : Opening and ending tag mismatch: a line 1 and b},
90              "Malformed XML warning correctly displayed";
91 is( defined $output? 1: 0, 0, 'Second engine respects it too');
92 undef $secondengine; #bye
93 $engine->do_not_return_source(0);
94 warning_like { $output = $engine->transform( '<a></b>', $xsltfile_1 ) }
95              qr{^Error while parsing input: :1: parser error : Opening and ending tag mismatch: a line 1 and b},
96              "Malformed XML warning correctly displayed";
97 is( defined $output? 1: 0, 1, 'Engine respects do_not_return_source==0');
98
99 #Testing valid refresh now
100 is( $engine->refresh($xsltfile_1), 1, 'Test on valid refresh' );
101 #A second time (for all) should return 0 now
102 is( $engine->refresh, 0, 'Test on repeated refresh' );
103
104 #Testing a string that should not change too much
105 my $xml_1=<<'EOT';
106 <just_a_tagname>
107 </just_a_tagname>
108 EOT
109 $output= $engine->transform( $xml_1, $xsltfile_1 );
110 is( $engine->err, undef, 'Engine returned no error for xml_1' );
111 is( index($output,'<just_a_tagname>')>0, 1, 'No real change expected for xml_1' ); #Just very simple check if the tag was still there
112
113 #Test of adding a new datafield to rudimentary 'marc record'
114 my $xml_2=<<'EOT';
115 <?xml version="1.0" encoding="UTF-8"?>
116 <collection>
117 <record>
118 <controlfield tag="001">1234</controlfield>
119 <datafield tag="245" ind1="1" ind2="0"><subfield tag="a">My favorite title</subfield></datafield>
120 </record>
121 </collection>
122 EOT
123 $output= $engine->transform( $xml_2 );
124     #note: second parameter (file) not passed again
125 is( $engine->err, undef, 'Engine returned no error for xml_2' );
126 is( index($output,'I saw you')>0, 1, 'Saw the expected change for xml_2' ); #Just very simple check if new datafield was added
127 #Test alternative parameter passing
128 my $output2;
129 $output2 = $engine->transform( { file => $xsltfile_1, xml => $xml_2 } );
130 is( $output, $output2, 'Try hash parameter file');
131 my $code = read_file( $xsltfile_1 );
132 $output2 = $engine->transform( { code => $code, xml => $xml_2 } );
133 is( $output, $output2, 'Try hash parameter code');
134 #Check rerun on last code
135 $output2 = $engine->transform( $xml_2 );
136 is( $output, $output2, 'Rerun on previous passed code');
137
138 #The second test xsl contains bad code
139 my $xsltfile_2 = 'test02.xsl';
140 is( -e $path.$xsltfile_2, 1, "Found my test stylesheet $xsltfile_2" );
141 exit if !-e $path.$xsltfile_2;
142 $xsltfile_2= $path.$xsltfile_2;
143
144 warning_like { $output = $engine->transform( $xml_2, $xsltfile_2 ) }
145              qr{^Error while parsing stylesheet:},
146              "Bad XSL warning correctly displayed";
147 is( $engine->err, 4, 'Engine returned error for parsing bad xsl' );
148 is( defined($engine->errstr), 1, 'Error string contains text');
149
150 #The third test xsl is okay again; main use is clearing two items from cache
151 my $xsltfile_3 = 'test03.xsl';
152 is( -e $path.$xsltfile_3, 1, "Found my test stylesheet $xsltfile_3" );
153 exit if !-e $path.$xsltfile_3;
154 $xsltfile_3= $path.$xsltfile_3;
155 $output= $engine->transform( $xml_2, $xsltfile_3 );
156 is( $engine->err, undef, 'Unexpected error on transform with third xsl' );
157 is( $engine->refresh, 3, 'Final test on clearing cache' );
158
159 my $xsltfile_4 = 'test04.xsl';
160 is( -e $path.$xsltfile_4, 1, "Found my test stylesheet $xsltfile_4" );
161 exit if !-e $path.$xsltfile_4;
162 $xsltfile_4 = $path.$xsltfile_4;
163
164 my $parameters = { injected_variable => "'this is a test'",};
165 $output = $engine->transform({
166             xml => $xml_1,
167             file => $xsltfile_4,
168             parameters => $parameters,
169         });
170 require XML::LibXML;
171 my $dom = XML::LibXML->load_xml(string => $output);
172 my $result = $dom->find( '/just_a_tagname' );
173 is ( $result->to_literal(), 'this is a test', "Successfully injected string into XSLT parameter/variable");
174
175 $output = $engine->transform({
176             xml => $xml_1,
177             file => $xsltfile_4,
178         });
179 $dom = XML::LibXML->load_xml(string => $output);
180 $result = $dom->find( '/just_a_tagname' );
181 is ( $result->to_literal(), '', "As expected, no XSLT parameters/variables were added");
182 #End of tests