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

(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-6 / +6 lines)
Lines 292-298 sub build_query_compat { Link Here
292
        my $ea = each_array( @$operands, @$operators, @index_params );
292
        my $ea = each_array( @$operands, @$operators, @index_params );
293
        while ( my ( $oand, $otor, $index ) = $ea->() ) {
293
        while ( my ( $oand, $otor, $index ) = $ea->() ) {
294
            next if ( !defined($oand) || $oand eq '' );
294
            next if ( !defined($oand) || $oand eq '' );
295
            $oand = $self->_clean_search_term($oand);
295
            $oand = $self->clean_search_term($oand);
296
            $oand = $self->_truncate_terms($oand) if ($truncate);
296
            $oand = $self->_truncate_terms($oand) if ($truncate);
297
            push @search_params, {
297
            push @search_params, {
298
                operand => $oand,      # the search terms
298
                operand => $oand,      # the search terms
Lines 445-451 sub build_authorities_query { Link Here
445
            my @tokens = $self->_split_query( $val );
445
            my @tokens = $self->_split_query( $val );
446
            foreach my $token ( @tokens ) {
446
            foreach my $token ( @tokens ) {
447
                $token = $self->_truncate_terms(
447
                $token = $self->_truncate_terms(
448
                    $self->_clean_search_term( $token )
448
                    $self->clean_search_term( $token )
449
                );
449
                );
450
            }
450
            }
451
            my $query = $self->_join_queries( @tokens );
451
            my $query = $self->_join_queries( @tokens );
Lines 644-650 sub _build_scan_query { Link Here
644
            terms => {
644
            terms => {
645
                field => $index . '__facet',
645
                field => $index . '__facet',
646
                order => { '_term' => 'asc' },
646
                order => { '_term' => 'asc' },
647
                include => $self->_create_regex_filter($self->_clean_search_term($term)) . '.*'
647
                include => $self->_create_regex_filter($self->clean_search_term($term)) . '.*'
648
            }
648
            }
649
        }
649
        }
650
    };
650
    };
Lines 909-917 sub _create_query_string { Link Here
909
    } @queries;
909
    } @queries;
910
}
910
}
911
911
912
=head2 _clean_search_term
912
=head2 clean_search_term
913
913
914
    my $term = $self->_clean_search_term($term);
914
    my $term = $self->clean_search_term($term);
