From 4367e30fa4c8f1736c2d3f1f14b61e829e66cdd9 Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Wed, 14 Nov 2018 14:02:12 +0200 Subject: [PATCH] Bug 19365: Clean up, fix and add new tests. Moved db_dependent tests to the proper directory in the hierarchy, fixed tests to check correct results now that the authority query builder works better and added several new tests to cover changed functionality. Signed-off-by: Martin Renvoize --- Koha/SearchEngine/Elasticsearch/Search.pm | 2 +- t/Koha/SearchEngine/Elasticsearch/Indexer.t | 78 ++++ .../SearchEngine/Elasticsearch/Indexer.t} | 0 .../SearchEngine/Elasticsearch/QueryBuilder.t | 353 +++++++++++++++++- .../Koha/SearchEngine/Elasticsearch/Search.t | 114 ++++++ .../Koha_SearchEngine_Elasticsearch_Search.t | 243 ------------ 6 files changed, 531 insertions(+), 259 deletions(-) create mode 100644 t/Koha/SearchEngine/Elasticsearch/Indexer.t rename t/db_dependent/{Koha_Elasticsearch_Indexer.t => Koha/SearchEngine/Elasticsearch/Indexer.t} (100%) create mode 100644 t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t delete mode 100644 t/db_dependent/Koha_SearchEngine_Elasticsearch_Search.t diff --git a/Koha/SearchEngine/Elasticsearch/Search.pm b/Koha/SearchEngine/Elasticsearch/Search.pm index 68cb0eca54..4bc259a067 100644 --- a/Koha/SearchEngine/Elasticsearch/Search.pm +++ b/Koha/SearchEngine/Elasticsearch/Search.pm @@ -407,7 +407,7 @@ sub max_result_window { my $index_name = $self->store->index_name; my $settings = $self->store->es->indices->get_settings( index => $index_name, - params => { include_defaults => 1, flat_settings => 1 }, + params => { include_defaults => 'true', flat_settings => 'true' }, ); my $max_result_window = $settings->{$index_name}->{settings}->{'index.max_result_window'}; diff --git a/t/Koha/SearchEngine/Elasticsearch/Indexer.t b/t/Koha/SearchEngine/Elasticsearch/Indexer.t new file mode 100644 index 0000000000..17d5e6f2c9 --- /dev/null +++ b/t/Koha/SearchEngine/Elasticsearch/Indexer.t @@ -0,0 +1,78 @@ +#!/usr/bin/perl +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 1; +use Test::Exception; + +use t::lib::Mocks; + +use Test::MockModule; + +use MARC::Record; +use Try::Tiny; + +use Koha::SearchEngine::Elasticsearch; +use Koha::SearchEngine::Elasticsearch::Indexer; + +subtest '_sanitise_records() tests' => sub { + plan tests => 5; + + my $indexer; + ok( + $indexer = Koha::SearchEngine::Elasticsearch::Indexer->new({ 'index' => $Koha::SearchEngine::Elasticsearch::BIBLIOS_INDEX }), + 'Creating a new indexer object' + ); + + my $record1 = MARC::Record->new(); + $record1->append_fields( + MARC::Field->new('999', '', '', 'c' => 1, 'd' => 2) + ); + + my $record2 = MARC::Record->new(); + $record2->append_fields( + MARC::Field->new('999', '', '', 'c' => 3, 'd' => 4) + ); + my $records = [$record1, $record2]; + + my $biblionumbers = [5, 6]; + + $indexer->_sanitise_records($biblionumbers, $records); + + is( + $record1->subfield('999', 'c'), + '5', + 'First record has 5 in 999c' + ); + is( + $record1->subfield('999', 'd'), + '5', + 'First record has 5 in 999d' + ); + + is( + $record2->subfield('999', 'c'), + '6', + 'Second record has 6 in 999c' + ); + is( + $record2->subfield('999', 'd'), + '6', + 'Second record has 6 in 999d' + ); +}; \ No newline at end of file diff --git a/t/db_dependent/Koha_Elasticsearch_Indexer.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t similarity index 100% rename from t/db_dependent/Koha_Elasticsearch_Indexer.t rename to t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t diff --git a/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t index 5c1f7f20ba..b6d78ad577 100644 --- a/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t +++ b/t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t @@ -19,8 +19,9 @@ use Modern::Perl; use C4::Context; use Test::Exception; +use t::lib::Mocks; use t::lib::TestBuilder; -use Test::More tests => 3; +use Test::More tests => 6; use Koha::Database; use Koha::SearchEngine::Elasticsearch::QueryBuilder; @@ -28,8 +29,60 @@ use Koha::SearchEngine::Elasticsearch::QueryBuilder; my $schema = Koha::Database->new->schema; $schema->storage->txn_begin; +my $se = Test::MockModule->new( 'Koha::SearchEngine::Elasticsearch' ); +$se->mock( 'get_elasticsearch_mappings', sub { + my ($self) = @_; + + my %all_mappings; + + my $mappings = { + data => { + properties => { + title => { + type => 'text' + }, + title__sort => { + type => 'text' + }, + subject => { + type => 'text' + }, + itemnumber => { + type => 'integer' + }, + sortablenumber => { + type => 'integer' + }, + sortablenumber__sort => { + type => 'integer' + }, + Heading => { + type => 'text' + }, + Heading__sort => { + type => 'text' + } + } + } + }; + $all_mappings{$self->index} = $mappings; + + my $sort_fields = { + $self->index => { + title => 1, + subject => 0, + itemnumber => 0, + sortablenumber => 1, + mainentry => 1 + } + }; + $self->sort_fields($sort_fields->{$self->index}); + + return $all_mappings{$self->index}; +}); + subtest 'build_authorities_query_compat() tests' => sub { - plan tests => 37; + plan tests => 44; my $qb; @@ -42,7 +95,7 @@ subtest 'build_authorities_query_compat() tests' => sub { my $search_term = 'a'; foreach my $koha_name ( keys %{ $koha_to_index_name } ) { my $query = $qb->build_authorities_query_compat( [ $koha_name ], undef, undef, ['contains'], [$search_term], 'AUTH_TYPE', 'asc' ); - if ( $koha_name eq 'all' ) { + if ( $koha_name eq 'all' || $koha_name eq 'any' ) { is( $query->{query}->{bool}->{must}[0]->{wildcard}->{"_all.phrase"}, "*a*"); } else { @@ -54,7 +107,7 @@ subtest 'build_authorities_query_compat() tests' => sub { $search_term = 'Donald Duck'; foreach my $koha_name ( keys %{ $koha_to_index_name } ) { my $query = $qb->build_authorities_query_compat( [ $koha_name ], undef, undef, ['contains'], [$search_term], 'AUTH_TYPE', 'asc' ); - if ( $koha_name eq 'all' ) { + if ( $koha_name eq 'all' || $koha_name eq 'any' ) { is( $query->{query}->{bool}->{must}[0]->{wildcard}->{"_all.phrase"}, "*donald*"); is( $query->{query}->{bool}->{must}[1]->{wildcard}->{"_all.phrase"}, @@ -69,26 +122,48 @@ subtest 'build_authorities_query_compat() tests' => sub { foreach my $koha_name ( keys %{ $koha_to_index_name } ) { my $query = $qb->build_authorities_query_compat( [ $koha_name ], undef, undef, ['is'], [$search_term], 'AUTH_TYPE', 'asc' ); - if ( $koha_name eq 'all' ) { - is( $query->{query}->{bool}->{must}[0]->{term}->{"_all.phrase"}, + if ( $koha_name eq 'all' || $koha_name eq 'any' ) { + is( $query->{query}->{bool}->{must}[0]->{match_phrase}->{"_all.phrase"}, "donald duck"); } else { - is( $query->{query}->{bool}->{must}[0]->{term}->{$koha_to_index_name->{$koha_name}.".phrase"}, + is( $query->{query}->{bool}->{must}[0]->{match_phrase}->{$koha_to_index_name->{$koha_name}.".phrase"}, "donald duck"); } } foreach my $koha_name ( keys %{ $koha_to_index_name } ) { my $query = $qb->build_authorities_query_compat( [ $koha_name ], undef, undef, ['start'], [$search_term], 'AUTH_TYPE', 'asc' ); - if ( $koha_name eq 'all' ) { - is( $query->{query}->{bool}->{must}[0]->{prefix}->{"_all.lc_raw"}, + if ( $koha_name eq 'all' || $koha_name eq 'any' ) { + is( $query->{query}->{bool}->{must}[0]->{match_phrase_prefix}->{"_all.phrase"}, "donald duck"); } else { - is( $query->{query}->{bool}->{must}[0]->{prefix}->{$koha_to_index_name->{$koha_name}.".lc_raw"}, + is( $query->{query}->{bool}->{must}[0]->{match_phrase_prefix}->{$koha_to_index_name->{$koha_name}.".phrase"}, "donald duck"); } } + # Sorting + my $query = $qb->build_authorities_query_compat( [ 'mainentry' ], undef, undef, ['start'], [$search_term], 'AUTH_TYPE', 'HeadingAsc' ); + is_deeply( + $query->{sort}, + [ + { + 'Heading__sort.phrase' => 'asc' + } + ], + "ascending sort parameter properly formed" + ); + $query = $qb->build_authorities_query_compat( [ 'mainentry' ], undef, undef, ['start'], [$search_term], 'AUTH_TYPE', 'HeadingDsc' ); + is_deeply( + $query->{sort}, + [ + { + 'Heading__sort.phrase' => 'desc' + } + ], + "descending sort parameter properly formed" + ); + # Failing case throws_ok { $qb->build_authorities_query_compat( [ 'tomas' ], undef, undef, ['contains'], [$search_term], 'AUTH_TYPE', 'asc' ); @@ -97,22 +172,199 @@ subtest 'build_authorities_query_compat() tests' => sub { 'Exception thrown on invalid value in the marclist param'; }; +subtest 'build_query tests' => sub { + plan tests => 26; + + my $qb; + + ok( + $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({ 'index' => 'biblios' }), + 'Creating new query builder object for biblios' + ); + + my @sort_by = 'title_asc'; + my @sort_params = $qb->_convert_sort_fields(@sort_by); + my %options; + $options{sort} = \@sort_params; + my $query = $qb->build_query('test', %options); + + is_deeply( + $query->{sort}, + [ + { + 'title__sort.phrase' => { + 'order' => 'asc' + } + } + ], + "sort parameter properly formed" + ); + + t::lib::Mocks::mock_preference('DisplayLibraryFacets','both'); + $query = $qb->build_query(); + ok( defined $query->{aggregations}{homebranch}, + 'homebranch added to facets if DisplayLibraryFacets=both' ); + ok( defined $query->{aggregations}{holdingbranch}, + 'holdingbranch added to facets if DisplayLibraryFacets=both' ); + t::lib::Mocks::mock_preference('DisplayLibraryFacets','holding'); + $query = $qb->build_query(); + ok( !defined $query->{aggregations}{homebranch}, + 'homebranch not added to facets if DisplayLibraryFacets=holding' ); + ok( defined $query->{aggregations}{holdingbranch}, + 'holdingbranch added to facets if DisplayLibraryFacets=holding' ); + t::lib::Mocks::mock_preference('DisplayLibraryFacets','home'); + $query = $qb->build_query(); + ok( defined $query->{aggregations}{homebranch}, + 'homebranch added to facets if DisplayLibraryFacets=home' ); + ok( !defined $query->{aggregations}{holdingbranch}, + 'holdingbranch not added to facets if DisplayLibraryFacets=home' ); + + t::lib::Mocks::mock_preference( 'QueryAutoTruncate', '' ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['donald duck'] ); + is( + $query->{query}{query_string}{query}, + "(donald duck)", + "query not altered if QueryAutoTruncate disabled" + ); + + t::lib::Mocks::mock_preference( 'QueryAutoTruncate', '1' ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['donald duck'] ); + is( + $query->{query}{query_string}{query}, + "(donald* duck*)", + "simple query is auto truncated when QueryAutoTruncate enabled" + ); + + # Ensure reserved words are not truncated + ( undef, $query ) = $qb->build_query_compat( undef, + ['donald or duck and mickey not mouse'] ); + is( + $query->{query}{query_string}{query}, + "(donald* or duck* and mickey* not mouse*)", + "reserved words are not affected by QueryAutoTruncate" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['donald* duck*'] ); + is( + $query->{query}{query_string}{query}, + "(donald* duck*)", + "query with '*' is unaltered when QueryAutoTruncate is enabled" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['donald duck and the mouse'] ); + is( + $query->{query}{query_string}{query}, + "(donald* duck* and the* mouse*)", + "individual words are all truncated and stopwords ignored" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['*'] ); + is( + $query->{query}{query_string}{query}, + "(*)", + "query of just '*' is unaltered when QueryAutoTruncate is enabled" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['"donald duck"'] ); + is( + $query->{query}{query_string}{query}, + '("donald duck")', + "query with quotes is unaltered when QueryAutoTruncate is enabled" + ); + + + ( undef, $query ) = $qb->build_query_compat( undef, ['"donald duck" and "the mouse"'] ); + is( + $query->{query}{query_string}{query}, + '("donald duck" and "the mouse")', + "all quoted strings are unaltered if more than one in query" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['barcode:123456'] ); + is( + $query->{query}{query_string}{query}, + '(barcode:123456*)', + "query of specific field is truncated" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['Local-number:"123456"'] ); + is( + $query->{query}{query_string}{query}, + '(Local-number:"123456")', + "query of specific field including hyphen and quoted is not truncated" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['Local-number:123456'] ); + is( + $query->{query}{query_string}{query}, + '(Local-number:123456*)', + "query of specific field including hyphen and not quoted is truncated" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['Local-number.raw:123456'] ); + is( + $query->{query}{query_string}{query}, + '(Local-number.raw:123456*)', + "query of specific field including period and not quoted is truncated" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['Local-number.raw:"123456"'] ); + is( + $query->{query}{query_string}{query}, + '(Local-number.raw:"123456")', + "query of specific field including period and quoted is not truncated" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['J.R.R'] ); + is( + $query->{query}{query_string}{query}, + '(J.R.R*)', + "query including period is truncated but not split at periods" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'] ); + is( + $query->{query}{query_string}{query}, + '(title:"donald duck")', + "query of specific field is not truncated when surrouned by quotes" + ); + + ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { suppress => 1 } ); + is( + $query->{query}{query_string}{query}, + '(title:"donald duck") AND suppress:0', + "query of specific field is added AND suppress:0" + ); + + my ($simple_query, $query_cgi); + ( undef, $query, $simple_query, $query_cgi ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { suppress => 0 } ); + is( + $query->{query}{query_string}{query}, + '(title:"donald duck")', + "query of specific field is not added AND suppress:0" + ); + is($query_cgi, 'q=title%3A%22donald%20duck%22', 'query cgi'); +}; + + subtest 'build query from form subtests' => sub { plan tests => 5; - my $builder = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({ 'index' => 'authorities' }), + my $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({ 'index' => 'authorities' }), #when searching for authorities from a record the form returns marclist with blanks for unentered terms my @marclist = ('mainmainentry','mainentry','match', 'all'); my @values = ( undef, 'Hamilton', undef, undef); my @operator = ( 'contains', 'contains', 'contains', 'contains'); - my $query = $builder->build_authorities_query_compat( \@marclist, undef, + my $query = $qb->build_authorities_query_compat( \@marclist, undef, undef, \@operator , \@values, 'AUTH_TYPE', 'asc' ); is($query->{query}->{bool}->{must}[0]->{wildcard}->{'Heading.phrase'}, "*hamilton*","Expected search is populated"); is( scalar @{ $query->{query}->{bool}->{must} }, 1,"Only defined search is populated"); @values[2] = 'Jefferson'; - $query = $builder->build_authorities_query_compat( \@marclist, undef, + $query = $qb->build_authorities_query_compat( \@marclist, undef, undef, \@operator , \@values, 'AUTH_TYPE', 'asc' ); is($query->{query}->{bool}->{must}[0]->{wildcard}->{'Heading.phrase'}, "*hamilton*","First index searched as expected"); is($query->{query}->{bool}->{must}[1]->{wildcard}->{'Match.phrase'}, "*jefferson*","Second index searched when populated"); @@ -124,7 +376,7 @@ subtest 'build query from form subtests' => sub { subtest 'build_query with weighted fields tests' => sub { plan tests => 4; - my $builder = Koha::SearchEngine::Elasticsearch::QueryBuilder->new( { index => 'mydb' } ); + my $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new( { index => 'mydb' } ); my $db_builder = t::lib::TestBuilder->new(); Koha::SearchFields->search({})->delete; @@ -156,7 +408,7 @@ subtest 'build_query with weighted fields tests' => sub { } }); - my ( undef, $query ) = $builder->build_query_compat( undef, ['title:"donald duck"'], undef, undef, + my ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { weighted_fields => 1 }); my $fields = $query->{query}{query_string}{fields}; @@ -166,4 +418,75 @@ subtest 'build_query with weighted fields tests' => sub { is($fields->[2], 'subject^15.00', 'Third search field is subject'); }; +subtest "_convert_sort_fields() tests" => sub { + plan tests => 3; + + my $qb; + + ok( + $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({ 'index' => 'biblios' }), + 'Creating new query builder object for biblios' + ); + + my @sort_by = $qb->_convert_sort_fields(qw( call_number_asc author_dsc )); + is_deeply( + \@sort_by, + [ + { field => 'callnum', direction => 'asc' }, + { field => 'author', direction => 'desc' } + ], + 'sort fields should have been split correctly' + ); + + # We could expect this to pass, but direction is undef instead of 'desc' + @sort_by = $qb->_convert_sort_fields(qw( call_number_asc author_desc )); + is_deeply( + \@sort_by, + [ + { field => 'callnum', direction => 'asc' }, + { field => 'author', direction => 'desc' } + ], + 'sort fields should have been split correctly' + ); +}; + +subtest "_sort_field() tests" => sub { + plan tests => 5; + + my $qb; + + ok( + $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({ 'index' => 'biblios' }), + 'Creating new query builder object for biblios' + ); + + my $f = $qb->_sort_field('title'); + is( + $f, + 'title__sort.phrase', + 'title sort mapped correctly' + ); + + $f = $qb->_sort_field('subject'); + is( + $f, + 'subject.raw', + 'subject sort mapped correctly' + ); + + $f = $qb->_sort_field('itemnumber'); + is( + $f, + 'itemnumber', + 'itemnumber sort mapped correctly' + ); + + $f = $qb->_sort_field('sortablenumber'); + is( + $f, + 'sortablenumber__sort', + 'sortablenumber sort mapped correctly' + ); +}; + $schema->storage->txn_rollback; diff --git a/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t new file mode 100644 index 0000000000..8d73f14058 --- /dev/null +++ b/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t @@ -0,0 +1,114 @@ +# Copyright 2015 Catalyst IT +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 11; +use t::lib::Mocks; + +use Koha::SearchEngine::Elasticsearch::QueryBuilder; +use Koha::SearchEngine::Elasticsearch::Indexer; + + +my $se = Test::MockModule->new( 'Koha::SearchEngine::Elasticsearch' ); +$se->mock( 'get_elasticsearch_mappings', sub { + my ($self) = @_; + + my %all_mappings; + + my $mappings = { + data => { + properties => { + title => { + type => 'text' + }, + title__sort => { + type => 'text' + }, + subject => { + type => 'text' + }, + itemnumber => { + type => 'integer' + }, + sortablenumber => { + type => 'integer' + }, + sortablenumber__sort => { + type => 'integer' + } + } + } + }; + $all_mappings{$self->index} = $mappings; + + my $sort_fields = { + $self->index => { + title => 1, + subject => 0, + itemnumber => 0, + sortablenumber => 1 + } + }; + $self->sort_fields($sort_fields->{$self->index}); + + return $all_mappings{$self->index}; +}); + +my $builder = Koha::SearchEngine::Elasticsearch::QueryBuilder->new( { index => 'mydb' } ); + +use_ok('Koha::SearchEngine::Elasticsearch::Search'); + +ok( + my $searcher = Koha::SearchEngine::Elasticsearch::Search->new( + { 'nodes' => ['localhost:9200'], 'index' => 'mydb' } + ), + 'Creating a Koha::SearchEngine::Elasticsearch::Search object' +); + +is( $searcher->index, 'mydb', 'Testing basic accessor' ); + +ok( my $query = $builder->build_query('easy'), 'Build a search query'); + +SKIP: { + + eval { $builder->get_elasticsearch_params; }; + + skip 'Elasticsearch configuration not available', 8 + if $@; + + Koha::SearchEngine::Elasticsearch::Indexer->new({ index => 'mydb' })->drop_index; + Koha::SearchEngine::Elasticsearch::Indexer->new({ index => 'mydb' })->create_index; + + ok( my $results = $searcher->search( $query) , 'Do a search ' ); + + is (my $count = $searcher->count( $query ), 0 , 'Get a count of the results, without returning results '); + + ok ($results = $searcher->search_compat( $query ), 'Test search_compat' ); + + ok (($results,$count) = $searcher->search_auth_compat ( $query ), 'Test search_auth_compat' ); + + is ( $count = $searcher->count_auth_use($searcher,1), 0, 'Testing count_auth_use'); + + is ($searcher->max_result_window, 10000, 'By default, max_result_window is 10000'); + $searcher->store->es->indices->put_settings(index => $searcher->store->index_name, body => { + 'index' => { + 'max_result_window' => 12000, + }, + }); + is ($searcher->max_result_window, 12000, 'max_result_window returns the correct value'); +} diff --git a/t/db_dependent/Koha_SearchEngine_Elasticsearch_Search.t b/t/db_dependent/Koha_SearchEngine_Elasticsearch_Search.t deleted file mode 100644 index 30e48cfe03..0000000000 --- a/t/db_dependent/Koha_SearchEngine_Elasticsearch_Search.t +++ /dev/null @@ -1,243 +0,0 @@ -# Copyright 2015 Catalyst IT -# -# This file is part of Koha. -# -# Koha is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# Koha is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Koha; if not, see . - -use Modern::Perl; - -use Test::More tests => 13; -use t::lib::Mocks; - -use Koha::SearchEngine::Elasticsearch::QueryBuilder; -use Koha::SearchEngine::Elasticsearch::Indexer; - - -my $builder = Koha::SearchEngine::Elasticsearch::QueryBuilder->new( { index => 'mydb' } ); - -use_ok('Koha::SearchEngine::Elasticsearch::Search'); - -ok( - my $searcher = Koha::SearchEngine::Elasticsearch::Search->new( - { 'nodes' => ['localhost:9200'], 'index' => 'mydb' } - ), - 'Creating a Koha::SearchEngine::Elasticsearch::Search object' -); - -is( $searcher->index, 'mydb', 'Testing basic accessor' ); - -ok( my $query = $builder->build_query('easy'), 'Build a search query'); - -SKIP: { - - eval { $builder->get_elasticsearch_params; }; - - skip 'ElasticSeatch configuration not available', 8 - if $@; - - Koha::SearchEngine::Elasticsearch::Indexer->new({ index => 'mydb' })->drop_index; - - ok( my $results = $searcher->search( $query) , 'Do a search ' ); - - is (my $count = $searcher->count( $query ), 0 , 'Get a count of the results, without returning results '); - - ok ($results = $searcher->search_compat( $query ), 'Test search_compat' ); - - ok (($results,$count) = $searcher->search_auth_compat ( $query ), 'Test search_auth_compat' ); - - is ( $count = $searcher->count_auth_use($searcher,1), 0, 'Testing count_auth_use'); - - is ($searcher->max_result_window, 10000, 'By default, max_result_window is 10000'); - $searcher->store->es->indices->put_settings(index => $searcher->store->index_name, body => { - 'index' => { - 'max_result_window' => 12000, - }, - }); - is ($searcher->max_result_window, 12000, 'max_result_window returns the correct value'); -} - -subtest 'build_query tests' => sub { - plan tests => 24; - - t::lib::Mocks::mock_preference('DisplayLibraryFacets','both'); - my $query = $builder->build_query(); - ok( defined $query->{aggregations}{homebranch}, - 'homebranch added to facets if DisplayLibraryFacets=both' ); - ok( defined $query->{aggregations}{holdingbranch}, - 'holdingbranch added to facets if DisplayLibraryFacets=both' ); - t::lib::Mocks::mock_preference('DisplayLibraryFacets','holding'); - $query = $builder->build_query(); - ok( !defined $query->{aggregations}{homebranch}, - 'homebranch not added to facets if DisplayLibraryFacets=holding' ); - ok( defined $query->{aggregations}{holdingbranch}, - 'holdingbranch added to facets if DisplayLibraryFacets=holding' ); - t::lib::Mocks::mock_preference('DisplayLibraryFacets','home'); - $query = $builder->build_query(); - ok( defined $query->{aggregations}{homebranch}, - 'homebranch added to facets if DisplayLibraryFacets=home' ); - ok( !defined $query->{aggregations}{holdingbranch}, - 'holdingbranch not added to facets if DisplayLibraryFacets=home' ); - - t::lib::Mocks::mock_preference( 'QueryAutoTruncate', '' ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['donald duck'] ); - is( - $query->{query}{query_string}{query}, - "(donald duck)", - "query not altered if QueryAutoTruncate disabled" - ); - - t::lib::Mocks::mock_preference( 'QueryAutoTruncate', '1' ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['donald duck'] ); - is( - $query->{query}{query_string}{query}, - "(donald* duck*)", - "simple query is auto truncated when QueryAutoTruncate enabled" - ); - - # Ensure reserved words are not truncated - ( undef, $query ) = $builder->build_query_compat( undef, - ['donald or duck and mickey not mouse'] ); - is( - $query->{query}{query_string}{query}, - "(donald* or duck* and mickey* not mouse*)", - "reserved words are not affected by QueryAutoTruncate" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['donald* duck*'] ); - is( - $query->{query}{query_string}{query}, - "(donald* duck*)", - "query with '*' is unaltered when QueryAutoTruncate is enabled" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['donald duck and the mouse'] ); - is( - $query->{query}{query_string}{query}, - "(donald* duck* and the* mouse*)", - "individual words are all truncated and stopwords ignored" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['*'] ); - is( - $query->{query}{query_string}{query}, - "(*)", - "query of just '*' is unaltered when QueryAutoTruncate is enabled" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['"donald duck"'] ); - is( - $query->{query}{query_string}{query}, - '("donald duck")', - "query with quotes is unaltered when QueryAutoTruncate is enabled" - ); - - - ( undef, $query ) = $builder->build_query_compat( undef, ['"donald duck" and "the mouse"'] ); - is( - $query->{query}{query_string}{query}, - '("donald duck" and "the mouse")', - "all quoted strings are unaltered if more than one in query" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['barcode:123456'] ); - is( - $query->{query}{query_string}{query}, - '(barcode:123456*)', - "query of specific field is truncated" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['Local-number:"123456"'] ); - is( - $query->{query}{query_string}{query}, - '(Local-number:"123456")', - "query of specific field including hyphen and quoted is not truncated" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['Local-number:123456'] ); - is( - $query->{query}{query_string}{query}, - '(Local-number:123456*)', - "query of specific field including hyphen and not quoted is truncated" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['Local-number.raw:123456'] ); - is( - $query->{query}{query_string}{query}, - '(Local-number.raw:123456*)', - "query of specific field including period and not quoted is truncated" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['Local-number.raw:"123456"'] ); - is( - $query->{query}{query_string}{query}, - '(Local-number.raw:"123456")', - "query of specific field including period and quoted is not truncated" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['J.R.R'] ); - is( - $query->{query}{query_string}{query}, - '(J.R.R*)', - "query including period is truncated but not split at periods" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['title:"donald duck"'] ); - is( - $query->{query}{query_string}{query}, - '(title:"donald duck")', - "query of specific field is not truncated when surrouned by quotes" - ); - - ( undef, $query ) = $builder->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { suppress => 1 } ); - is( - $query->{query}{query_string}{query}, - '(title:"donald duck") AND suppress:0', - "query of specific field is added AND suppress:0" - ); - - my ($simple_query, $query_cgi); - ( undef, $query, $simple_query, $query_cgi ) = $builder->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { suppress => 0 } ); - is( - $query->{query}{query_string}{query}, - '(title:"donald duck")', - "query of specific field is not added AND suppress:0" - ); - is($query_cgi, 'q=title%3A%22donald%20duck%22', 'query cgi'); -}; - -subtest "_convert_sort_fields" => sub { - plan tests => 2; - my @sort_by = $builder->_convert_sort_fields(qw( call_number_asc author_dsc )); - is_deeply( - \@sort_by, - [ - { field => 'callnum', direction => 'asc' }, - { field => 'author', direction => 'desc' } - ], - 'sort fields should have been split correctly' - ); - - # We could expect this to pass, but direction is undef instead of 'desc' - @sort_by = $builder->_convert_sort_fields(qw( call_number_asc author_desc )); - is_deeply( - \@sort_by, - [ - { field => 'callnum', direction => 'asc' }, - { field => 'author', direction => 'desc' } - ], - 'sort fields should have been split correctly' - ); -}; -- 2.19.1