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

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

Return to bug 26031