915
915
916
This cleans a search term by removing any funny characters that may upset
916
This cleans a search term by removing any funny characters that may upset
917
ES and give us an error. It also calls L<_convert_index_strings_freeform>
917
ES and give us an error. It also calls L<_convert_index_strings_freeform>
Lines 919-925 to ensure those parts are correct. Link Here
919
919
920
=cut
920
=cut
921
921
922
sub _clean_search_term {
922
sub clean_search_term {
923
    my ( $self, $term ) = @_;
923
    my ( $self, $term ) = @_;
924
924
925
    # Lookahead for checking if we are inside quotes
925
    # Lookahead for checking if we are inside quotes
(-)a/t/Koha/SearchEngine/Elasticsearch/QueryBuilder.t (-25 / +24 lines)
Lines 186-192 subtest '_split_query() tests' => sub { Link Here
186
    is_deeply(\@res, \@exp, 'quoted search terms surrounded by spaces correctly');
186
    is_deeply(\@res, \@exp, 'quoted search terms surrounded by spaces correctly');
187
};
187
};
188
188
189
subtest '_clean_search_term() tests' => sub {
189
subtest 'clean_search_term() tests' => sub {
190
    plan tests => 24;
190
    plan tests => 24;
191
191
192
    my $qb;
192
    my $qb;
Lines 197-273 subtest '_clean_search_term() tests' => sub { Link Here
197
197
198
    t::lib::Mocks::mock_preference('QueryAutoTruncate', 0);
198
    t::lib::Mocks::mock_preference('QueryAutoTruncate', 0);
199
199
200
    my $res = $qb->_clean_search_term('an=123');
200
    my $res = $qb->clean_search_term('an=123');
201
    is($res, 'koha-auth-number:123', 'equals sign replaced with colon');
201
    is($res, 'koha-auth-number:123', 'equals sign replaced with colon');
202
202
203
    $res = $qb->_clean_search_term('"balanced quotes"');
203
    $res = $qb->clean_search_term('"balanced quotes"');
204
    is($res, '"balanced quotes"', 'balanced quotes returned correctly');
204
    is($res, '"balanced quotes"', 'balanced quotes returned correctly');
205
205
206
    $res = $qb->_clean_search_term('unbalanced quotes"');
206
    $res = $qb->clean_search_term('unbalanced quotes"');
207
    is($res, 'unbalanced quotes ', 'unbalanced quotes removed');
207
    is($res, 'unbalanced quotes ', 'unbalanced quotes removed');
208
208
209
    $res = $qb->_clean_search_term('"unbalanced "quotes"');
209
    $res = $qb->clean_search_term('"unbalanced "quotes"');
210
    is($res, ' unbalanced  quotes ', 'unbalanced quotes removed');
210
    is($res, ' unbalanced  quotes ', 'unbalanced quotes removed');
211
211
212
    $res = $qb->_clean_search_term(':test query');
212
    $res = $qb->clean_search_term(':test query');
213
    is($res, 'test query', 'remove colon at the start');
213
    is($res, 'test query', 'remove colon at the start');
214
214
215
    $res = $qb->_clean_search_term('test query\:');
215
    $res = $qb->clean_search_term('test query\:');
216
    is($res, 'test query', 'remove colon at the end');
216
    is($res, 'test query', 'remove colon at the end');
217
217
218
    $res = $qb->_clean_search_term('test : query');
218
    $res = $qb->clean_search_term('test : query');
219
    is($res, 'test query', 'dangling colon removed');
219
    is($res, 'test query', 'dangling colon removed');
220
220
221
    $res = $qb->_clean_search_term('test :: query');
221
    $res = $qb->clean_search_term('test :: query');
222
    is($res, 'test query', 'dangling double colon removed');
222
    is($res, 'test query', 'dangling double colon removed');
223
223
224
    $res = $qb->_clean_search_term('test "another : query"');
224
    $res = $qb->clean_search_term('test "another : query"');
225
    is($res, 'test "another : query"', 'quoted dangling colon not removed');
225
    is($res, 'test "another : query"', 'quoted dangling colon not removed');
226
226
227
    $res = $qb->_clean_search_term('host-item:test:n');
227
    $res = $qb->clean_search_term('host-item:test:n');
228
    is($res, 'host-item:test\:n', 'screen colons properly');
228
    is($res, 'host-item:test\:n', 'screen colons properly');
229
229
230
    $res = $qb->_clean_search_term('host-item:test:n:test:and more');
230
    $res = $qb->clean_search_term('host-item:test:n:test:and more');
231
    is($res, 'host-item:test\:n\:test\:and more', 'screen multiple colons properly');
231
    is($res, 'host-item:test\:n\:test\:and more', 'screen multiple colons properly');
232
232
233
    $res = $qb->_clean_search_term('host-item:te st:n');
233
    $res = $qb->clean_search_term('host-item:te st:n');
234
    is($res, 'host-item:te st:n', 'leave colons as they are');
234
    is($res, 'host-item:te st:n', 'leave colons as they are');
235
235
236
    $res = $qb->_clean_search_term('test!');
236
    $res = $qb->clean_search_term('test!');
237
    is($res, 'test', 'remove exclamation sign at the end of the line');
237
    is($res, 'test', 'remove exclamation sign at the end of the line');
238
238
239
    $res = $qb->_clean_search_term('test! and more');
239
    $res = $qb->clean_search_term('test! and more');
240
    is($res, 'test and more', 'remove exclamation sign at with space after it');
240
    is($res, 'test and more', 'remove exclamation sign at with space after it');
241
241
242
    $res = $qb->_clean_search_term('!test');
242
    $res = $qb->clean_search_term('!test');
243
    is($res, '!test', 'exclamation sign left untouched');
243
    is($res, '!test', 'exclamation sign left untouched');
244
244
245
    $res = $qb->_clean_search_term('test [123 TO 345]');
245
    $res = $qb->clean_search_term('test [123 TO 345]');
246
    is($res, 'test [123 TO 345]', 'keep inculsive range untouched');
246
    is($res, 'test [123 TO 345]', 'keep inculsive range untouched');
247
247
248
    $res = $qb->_clean_search_term('test [test TO TEST} [and] {123 TO 456]');
248
    $res = $qb->clean_search_term('test [test TO TEST} [and] {123 TO 456]');
249
    is($res, 'test [test TO TEST} \[and\] {123 TO 456]', 'keep exclusive range untouched');
249
    is($res, 'test [test TO TEST} \[and\] {123 TO 456]', 'keep exclusive range untouched');
250
250
251
    $res = $qb->_clean_search_term('test [test TO TEST} ["[and] {123 TO 456]" "[balanced]"]');
251
    $res = $qb->clean_search_term('test [test TO TEST} ["[and] {123 TO 456]" "[balanced]"]');
252
    is($res, 'test [test TO TEST} \["[and] {123 TO 456]" "[balanced]"\]', 'keep exclusive range untouched');
252
    is($res, 'test [test TO TEST} \["[and] {123 TO 456]" "[balanced]"\]', 'keep exclusive range untouched');
253
253
254
    $res = $qb->_clean_search_term('test[]test TO TEST] [ {123 to 345}}');
254
    $res = $qb->clean_search_term('test[]test TO TEST] [ {123 to 345}}');
255
    is($res, 'test\[\]test TO TEST\] \[ \{123 to 345\}\}', 'screen all square and curly brackets');
255
    is($res, 'test\[\]test TO TEST\] \[ \{123 to 345\}\}', 'screen all square and curly brackets');
256
256
257
    t::lib::Mocks::mock_preference('QueryRegexEscapeOptions', 'escape');
257
    t::lib::Mocks::mock_preference('QueryRegexEscapeOptions', 'escape');
258
258
259
    $res = $qb->_clean_search_term('test inside regexps /this [a-z]/ and \/not [a-z]\/ and that [a-z] [a TO z]');
259
    $res = $qb->clean_search_term('test inside regexps /this [a-z]/ and \/not [a-z]\/ and that [a-z] [a TO z]');
260
    is($res, 'test inside regexps \/this \[a-z\]\/ and \/not \[a-z\]\/ and that \[a-z\] [a TO z]', 'behaviour with QueryRegexEscapeOptions set to "escape"');
260
    is($res, 'test inside regexps \/this \[a-z\]\/ and \/not \[a-z\]\/ and that \[a-z\] [a TO z]', 'behaviour with QueryRegexEscapeOptions set to "escape"');
261
261
262
    t::lib::Mocks::mock_preference('QueryRegexEscapeOptions', 'dont_escape');
262
    t::lib::Mocks::mock_preference('QueryRegexEscapeOptions', 'dont_escape');
263
263
264
    $res = $qb->_clean_search_term('test inside regexps /this [a-z]/ /this2 [a-z]/ [but] /this3 [a-z]/ and \/not [a-z]\/ and that [a-z] [a TO z]');
264
    $res = $qb->clean_search_term('test inside regexps /this [a-z]/ /this2 [a-z]/ [but] /this3 [a-z]/ and \/not [a-z]\/ and that [a-z] [a TO z]');
265
    is($res, 'test inside regexps /this [a-z]/ /this2 [a-z]/ \[but\] /this3 [a-z]/ and \/not \[a-z\]\/ and that \[a-z\] [a TO z]', 'behaviour with QueryRegexEscapeOptions set to "dont_escape"');
265
    is($res, 'test inside regexps /this [a-z]/ /this2 [a-z]/ \[but\] /this3 [a-z]/ and \/not \[a-z\]\/ and that \[a-z\] [a TO z]', 'behaviour with QueryRegexEscapeOptions set to "dont_escape"');
266
266
267
    $res = $qb->_clean_search_term('ti:test AND kw:test');
267
    $res = $qb->clean_search_term('ti:test AND kw:test');
268
    is($res, 'title:test AND test', 'ti converted to title, kw converted to empty string, dangling colon removed with space preserved');
268
    is($res, 'title:test AND test', 'ti converted to title, kw converted to empty string, dangling colon removed with space preserved');
269
269
270
    $res = $qb->_clean_search_term('kw:test');
270
    $res = $qb->clean_search_term('kw:test');
271
    is($res, 'test', 'kw converted to empty string, dangling colon is removed');
271
    is($res, 'test', 'kw converted to empty string, dangling colon is removed');
272
};
272
};
273
273
274
- 

Return to bug 28316