Bug 18984: Remove NORMARC support
[srvgit] / t / db_dependent / www / search_utf8.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use utf8;
21 use Test::More; #See plan tests => \d+ below
22 use Test::WWW::Mechanize;
23 use Data::Dumper;
24 use XML::Simple;
25 use JSON;
26 use File::Basename;
27 use File::Path;
28 use File::Spec;
29 use File::Temp qw/ tempdir /;
30 use POSIX;
31 use Encode;
32 use URI::Escape;
33
34 use C4::Context;
35
36 my $testdir = File::Spec->rel2abs( dirname(__FILE__) );
37 # global variables that will be used when forking
38 our $zebra_pid;
39 our $indexer_pid;
40 our $datadir = tempdir();;
41
42 my $koha_conf = $ENV{KOHA_CONF};
43 my $xml       = XMLin($koha_conf);
44
45 my $marcflavour = C4::Context->preference('marcflavour') || 'MARC21';
46
47 my $file1 =
48   $marcflavour eq 'UNIMARC'
49   ? "$testdir/data/unimarcutf8record.mrc"
50   : "$testdir/data/marc21utf8record.mrc";
51
52 my $file2 =
53   $marcflavour eq 'UNIMARC'
54   ? "$testdir/data/unimarclatin1utf8rec.mrc"
55   : "$testdir/data/marc21latin1utf8rec.mrc";
56
57 my $file3 =
58   $marcflavour eq 'UNIMARC'
59   ? "$testdir/data/unimarcutf8supprec.mrc"
60   : "$testdir/data/marc21utf8supprec.mrc";
61
62 my $user     = $ENV{KOHA_USER} || $xml->{config}->{user};
63 my $password = $ENV{KOHA_PASS} || $xml->{config}->{pass};
64 my $intranet = $ENV{KOHA_INTRANET_URL};
65 my $opac     = $ENV{KOHA_OPAC_URL};
66
67
68 # test KOHA_INTRANET_URL is set
69 if ( not $intranet ) {
70    plan skip_all => "Tests skip. You must set env. variable KOHA_INTRANET_URL to do tests\n";
71 }
72 # test KOHA_OPAC_URL is set
73 elsif ( not $opac ) {
74    plan skip_all => "Tests skip. You must set env. variable KOHA_OPAC_URL to do tests\n";
75 }
76 else {
77     plan tests => 87;
78 }
79
80 $intranet =~ s#/$##;
81 $opac     =~ s#/$##;
82
83 #-------------------------------- Test with greek and corean chars;
84 # launch the zebra saerch process
85 launch_zebra( $datadir, $koha_conf );
86 if ( not defined $zebra_pid ) {
87     plan skip_all => "Tests skip. Error starting Zebra Server to do those tests\n";
88 }
89 # launch the zebra index process
90 launch_indexer( );
91 if ( not defined $indexer_pid ) {
92     plan skip_all => "Tests skip. Error starting the indexer daemon to do those tests\n";
93 }
94
95 my $utf8_reg1 = qr/学協会. μμ/;
96 test_search($file1,'Αθήνα', 'deuteros', $utf8_reg1);
97
98
99 #--------------------------------- Test with only utf-8 chars in the latin-1 range;
100 launch_zebra( $datadir, $koha_conf );
101 if ( not defined $zebra_pid ) {
102     plan skip_all => "Tests skip. Error starting Zebra Server to do those tests\n";
103 }
104 launch_indexer( );
105 if ( not defined $indexer_pid ) {
106     plan skip_all => "Tests skip. Error starting the indexer daemon to do those tests\n";
107 }
108 my $utf8_reg2 = qr/Tòmas/;
109 test_search($file2,'Ramòn', 'Tòmas',$utf8_reg2);
110
111 #--------------------------------- Test with supplementary utf-8 chars;
112 launch_zebra( $datadir, $koha_conf );
113 if ( not defined $zebra_pid ) {
114     plan skip_all => "Tests skip. Error starting Zebra Server to do those tests\n";
115 }
116 launch_indexer( );
117 if ( not defined $indexer_pid ) {
118     plan skip_all => "Tests skip. Error starting the indexer daemon to do those tests\n";
119 }
120 my $utf8_reg3 = qr/😀/;
121 test_search($file3, "𠻺tomasito𠻺", 'A tiny record', $utf8_reg3);
122
123 sub test_search{
124     #Params
125     my $file = $_[0];
126     my $publisher = $_[1];
127     my $search_key = $_[2];
128     my $utf8_reg = $_[3];
129
130     my $agent = Test::WWW::Mechanize->new( autocheck => 1 );
131     my $jsonresponse;
132
133     # -------------------------------------------------- LOAD RECORD
134
135     $agent->get_ok( "$intranet/cgi-bin/koha/mainpage.pl", 'connect to intranet' );
136     $agent->form_name('loginform');
137     $agent->field( 'password', $password );
138     $agent->field( 'userid',   $user );
139     $agent->field( 'branch',   '' );
140     $agent->click_ok( '', 'login to staff interface' );
141
142     $agent->get_ok( "$intranet/cgi-bin/koha/mainpage.pl", 'load main page' );
143
144     $agent->follow_link_ok( { url_regex => qr/tools-home/i }, 'open tools module' );
145     $agent->follow_link_ok( { text => 'Stage MARC records for import' },
146         'go to stage MARC' );
147
148     $agent->post(
149         "$intranet/cgi-bin/koha/tools/upload-file.pl?temp=1",
150         [ 'fileToUpload' => [$file], ],
151         'Content_Type' => 'form-data',
152     );
153     ok( $agent->success, 'uploaded file' );
154
155     $jsonresponse = decode_json $agent->content();
156     is( $jsonresponse->{'status'}, 'done', 'upload succeeded' );
157     my $fileid = $jsonresponse->{'fileid'};
158
159     $agent->get_ok( "$intranet/cgi-bin/koha/tools/stage-marc-import.pl",
160         'reopen stage MARC page' );
161     $agent->submit_form_ok(
162         {
163             form_number => 5,
164             fields      => {
165                 'uploadedfileid'  => $fileid,
166                 'nomatch_action'  => 'create_new',
167                 'overlay_action'  => 'replace',
168                 'item_action'     => 'always_add',
169                 'matcher'         => '',
170                 'comments'        => '',
171                 'encoding'        => 'utf8',
172                 'parse_items'     => '1',
173                 'runinbackground' => '1',
174                 'record_type'     => 'biblio'
175             }
176         },
177         'stage MARC'
178     );
179
180     $jsonresponse = decode_json $agent->content();
181     my $jobID = $jsonresponse->{'jobID'};
182     ok( $jobID, 'have job ID' );
183
184     my $completed = 0;
185
186     # if we haven't completed the batch in two minutes, it's not happening
187     for my $counter ( 1 .. 24 ) {
188         $agent->get(
189             "$intranet/cgi-bin/koha/tools/background-job-progress.pl?jobID=$jobID"
190         ); # get job progress
191         $jsonresponse = decode_json $agent->content();
192         if ( $jsonresponse->{'job_status'} eq 'completed' ) {
193             $completed = 1;
194             last;
195         }
196         warn(
197             (
198                 $jsonresponse->{'job_size'}
199                 ? floor(
200                     100 * $jsonresponse->{'progress'} / $jsonresponse->{'job_size'}
201                   )
202                 : '100'
203             )
204             . "% completed"
205         );
206         sleep 5;
207     }
208     is( $jsonresponse->{'job_status'}, 'completed', 'job was completed' );
209
210     $agent->get_ok(
211         "$intranet/cgi-bin/koha/tools/stage-marc-import.pl",
212         'reopen stage MARC page at end of upload'
213     );
214     $agent->submit_form_ok(
215         {
216             form_number => 5,
217             fields      => {
218                 'uploadedfileid'  => $fileid,
219                 'nomatch_action'  => 'create_new',
220                 'overlay_action'  => 'replace',
221                 'item_action'     => 'always_add',
222                 'matcher'         => '1',
223                 'comments'        => '',
224                 'encoding'        => 'utf8',
225                 'parse_items'     => '1',
226                 'runinbackground' => '1',
227                 'completedJobID'  => $jobID,
228                 'record_type'     => 'biblio'
229             }
230         },
231         'stage MARC'
232     );
233
234     $agent->follow_link_ok( { text => 'Manage staged records' }, 'view batch' );
235
236
237     $agent->form_number(6);
238     $agent->field( 'framework', '' );
239     $agent->click_ok( 'mainformsubmit', "imported records into catalog" );
240     my $webpage = $agent->{content};
241
242     $webpage =~ /(.*<title>.*?)(\d{1,})(.*<\/title>)/sx;
243     my $id_batch = $2;
244     my $id_bib_number = GetBiblionumberFromImport($id_batch);
245
246     # wait enough time for the indexer
247     sleep 10;
248
249     # --------------------------------- TEST INTRANET SEARCH
250
251
252     $agent->get_ok( "$intranet/cgi-bin/koha/catalogue/search.pl" , "got search on intranet");
253     $agent->form_number(5);
254     $agent->field('idx', 'kw');
255     $agent->field('q', $search_key);
256     $agent->click();
257     my $intra_text = $agent->text() ;
258
259     $agent->get_ok( "$intranet/cgi-bin/koha/catalogue/search.pl" , "got search on intranet");
260     $agent->form_number(5);
261     $agent->field('idx', 'kw');
262     $agent->field('q', $publisher);
263     $agent->click();
264     $intra_text = $agent->text();
265
266     my $expected_base = q|search.pl\?advsearch=1&idx=kw&q=| . uri_escape_utf8( $publisher );
267     $agent->base_like(qr|$expected_base|, );
268
269     ok ( ( length(Encode::encode('UTF-8', $intra_text)) != length($intra_text) ) , 'UTF-8 are multi-byte. Good') ;
270     ok ($intra_text =~  $utf8_reg, 'UTF-8 chars are correctly present. Good');
271     # -------------------------------------------------- TEST ON OPAC
272
273     $agent->get_ok( "$opac" , "got opac");
274     $agent->form_name('searchform');
275     $agent->field( 'q',   $search_key );
276     $agent->field( 'idx',   '' );
277     $agent->click( );
278     my $opac_text = $agent->text() ;
279
280     $agent->get_ok( "$opac" , "got opac");
281     $agent->form_name('searchform');
282     $agent->field('q', $publisher);
283     $agent->field( 'idx',   '' );
284     $agent->click();
285     $opac_text = $agent->text();
286
287     $expected_base = q|opac-search.pl\?(idx=&)?q=| . uri_escape_utf8( $publisher );
288     $agent->base_like(qr|$expected_base|, );
289     # Test added on BZ 14909 in addition to making the empty idx= optional
290     # in the previous regex
291     $agent->base_unlike( qr|idx=\w+|, 'Base does not contain an idx' );
292
293
294     ok ( ( length(Encode::encode('UTF-8', $opac_text)) != length($opac_text) ) , 'UTF-8 are multi-byte. Good') ;
295     ok ($opac_text =~  $utf8_reg, 'UTF-8 chars are correctly present. Good');
296
297     #-------------------------------------------------- REVERT
298
299     $agent->get_ok( "$intranet/cgi-bin/koha/tools/manage-marc-import.pl", 'view and clean batch' );
300     $agent->form_name('clean_batch_'.$id_batch);
301     $agent->click();
302     $agent->get_ok( "$intranet/cgi-bin/koha/catalogue/detail.pl?biblionumber=$id_bib_number", 'biblio on intranet' );
303     $agent->get_ok( "$intranet/cgi-bin/koha/cataloguing/addbiblio.pl?op=delete&biblionumber=$id_bib_number", 'biblio deleted' );
304
305     # clean
306     cleanup();
307 }
308
309
310 # function that launches the zebra daemon
311 sub launch_zebra {
312
313     my ( $datadir, $koha_conf ) = @_;
314
315     $zebra_pid = fork();
316     if ( $zebra_pid == 0 ) {
317         exec("zebrasrv -f $koha_conf -v none,request -l $datadir/zebra.log");
318         exit;
319     }
320     sleep( 1 );
321 }
322
323 sub launch_indexer {
324
325     my $rootdir       = dirname(__FILE__) . '/../../../';
326     my $rebuild_zebra = "$rootdir/misc/migration_tools/rebuild_zebra.pl";
327
328     $indexer_pid = fork();
329
330     if ( $indexer_pid == 0 ) {
331         exec("$rebuild_zebra -daemon -sleep 5");
332         exit;
333     }
334     sleep( 1 );
335 }
336
337 sub cleanup {
338
339     kill 9, $zebra_pid   if defined $zebra_pid;
340     kill 9, $indexer_pid if defined $indexer_pid;
341     # Clean up the Zebra files since the child process was just shot
342     rmtree $datadir;
343
344 }
345
346 sub GetBiblionumberFromImport{
347     my ( $batch_id) = @_;
348     use C4::ImportBatch;
349     my $data = C4::ImportBatch::GetImportRecordsRange($batch_id, '', '', undef,
350                     { order_by => 'import_record_id', order_by_direction => 'DESC' });
351     my $biblionumber = $data->[0]->{'matched_biblionumber'};
352
353     return $biblionumber;
354 }
355
356 END {
357     cleanup();
358 };
359