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