Bug 32710: Try to prevent UI/Form/Builder/Item.t to fail randomly
[koha.git] / t / Search / buildQuery.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 Test::More;
21 use t::lib::Mocks;
22
23 use Module::Load::Conditional qw/check_install/;
24
25 BEGIN {
26     if ( check_install( module => 'Test::DBIx::Class' ) ) {
27         plan tests => 12;
28     } else {
29         plan skip_all => "Need Test::DBIx::Class"
30     }
31 }
32
33 # Mock the DB connection and C4::Context
34 use Test::DBIx::Class;
35
36 use_ok('C4::Search', qw( buildQuery ));
37 can_ok('C4::Search',
38     qw/buildQuery/);
39 use_ok("Net::Z3950::ZOOM");
40
41 #FIXME: would it be better to use our real ccl.properties file?
42 sub _get_ccl_properties {
43     my $config = q(
44         kw 1=1016
45         wrdl 4=6
46         rtrn 5=1
47         right-Truncation rtrn
48         rk 2=102
49         ti 1=4
50         title ti
51         ext 4=1 6=3
52         Title-cover 1=36
53         r1 9=32
54         r2 9=28
55         r3 9=26
56         r4 9=24
57         r5 9=22
58         r6 9=20
59         r7 9=18
60         r8 9=16
61         r9 9=14
62         phr 4=1
63         fuzzy 5=103
64         ccode 1=8009
65         nb 1=7
66         ns 1=8
67     );
68     return $config;
69 }
70
71 #FIXME: We should add QueryFuzzy and QueryStemming preferences to expand test permutations
72
73 subtest "test weighted autotruncated" => sub {
74     plan tests => 13;
75
76     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
77     t::lib::Mocks::mock_preference('QueryAutoTruncate', '1');
78
79     my $config = _get_ccl_properties();
80     my $operators = [""];
81     my $operands = ["test"];
82     my $indexes = [""];
83     my $limits = [""];
84     my $sort_by = [""];
85     my ($scan,$lang);
86
87     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
88         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
89     is($error,undef,"Error is correct");
90     is($query,'(rk=(kw,wrdl,rtrn=test )) ','Query is correct with auto truncation');
91     is($simple_query,'test',"Simple query is correct");
92     is($query_cgi,'idx=kw&q=test','Query cgi is correct');
93     is($query_desc,'kw,wrdl: test','Query desc is correct');
94     is($limit,'',"Limit is correct");
95     is($limit_cgi,'',"Limit cgi is correct");
96     is($limit_desc,'',"Limit desc is correct");
97     is($query_type,undef,"Query type is correct");
98     my $q = Net::Z3950::ZOOM::query_create();
99     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
100     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
101         $ccl_errcode, $ccl_errstr, $ccl_errpos
102     );
103     is($res,0,"created CCL2RPN query");
104     is($ccl_errcode,0);
105     is($ccl_errstr,"");
106     is($ccl_errpos,0);
107     Net::Z3950::ZOOM::query_destroy($q);
108
109 };
110
111 subtest "test* weighted autotruncated" => sub {
112     plan tests => 13;
113
114     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
115     t::lib::Mocks::mock_preference('QueryAutoTruncate', '1');
116
117     my $config = _get_ccl_properties();
118     my $operators = [""];
119     my $operands = ["test*"];
120     my $indexes = [""];
121     my $limits = [""];
122     my $sort_by = [""];
123     my ($scan,$lang);
124
125     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
126         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
127     is($error,undef,"Error is correct");
128     is($query,'(rk=(kw,wrdl,rtrn=test )) ','Query is correct with manual truncation');
129     is($simple_query,'test*',"Simple query is correct");
130     is($query_cgi,'idx=kw&q=test%2A','Query cgi is correct');
131     is($query_desc,'kw,wrdl: test*','Query desc is correct');
132     is($limit,'',"Limit is correct");
133     is($limit_cgi,'',"Limit cgi is correct");
134     is($limit_desc,'',"Limit desc is correct");
135     is($query_type,undef,"Query type is correct");
136     my $q = Net::Z3950::ZOOM::query_create();
137     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
138     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
139         $ccl_errcode, $ccl_errstr, $ccl_errpos
140     );
141     is($res,0,"created CCL2RPN query");
142     is($ccl_errcode,0);
143     is($ccl_errstr,"");
144     is($ccl_errpos,0);
145     Net::Z3950::ZOOM::query_destroy($q);
146 };
147
148 subtest "test weighted not-autotruncated" => sub {
149     plan tests => 13;
150
151     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
152     t::lib::Mocks::mock_preference('QueryAutoTruncate', '0');
153     t::lib::Mocks::mock_preference('QueryFuzzy', '1');
154
155     my $config = _get_ccl_properties();
156     my $operators = [""];
157     my $operands = ["test"];
158     my $indexes = [""];
159     my $limits = [""];
160     my $sort_by = [""];
161     my ($scan,$lang);
162
163     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
164         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
165     is($error,undef,"Error is correct");
166     is($query,'(rk=(Title-cover,ext,r1="test" or ti,ext,r2="test" or Title-cover,phr,r3="test" or ti,wrdl,r4="test" or wrdl,fuzzy,r8="test" or wrdl,right-Truncation,r9="test" or wrdl,r9="test")) ','Query is correct with weighted fields');
167     is($simple_query,'test',"Simple query is correct");
168     is($query_cgi,'idx=kw&q=test','Query cgi is correct');
169     is($query_desc,'kw,wrdl: test','Query desc is correct');
170     is($limit,'',"Limit is correct");
171     is($limit_cgi,'',"Limit cgi is correct");
172     is($limit_desc,'',"Limit desc is correct");
173     is($query_type,undef,"Query type is correct");
174     my $q = Net::Z3950::ZOOM::query_create();
175     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
176     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
177         $ccl_errcode, $ccl_errstr, $ccl_errpos
178     );
179     is($res,0,"created CCL2RPN query");
180     is($ccl_errcode,0);
181     is($ccl_errstr,"");
182     is($ccl_errpos,0);
183     Net::Z3950::ZOOM::query_destroy($q);
184 };
185
186
187 subtest "test ccode:REF weighted autotruncated" => sub {
188     plan tests => 13;
189
190     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
191     t::lib::Mocks::mock_preference('QueryAutoTruncate', '1');
192
193     my $config = _get_ccl_properties();
194     my $operators = [""];
195     my $operands = ["test"];
196     my $indexes = [""];
197     my $limits = ["ccode:REF"];
198     my $sort_by = [""];
199     my ($scan,$lang);
200
201     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
202         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
203     is($error,undef,"Error is correct");
204     is($query,'(rk=(kw,wrdl,rtrn=test )) and ccode=REF','Query is correct with auto truncation and limits');
205     is($simple_query,'test',"Simple query is correct");
206     is($query_cgi,'idx=kw&q=test','Query cgi is correct');
207     is($query_desc,'kw,wrdl: test','Query desc is correct');
208     is($limit,'and ccode=REF',"Limit is correct");
209     is($limit_cgi,'&limit=ccode%3AREF',"Limit cgi is correct");
210     is($limit_desc,'ccode:REF',"Limit desc is correct");
211     is($query_type,undef,"Query type is correct");
212     my $q = Net::Z3950::ZOOM::query_create();
213     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
214     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
215         $ccl_errcode, $ccl_errstr, $ccl_errpos
216     );
217     is($res,0,"created CCL2RPN query");
218     is($ccl_errcode,0);
219     is($ccl_errstr,"");
220     is($ccl_errpos,0);
221     Net::Z3950::ZOOM::query_destroy($q);
222 };
223
224 subtest "test ccode:REF weighted not-autotruncated" => sub {
225     plan tests => 13;
226
227     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
228     t::lib::Mocks::mock_preference('QueryAutoTruncate', '0');
229
230     my $config = _get_ccl_properties();
231     my $operators = [""];
232     my $operands = ["test"];
233     my $indexes = [""];
234     my $limits = ["ccode:REF"];
235     my $sort_by = [""];
236     my ($scan,$lang);
237
238     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
239         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
240     is($error,undef,"Error is correct");
241     is($query,'(rk=(Title-cover,ext,r1="test" or ti,ext,r2="test" or Title-cover,phr,r3="test" or ti,wrdl,r4="test" or wrdl,fuzzy,r8="test" or wrdl,right-Truncation,r9="test" or wrdl,r9="test")) and ccode=REF','Query is correct with weighted fields and limits');
242     is($simple_query,'test',"Simple query is correct");
243     is($query_cgi,'idx=kw&q=test','Query cgi is correct');
244     is($query_desc,'kw,wrdl: test','Query desc is correct');
245     is($limit,'and ccode=REF',"Limit is correct");
246     is($limit_cgi,'&limit=ccode%3AREF',"Limit cgi is correct");
247     is($limit_desc,'ccode:REF',"Limit desc is correct");
248     is($query_type,undef,"Query type is correct");
249     my $q = Net::Z3950::ZOOM::query_create();
250     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
251     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
252         $ccl_errcode, $ccl_errstr, $ccl_errpos
253     );
254     is($res,0,"created CCL2RPN query");
255     is($ccl_errcode,0);
256     is($ccl_errstr,"");
257     is($ccl_errpos,0);
258     Net::Z3950::ZOOM::query_destroy($q);
259 };
260
261 subtest "kw:one and title:two ccode:REF weighted autotruncated" => sub {
262     plan tests => 13;
263
264     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
265     t::lib::Mocks::mock_preference('QueryAutoTruncate', '1');
266
267     my $config = _get_ccl_properties();
268     my $operators = ["and"];
269     my $operands = ["one","two"];
270     my $indexes = ["kw","title"];
271     my $limits = ["ccode:REF"];
272     my $sort_by = [""];
273     my ($scan,$lang);
274
275     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
276         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
277     is($error,undef,"Error is correct");
278     is($query,'(rk=(kw,wrdl,rtrn=one )) and (rk=(title,wrdl,rtrn=two )) and ccode=REF','Query is correct with auto truncation, limits, and using indexes and operators');
279     is($simple_query,'one',"Simple query is correct?");
280     is($query_cgi,'idx=kw&q=one&op=and&idx=title&q=two','Query cgi is correct');
281     is($query_desc,'kw,wrdl: one and title,wrdl: two','Query desc is correct');
282     is($limit,'and ccode=REF',"Limit is correct");
283     is($limit_cgi,'&limit=ccode%3AREF',"Limit cgi is correct");
284     is($limit_desc,'ccode:REF',"Limit desc is correct");
285     is($query_type,undef,"Query type is correct");
286     my $q = Net::Z3950::ZOOM::query_create();
287     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
288     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
289         $ccl_errcode, $ccl_errstr, $ccl_errpos
290     );
291     is($res,0,"created CCL2RPN query");
292     is($ccl_errcode,0);
293     is($ccl_errstr,"");
294     is($ccl_errpos,0);
295     Net::Z3950::ZOOM::query_destroy($q);
296 };
297
298 subtest "one and two weighted autotruncated" => sub {
299     plan tests => 13;
300
301     t::lib::Mocks::mock_preference('QueryWeightFields', '1');
302     t::lib::Mocks::mock_preference('QueryAutoTruncate', '1');
303
304     my $config = _get_ccl_properties();
305     my $operators = [""];
306     my $operands = ["one and two"];
307     my $indexes = [""];
308     my $limits = [""];
309     my $sort_by = [""];
310     my ($scan,$lang);
311
312     my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
313         C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
314     is($error,undef,"Error is correct");
315     is($query,'(rk=(kw,wrdl,rtrn=one and two )) ','Query is correct with auto truncation and unstructured query');
316     is($simple_query,'one and two',"Simple query is correct");
317     is($query_cgi,'idx=kw&q=one%20and%20two','Query cgi is correct');
318     is($query_desc,'kw,wrdl: one and two','Query desc is correct');
319     is($limit,'',"Limit is correct");
320     is($limit_cgi,'',"Limit cgi is correct");
321     is($limit_desc,'',"Limit desc is correct");
322     is($query_type,undef,"Query type is correct");
323     my $q = Net::Z3950::ZOOM::query_create();
324     my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
325     my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
326         $ccl_errcode, $ccl_errstr, $ccl_errpos
327     );
328     is($res,0,"created CCL2RPN query");
329     is($ccl_errcode,0);
330     is($ccl_errstr,"");
331     is($ccl_errpos,0);
332     Net::Z3950::ZOOM::query_destroy($q);
333 };
334
335 subtest "test with ISBN variations" => sub {
336     plan tests => 12;
337
338     my $config = _get_ccl_properties();
339     my $operators = [""];
340     my $operands = ["1565926994"];
341     my $indexes = ["nb"];
342     my $limits = [""];
343     my $sort_by = [""];
344     my ($scan,$lang);
345
346     foreach my $sample (
347         { state => 0, query => 'nb=(rk=(1565926994)) ' },
348         { state => 1, query => 'kw,wrdl=(rk=((nb=1-56592-699-4 OR nb=1-56592-699-4 OR nb=978-1-56592-699-8 OR nb=1565926994 OR nb=9781565926998))) ' })
349     {
350         t::lib::Mocks::mock_preference('SearchWithISBNVariations', $sample->{state});
351         # Test with disabled variatioms
352         my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
353             C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
354             say 'Q: > ', $query;
355         is($error,undef,"Error is correct");
356         is($query,$sample->{query},'Search ISBN when variations is '.$sample->{state});
357         my $q = Net::Z3950::ZOOM::query_create();
358         my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
359         my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
360             $ccl_errcode, $ccl_errstr, $ccl_errpos
361         );
362         is($res,0,"created CCL2RPN query");
363         is($ccl_errcode,0);
364         is($ccl_errstr,"");
365         is($ccl_errpos,0);
366         Net::Z3950::ZOOM::query_destroy($q);
367     }
368
369 };
370
371 subtest "test with ISSN variations" => sub {
372     plan tests => 12;
373
374     my $config = _get_ccl_properties();
375     my $operators = [""];
376     my $operands = ["2434561X"];
377     my $indexes = ["ns"];
378     my $limits = [""];
379     my $sort_by = [""];
380     my ($scan,$lang);
381
382     foreach my $sample (
383         { state => 0, query => 'ns=(rk=(2434561X)) ' },
384         { state => 1, query => 'kw,wrdl=(rk=((ns=2434-561X OR ns=2434561X))) ' })
385     {
386         t::lib::Mocks::mock_preference('SearchWithISSNVariations', $sample->{state});
387         # Test with disabled variatioms
388         my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type) =
389             C4::Search::buildQuery($operators,$operands,$indexes,$limits,$sort_by,$scan,$lang);
390             say 'Q: > ', $query;
391         is($error,undef,"Error is correct");
392         is($query,$sample->{query},'Search ISSN when variations is '.$sample->{state});
393         my $q = Net::Z3950::ZOOM::query_create();
394         my ($ccl_errcode, $ccl_errstr, $ccl_errpos) = (0,"",0);
395         my $res = Net::Z3950::ZOOM::query_ccl2rpn($q, $query, $config,
396             $ccl_errcode, $ccl_errstr, $ccl_errpos
397         );
398         is($res,0,"created CCL2RPN query");
399         is($ccl_errcode,0);
400         is($ccl_errstr,"");
401         is($ccl_errpos,0);
402         Net::Z3950::ZOOM::query_destroy($q);
403     }
404
405 };