Files
SyliusElasticsearchPlugin/spec/QueryBuilder/SearchProductsQueryBuilderSpec.php
Manuele Menozzi 1262d4701e Sitewide search (#69)
* Add first site-wide search behat test and setup

* Site wide search WIP with rudimental search page and results

* Add description and short description property builders and test

* Add search form on all shop pages using a sonata block

* Remove the bitbag comment

* Imporve site wide search box UI

* Improve site wide search form validation

* Disambiguate Filter button selector in filtering products test

* Improve search result page UI

* Enable simple pagination on search results page

* First WIP of faceted search on the site wide search page

* Implement PriceFacet

* Implement TaxonFacet

* Fix PriceFacet to use ChannelContext instead of Channel

* Refactor site wide search facets using FacetInterface services

* Add label to FacetInterface services

* Make facet registry class final

* Refactor PriceFacet with ShopperContext

* Remove FacetsConfig class not used anymore

* Rename search box form model from Box to SearchBox

* Add SearchFacets class as model of SearchFacetsType form

* Introduce SearchProductsQueryBuilder to build MultiMatch search

* Add SearchPropertyNameResolverRegistry to SearchProductsQueryBuilder

* Change AttributeBuilder to not format select attribute values

* Implement AttributeFacet for select attributes filters in search

* Improve label formatting in AttributeFacet for non-select attributes

* Make several classes final

* Implement OptionFacet

* Declare return type in specs

* Improve search to return only enabled and in current channel products

* Only add search facet if there is at least one choice

* Revert "Change AttributeBuilder to not format select attribute values"

This reverts commit 54625989e0542faa784f32312571241db4cdf1e6.

* Improve AttributeBuilder by index select attribute options labels

* Fix pagination on site wide search page

* CS fix
2019-10-02 00:05:35 +02:00

101 lines
4.1 KiB
PHP

<?php
declare(strict_types=1);
namespace spec\BitBag\SyliusElasticsearchPlugin\QueryBuilder;
use BitBag\SyliusElasticsearchPlugin\PropertyNameResolver\ConcatedNameResolverInterface;
use BitBag\SyliusElasticsearchPlugin\PropertyNameResolver\SearchPropertyNameResolverRegistryInterface;
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\SearchProductsQueryBuilder;
use Elastica\Query\BoolQuery;
use Elastica\Query\MultiMatch;
use Elastica\Query\Term;
use Elastica\Query\Terms;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Locale\Context\LocaleContextInterface;
final class SearchProductsQueryBuilderSpec extends ObjectBehavior
{
private $isEnabeldQuery;
private $hasChannelQuery;
function let(
SearchPropertyNameResolverRegistryInterface $searchPropertyNameResolverRegistry,
LocaleContextInterface $localeContext,
QueryBuilderInterface $isEnabledQueryBuilder,
QueryBuilderInterface $hasChannelQueryBuilder
): void {
$localeContext->getLocaleCode()->willReturn('en_US');
$searchPropertyNameResolverRegistry->getPropertyNameResolvers()->willReturn([]);
$this->isEnabeldQuery = new Term();
$this->isEnabeldQuery->setTerm('enabled', true);
$isEnabledQueryBuilder->buildQuery([])->willReturn($this->isEnabeldQuery);
$this->hasChannelQuery = new Terms();
$this->hasChannelQuery->setTerms('channels', ['web_us']);
$hasChannelQueryBuilder->buildQuery([])->willReturn($this->hasChannelQuery);
$this->beConstructedWith(
$searchPropertyNameResolverRegistry,
$localeContext,
$isEnabledQueryBuilder,
$hasChannelQueryBuilder
);
}
function it_is_initializable(): void
{
$this->shouldHaveType(SearchProductsQueryBuilder::class);
}
function it_implements_query_builder_interface(): void
{
$this->shouldHaveType(QueryBuilderInterface::class);
}
function it_throws_an_exception_if_query_is_not_present_in_data(): void
{
$this->shouldThrow(\RuntimeException::class)->during('buildQuery', [['not_relevant_key' => 'value']]);
}
function it_throws_an_exception_if_query_is_not_a_string(): void
{
$this->shouldThrow(\RuntimeException::class)->during('buildQuery', [['query' => new \stdClass()]]);
}
function it_builds_multi_match_query_with_provided_query_string(): void
{
$expectedMultiMatch = new MultiMatch();
$expectedMultiMatch->setQuery('bmw');
$expectedMultiMatch->setFuzziness('AUTO');
$expectedMultiMatch->setFields([]);
$expectedQuery = new BoolQuery();
$expectedQuery->addMust($expectedMultiMatch);
$expectedQuery->addFilter($this->isEnabeldQuery);
$expectedQuery->addFilter($this->hasChannelQuery);
$this->buildQuery(['query' => 'bmw'])->shouldBeLike($expectedQuery);
}
function it_builds_multi_match_query_with_provided_query_string_and_fields_from_registry(
SearchPropertyNameResolverRegistryInterface $searchPropertyNameResolverRegistry,
ConcatedNameResolverInterface $firstPropertyNameResolver,
ConcatedNameResolverInterface $secondPropertyNameResolver
): void {
$firstPropertyNameResolver->resolvePropertyName('en_US')->shouldBeCalled()->willReturn('property_1_en_us');
$secondPropertyNameResolver->resolvePropertyName('en_US')->shouldBeCalled()->willReturn('property_2_en_us');
$searchPropertyNameResolverRegistry->getPropertyNameResolvers()->willReturn(
[$firstPropertyNameResolver, $secondPropertyNameResolver]
);
$expectedMultiMatch = new MultiMatch();
$expectedMultiMatch->setQuery('bmw');
$expectedMultiMatch->setFuzziness('AUTO');
$expectedMultiMatch->setFields(['property_1_en_us', 'property_2_en_us']);
$expectedQuery = new BoolQuery();
$expectedQuery->addMust($expectedMultiMatch);
$expectedQuery->addFilter($this->isEnabeldQuery);
$expectedQuery->addFilter($this->hasChannelQuery);
$this->buildQuery(['query' => 'bmw'])->shouldBeLike($expectedQuery);
}
}