use C4::Context;
use Test::Exception;
+use Test::Warn;
use t::lib::Mocks;
use t::lib::TestBuilder;
-use Test::More tests => 6;
+use Test::More tests => 7;
use List::Util qw( all );
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'
- }
- }
+ properties => {
+ title => {
+ type => 'text'
+ },
+ title__sort => {
+ type => 'text'
+ },
+ subject => {
+ type => 'text',
+ facet => 1
+ },
+ 'subject-heading-thesaurus' => {
+ type => 'text',
+ facet => 1
+ },
+ itemnumber => {
+ type => 'integer'
+ },
+ sortablenumber => {
+ type => 'integer'
+ },
+ sortablenumber__sort => {
+ type => 'integer'
+ },
+ heading => {
+ type => 'text'
+ },
+ 'heading-main' => {
+ type => 'text'
+ },
+ heading__sort => {
+ type => 'text'
+ },
+ match => {
+ type => 'text'
+ },
+ 'match-heading' => {
+ type => 'text'
+ },
+ 'match-heading-see-from' => {
+ type => 'text'
+ },
}
};
$all_mappings{$self->index} = $mappings;
return $all_mappings{$self->index};
});
-my $cache = Koha::Caches->get_instance();
-my $clear_search_fields_cache = sub {
- $cache->clear_from_cache('elasticsearch_search_fields_staff_client');
- $cache->clear_from_cache('elasticsearch_search_fields_opac');
-};
-
subtest 'build_authorities_query_compat() tests' => sub {
- plan tests => 55;
+
+ plan tests => 65;
my $qb;
"a*");
}
is( $query->{query}->{bool}->{must}[0]->{query_string}->{analyze_wildcard}, JSON::true, 'Set analyze_wildcard true' );
+ is( $query->{query}->{bool}->{must}[0]->{query_string}->{lenient}, JSON::true, 'Set lenient true' );
}
$search_term = 'Donald Duck';
"authorities type code is used as filter"
);
- # Failing case
- throws_ok {
- $qb->build_authorities_query_compat( [ 'tomas' ], undef, undef, ['contains'], [$search_term], 'AUTH_TYPE', 'asc' );
+ # Authorities marclist check
+ warning_like {
+ $query = $qb->build_authorities_query_compat( [ 'tomas','mainentry' ], undef, undef, ['contains'], [$search_term,$search_term], 'AUTH_TYPE', 'asc' )
}
- 'Koha::Exceptions::WrongParameter',
- 'Exception thrown on invalid value in the marclist param';
+ qr/Unknown search field tomas/,
+ "Warning for unknown field in marclist";
+ is_deeply(
+ $query->{query}->{bool}->{must}[0]->{query_string}->{default_field},
+ 'tomas',
+ "If no mapping for marclist the index is passed through as defined"
+ );
+ is_deeply(
+ $query->{query}->{bool}->{must}[1]->{query_string}{default_field},
+ 'heading',
+ "If mapping found for marclist the index is passed through converted"
+ );
+
};
subtest 'build_query tests' => sub {
- plan tests => 40;
+ plan tests => 57;
my $qb;
$query->{sort},
[
{
- 'title__sort.phrase' => {
+ 'title__sort' => {
'order' => 'asc'
}
}
);
t::lib::Mocks::mock_preference('FacetMaxCount','37');
+ t::lib::Mocks::mock_preference('DisplayLibraryFacets','both');
$query = $qb->build_query('test', %options);
ok( defined $query->{aggregations}{ccode}{terms}{size},'we need to ask for a size or we get only 5 facet' );
is( $query->{aggregations}{ccode}{terms}{size}, 37,'we ask for the size as defined by the syspref FacetMaxCount');
+ is( $query->{aggregations}{homebranch}{terms}{size}, 37,'we ask for the size as defined by the syspref FacetMaxCount for homebranch');
+ is( $query->{aggregations}{holdingbranch}{terms}{size}, 37,'we ask for the size as defined by the syspref FacetMaxCount for holdingbranch');
t::lib::Mocks::mock_preference('DisplayLibraryFacets','both');
$query = $qb->build_query();
"query not altered if QueryAutoTruncate disabled"
);
+ ( undef, $query ) = $qb->build_query_compat( undef, ['donald duck'], ['kw,phr'] );
+ is(
+ $query->{query}{query_string}{query},
+ '("donald duck")',
+ "keyword as phrase correctly quotes search term and strips index"
+ );
+
( undef, $query ) = $qb->build_query_compat( undef, ['donald duck'], ['title'] );
is(
$query->{query}{query_string}{query},
( undef, $query ) = $qb->build_query_compat( undef, ['2019-'], ['yr,st-year'], ['yr,st-numeric=-2019'] );
is(
$query->{query}{query_string}{query},
- '(date-of-publication:[2019 TO *]) AND copydate:[* TO 2019]',
+ '(date-of-publication:[2019 TO *]) AND date-of-publication:[* TO 2019]',
'Open end year in year range of an st-year search is handled properly'
);
"query of just '*' is unaltered when QueryAutoTruncate is enabled"
);
- ( undef, $query ) = $qb->build_query_compat( undef, ['"donald duck"'] );
+ ( undef, $query ) = $qb->build_query_compat( undef, ['"donald duck"'], undef, ['available'] );
is(
$query->{query}{query_string}{query},
- '("donald duck")',
+ '("donald duck") AND onloan:false',
"query with quotes is unaltered when QueryAutoTruncate is enabled"
);
( 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"
+ '(title:"donald duck") AND suppress:false',
+ "query of specific field is added AND suppress:false"
);
( undef, $query, $simple_query, $query_cgi, $query_desc ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef, undef, undef, undef, { suppress => 0 } );
'(title:"donald duck")',
"query of specific field is not added AND suppress:0"
);
+
+ ( undef, $query ) = $qb->build_query_compat( ['AND'], ['title:"donald duck"'], undef, ['author:Dillinger Escaplan'] );
+ is(
+ $query->{query}{query_string}{query},
+ '(title:"donald duck") AND author:("Dillinger Escaplan")',
+ "Simple query with limit term quoted in parentheses"
+ );
+
+ ( undef, $query ) = $qb->build_query_compat( ['AND'], ['title:"donald duck"'], undef, ['author:Dillinger Escaplan', 'itype:BOOK'] );
+ is(
+ $query->{query}{query_string}{query},
+ '(title:"donald duck") AND (author:("Dillinger Escaplan")) AND (itype:("BOOK"))',
+ "Simple query with each limit's term quoted in parentheses"
+ );
is($query_cgi, 'idx=&q=title%3A%22donald%20duck%22', 'query cgi');
is($query_desc, 'title:"donald duck"', 'query desc ok');
+
+ ( undef, $query ) = $qb->build_query_compat( ['AND'], ['title:"donald duck"'], undef, ['author:Dillinger Escaplan', 'mc-itype,phr:BOOK', 'mc-itype,phr:CD'] );
+ is(
+ $query->{query}{query_string}{query},
+ '(title:"donald duck") AND (author:("Dillinger Escaplan")) AND itype:(("BOOK") OR ("CD"))',
+ "Limits quoted correctly when passed as phrase"
+ );
+
+ # Scan queries
+ ( undef, $query, $simple_query, $query_cgi, $query_desc ) = $qb->build_query_compat( undef, ['new'], ['au'], undef, undef, 1 );
+ is(
+ $query->{query}{query_string}{query},
+ '*',
+ "scan query is properly formed"
+ );
+ is_deeply(
+ $query->{aggregations}{'author'}{'terms'},
+ {
+ field => 'author__facet',
+ order => { '_key' => 'asc' },
+ include => '[nN][eE][wW].*'
+ },
+ "scan aggregation request is properly formed"
+ );
+ is($query_cgi, 'idx=au&q=new&scan=1', 'query cgi');
+ is($query_desc, 'new', 'query desc ok');
+
+ ( undef, $query, $simple_query, $query_cgi, $query_desc ) = $qb->build_query_compat( undef, ['new'], [], undef, undef, 1 );
+ is(
+ $query->{query}{query_string}{query},
+ '*',
+ "scan query is properly formed"
+ );
+ is_deeply(
+ $query->{aggregations}{'subject'}{'terms'},
+ {
+ field => 'subject__facet',
+ order => { '_key' => 'asc' },
+ include => '[nN][eE][wW].*'
+ },
+ "scan aggregation request is properly formed"
+ );
+ is($query_cgi, 'idx=&q=new&scan=1', 'query cgi');
+ is($query_desc, 'new', 'query desc ok');
+
+ my( $limit, $limit_cgi, $limit_desc );
+ ( undef, $query, $simple_query, $query_cgi, $query_desc, $limit, $limit_cgi, $limit_desc ) = $qb->build_query_compat( ['AND'], ['kw:""'], undef, ['author:Dillinger Escaplan', 'mc-itype,phr:BOOK', 'mc-itype,phr:CD'] );
+ is( $limit, '(author:("Dillinger Escaplan")) AND itype:(("BOOK") OR ("CD"))', "Limit formed correctly when no search terms");
+ is( $limit_cgi,'&limit=author%3ADillinger%20Escaplan&limit=mc-itype%2Cphr%3ABOOK&limit=mc-itype%2Cphr%3ACD', "Limit CGI formed correctly when no search terms");
+ is( $limit_desc,'(author:("Dillinger Escaplan")) AND itype:(("BOOK") OR ("CD"))',"Limit desc formed correctly when no search terms");
};
};
subtest 'build_query with weighted fields tests' => sub {
- plan tests => 4;
+ plan tests => 6;
$se->mock( '_load_elasticsearch_mappings', sub {
return {
+ authorities => {
+ Heading => {
+ label => 'heading',
+ type => 'string',
+ opac => 0,
+ staff_client => 1,
+ mappings => [{
+ marc_field => '150',
+ marc_type => 'marc21',
+ }]
+ },
+ Headingmain => {
+ label => 'headingmain',
+ type => 'string',
+ opac => 1,
+ staff_client => 1,
+ mappings => [{
+ marc_field => '150',
+ marc_type => 'marc21',
+ }]
+ }
+ },
biblios => {
abstract => {
label => 'abstract',
$search_field->update({ weight => 25.0 });
$search_field = Koha::SearchFields->find({ name => 'subject' });
$search_field->update({ weight => 15.5 });
- $clear_search_fields_cache->();
+ Koha::SearchEngine::Elasticsearch->clear_search_fields_cache();
my ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef,
undef, undef, undef, { weighted_fields => 1 });
['abstract'],
'Only OPAC search fields are used when opac search is performed'
);
+
+ $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new( { index => 'authorities' } );
+ ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef,
+ undef, undef, undef, { weighted_fields => 1 });
+ $fields = $query->{query}{query_string}{fields};
+ is_deeply( [sort @$fields], ['heading','headingmain'],'Authorities fields retrieve for authorities index');
+
+ ( undef, $query ) = $qb->build_query_compat( undef, ['title:"donald duck"'], undef, undef,
+ undef, undef, undef, { weighted_fields => 1, is_opac => 1 });
+ $fields = $query->{query}{query_string}{fields};
+ is_deeply($fields,['headingmain'],'Only opac authorities fields retrieved for authorities index is is_opac');
+
+};
+
+subtest 'build_query_compat() SearchLimitLibrary tests' => sub {
+
+ plan tests => 18;
+
+ $schema->storage->txn_begin;
+
+ my $builder = t::lib::TestBuilder->new;
+
+ my $branch_1 = $builder->build_object({ class => 'Koha::Libraries' });
+ my $branch_2 = $builder->build_object({ class => 'Koha::Libraries' });
+ my $group = $builder->build_object({ class => 'Koha::Library::Groups', value => {
+ ft_search_groups_opac => 1,
+ ft_search_groups_staff => 1,
+ parent_id => undef,
+ branchcode => undef
+ }
+ });
+ my $group_1 = $builder->build_object({ class => 'Koha::Library::Groups', value => {
+ parent_id => $group->id,
+ branchcode => $branch_1->id
+ }
+ });
+ my $group_2 = $builder->build_object({ class => 'Koha::Library::Groups', value => {
+ parent_id => $group->id,
+ branchcode => $branch_2->id
+ }
+ });
+ my $groupid = $group->id;
+ my @branchcodes = sort { $a cmp $b } ( $branch_1->id, $branch_2->id );
+
+
+ my $query_builder = Koha::SearchEngine::Elasticsearch::QueryBuilder->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
+ t::lib::Mocks::mock_preference('SearchLimitLibrary', 'both');
+ my ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "branch:CPL" ], undef, undef, undef, undef );
+ is( $limit, '(homebranch: "CPL" OR holdingbranch: "CPL")', "Branch limit expanded to home/holding branch");
+ is( $limit_desc, '(homebranch: "CPL" OR holdingbranch: "CPL")', "Limit description correctly expanded");
+ is( $limit_cgi, '&limit=branch%3ACPL', "Limit cgi does not get expanded");
+ ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "multibranchlimit:$groupid" ], undef, undef, undef, undef );
+ is( $limit, "(homebranch: \"$branchcodes[0]\" OR homebranch: \"$branchcodes[1]\" OR holdingbranch: \"$branchcodes[0]\" OR holdingbranch: \"$branchcodes[1]\")", "Multibranch limit expanded to home/holding branches");
+ is( $limit_desc, "(homebranch: \"$branchcodes[0]\" OR homebranch: \"$branchcodes[1]\" OR holdingbranch: \"$branchcodes[0]\" OR holdingbranch: \"$branchcodes[1]\")", "Multibranch limit description correctly expanded");
+ is( $limit_cgi, "&limit=multibranchlimit%3A$groupid", "Multibranch limit cgi does not get expanded");
+
+ t::lib::Mocks::mock_preference('SearchLimitLibrary', 'homebranch');
+ ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "branch:CPL" ], undef, undef, undef, undef );
+ is( $limit, "(homebranch: \"CPL\")", "branch limit expanded to home branch");
+ is( $limit_desc, "(homebranch: \"CPL\")", "limit description correctly expanded");
+ is( $limit_cgi, "&limit=branch%3ACPL", "limit cgi does not get expanded");
+ ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "multibranchlimit:$groupid" ], undef, undef, undef, undef );
+ is( $limit, "(homebranch: \"$branchcodes[0]\" OR homebranch: \"$branchcodes[1]\")", "branch limit expanded to home branch");
+ is( $limit_desc, "(homebranch: \"$branchcodes[0]\" OR homebranch: \"$branchcodes[1]\")", "limit description correctly expanded");
+ is( $limit_cgi, "&limit=multibranchlimit%3A$groupid", "Limit cgi does not get expanded");
+
+ t::lib::Mocks::mock_preference('SearchLimitLibrary', 'holdingbranch');
+ ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "branch:CPL" ], undef, undef, undef, undef );
+ is( $limit, "(holdingbranch: \"CPL\")", "branch limit expanded to holding branch");
+ is( $limit_desc, "(holdingbranch: \"CPL\")", "Limit description correctly expanded");
+ is( $limit_cgi, "&limit=branch%3ACPL", "Limit cgi does not get expanded");
+ ( undef, undef, undef, undef, undef, $limit, $limit_cgi, $limit_desc, undef ) =
+ $query_builder->build_query_compat( undef, undef, undef, [ "multibranchlimit:$groupid" ], undef, undef, undef, undef );
+ is( $limit, "(holdingbranch: \"$branchcodes[0]\" OR holdingbranch: \"$branchcodes[1]\")", "branch limit expanded to holding branch");
+ is( $limit_desc, "(holdingbranch: \"$branchcodes[0]\" OR holdingbranch: \"$branchcodes[1]\")", "Limit description correctly expanded");
+ is( $limit_cgi, "&limit=multibranchlimit%3A$groupid", "Limit cgi does not get expanded");
+
};
subtest "_convert_sort_fields() tests" => sub {
is_deeply(
\@sort_by,
[
- { field => 'local-classification', direction => 'asc' },
+ { field => 'cn-sort', direction => 'asc' },
{ field => 'author', direction => 'desc' }
],
'sort fields should have been split correctly'
is_deeply(
\@sort_by,
[
- { field => 'local-classification', direction => 'asc' },
+ { field => 'cn-sort', direction => 'asc' },
{ field => 'author', direction => 'desc' }
],
'sort fields should have been split correctly'
my $f = $qb->_sort_field('title');
is(
$f,
- 'title__sort.phrase',
+ 'title__sort',
'title sort mapped correctly'
);