Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the Search Engine & Filter Builder #17

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@
},
"autoload-dev": {
"psr-4": {
"Setono\\SyliusMeilisearchPlugin\\Tests\\": "tests/"
"Setono\\SyliusMeilisearchPlugin\\Tests\\": "tests/",
"TestApp\\": "tests/Application/src/"
},
"classmap": [
"tests/Application/Kernel.php"
Expand Down
68 changes: 60 additions & 8 deletions src/Engine/SearchEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
namespace Setono\SyliusMeilisearchPlugin\Engine;

use Meilisearch\Client;
use Meilisearch\Contracts\SearchQuery;
use Meilisearch\Search\SearchResult;
use Setono\SyliusMeilisearchPlugin\Config\Index;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\Facet;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataFactoryInterface;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface;
use Setono\SyliusMeilisearchPlugin\Resolver\IndexName\IndexNameResolverInterface;
Expand All @@ -27,19 +29,69 @@
{
$page = max(1, (int) ($parameters['p'] ?? 1));
$sort = (string) ($parameters['sort'] ?? '');
$facetsFilter = $parameters['facets'] ?? [];

Check failure on line 32 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:32:9: MixedAssignment: Unable to determine the type that $facetsFilter is being assigned to (see https://psalm.dev/032)

Check failure on line 32 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:32:9: MixedAssignment: Unable to determine the type that $facetsFilter is being assigned to (see https://psalm.dev/032)

Check failure on line 32 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:32:9: MixedAssignment: Unable to determine the type that $facetsFilter is being assigned to (see https://psalm.dev/032)

$metadata = $this->metadataFactory->getMetadataFor($this->index->document);
$indexUid = $this->indexNameResolver->resolve($this->index);
$query = $query ?? '';
$facets = array_map(static fn (Facet $facet) => $facet->name, $metadata->getFacets());

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:37:71: MixedArgument: Argument 2 of array_map cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

UndefinedInterfaceMethod

src/Engine/SearchEngine.php:37:82: UndefinedInterfaceMethod: Method Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataInterface::getFacets does not exist (see https://psalm.dev/181)

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:37:71: MixedArgument: Argument 2 of array_map cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

UndefinedInterfaceMethod

src/Engine/SearchEngine.php:37:82: UndefinedInterfaceMethod: Method Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataInterface::getFacets does not exist (see https://psalm.dev/181)

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:37:71: MixedArgument: Argument 2 of array_map cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 37 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

UndefinedInterfaceMethod

src/Engine/SearchEngine.php:37:82: UndefinedInterfaceMethod: Method Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataInterface::getFacets does not exist (see https://psalm.dev/181)
$filter = $this->filterBuilder->build($facetsFilter);

Check failure on line 38 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:38:47: MixedArgument: Argument 1 of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface::build cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 38 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:38:47: MixedArgument: Argument 1 of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface::build cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 38 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:38:47: MixedArgument: Argument 1 of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface::build cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

$mainQuery = $this->buildSearchQuery($indexUid, $query, $facets, $filter)

Check failure on line 40 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgumentTypeCoercion

src/Engine/SearchEngine.php:40:74: MixedArgumentTypeCoercion: Argument 4 of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine::buildSearchQuery expects array<string, mixed>, but parent type array<array-key, mixed>|string provided (see https://psalm.dev/194)

Check failure on line 40 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgumentTypeCoercion

src/Engine/SearchEngine.php:40:74: MixedArgumentTypeCoercion: Argument 4 of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine::buildSearchQuery expects array<string, mixed>, but parent type array<array-key, mixed>|string provided (see https://psalm.dev/194)

Check failure on line 40 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgumentTypeCoercion

src/Engine/SearchEngine.php:40:74: MixedArgumentTypeCoercion: Argument 4 of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine::buildSearchQuery expects array<string, mixed>, but parent type array<array-key, mixed>|string provided (see https://psalm.dev/194)
->setHitsPerPage($this->hitsPerPage)
->setPage($page)
;

$searchParams = [
'facets' => $metadata->getFacetableAttributeNames(),
'filter' => $this->filterBuilder->build($parameters),
'hitsPerPage' => $this->hitsPerPage,
'page' => $page,
];
if ('' !== $sort) {
$searchParams['sort'] = [$sort];
$mainQuery->setSort([$sort]);
}

$results = $this->client->multiSearch([

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:49:9: MixedAssignment: Unable to determine the type that $results is being assigned to (see https://psalm.dev/032)

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

ArgumentTypeCoercion

src/Engine/SearchEngine.php:49:47: ArgumentTypeCoercion: Argument 1 of Meilisearch\Client::multiSearch expects list<Meilisearch\Contracts\SearchQuery>, but parent type array{0: Meilisearch\Contracts\SearchQuery, ...<array-key, Meilisearch\Contracts\SearchQuery>} provided (see https://psalm.dev/193)

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:49:9: MixedAssignment: Unable to determine the type that $results is being assigned to (see https://psalm.dev/032)

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

ArgumentTypeCoercion

src/Engine/SearchEngine.php:49:47: ArgumentTypeCoercion: Argument 1 of Meilisearch\Client::multiSearch expects list<Meilisearch\Contracts\SearchQuery>, but parent type array{0: Meilisearch\Contracts\SearchQuery, ...<array-key, Meilisearch\Contracts\SearchQuery>} provided (see https://psalm.dev/193)

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedAssignment

src/Engine/SearchEngine.php:49:9: MixedAssignment: Unable to determine the type that $results is being assigned to (see https://psalm.dev/032)

Check failure on line 49 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

ArgumentTypeCoercion

src/Engine/SearchEngine.php:49:47: ArgumentTypeCoercion: Argument 1 of Meilisearch\Client::multiSearch expects list<Meilisearch\Contracts\SearchQuery>, but parent type array{0: Meilisearch\Contracts\SearchQuery, ...<array-key, Meilisearch\Contracts\SearchQuery>} provided (see https://psalm.dev/193)
$mainQuery,
...$this->createSearchQueries($indexUid, $facets, $query),
])['results'] ?? [];
/** @var array{facetDistribution: array<string, int>} $firstResult */
$firstResult = current($results);

Check failure on line 54 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:54:32: MixedArgument: Argument 1 of current cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 54 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:54:32: MixedArgument: Argument 1 of current cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 54 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:54:32: MixedArgument: Argument 1 of current cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)
$firstResult['facetDistribution'] = array_merge(...array_column($results, 'facetDistribution'));

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:60: MixedArgument: Argument 1 of array_merge cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.1 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:73: MixedArgument: Argument 1 of array_column cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:60: MixedArgument: Argument 1 of array_merge cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: lowest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:73: MixedArgument: Argument 1 of array_column cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:60: MixedArgument: Argument 1 of array_merge cannot be mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

Check failure on line 55 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (PHP8.2 | Deps: highest | SF~5.4.0)

MixedArgument

src/Engine/SearchEngine.php:55:73: MixedArgument: Argument 1 of array_column cannot be array<never, never>|mixed, expecting array<array-key, mixed> (see https://psalm.dev/030)

return new SearchResult($firstResult);
}

/**
* @param array<string> $facets
*
* @return array<SearchQuery>
*/
private function createSearchQueries(string $indexUid, array $facets, ?string $query): array
{
$searchQueries = [];

foreach ($facets as $facet) {
$facets = [$facet];
$filteredFacets = array_filter(
$parameters['facets'] ?? [],
static fn ($value) => $value !== $facet,
\ARRAY_FILTER_USE_KEY,
);
$filter = $this->filterBuilder->build($filteredFacets);

$searchQueries[] = $this->buildSearchQuery($indexUid, $query, $facets, $filter)->setLimit(1);
}

return $this->client->index($this->indexNameResolver->resolve($this->index))->search($query, $searchParams);
return $searchQueries;
}

/**
* @param array<string> $facets
* @param array<string, mixed> $filter
*/
private function buildSearchQuery(string $indexUid, ?string $query, array $facets, array $filter): SearchQuery
{
return (new SearchQuery())
->setIndexUid($indexUid)
->setQuery($query ?? '')
->setFacets($facets)
->setFilter($filter)
;
}
}
34 changes: 34 additions & 0 deletions src/Meilisearch/Builder/CompositeFilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Meilisearch\Builder;

final class CompositeFilterBuilder implements FilterBuilderInterface
{
/**
* @param iterable<FilterBuilderInterface> $filterBuilders
*/
public function __construct(
private readonly iterable $filterBuilders,
) {
}

public function build(array $facets): string|array
{
$filters = [];

foreach ($this->filterBuilders as $filterBuilder) {
if ($filterBuilder->supports($facets)) {
$filters[] = $filterBuilder->build($facets);
}
}

return $filters;
}

public function supports(array $facets): bool
{
return true;
}
}
29 changes: 0 additions & 29 deletions src/Meilisearch/Builder/FilterBuilder.php

This file was deleted.

4 changes: 3 additions & 1 deletion src/Meilisearch/Builder/FilterBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Setono\SyliusMeilisearchPlugin\Meilisearch\Builder;

interface FilterBuilderInterface

Check failure on line 7 in src/Meilisearch/Builder/FilterBuilderInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Method supports() was added to interface Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface
{
public function build(array $parameters): array;
public function build(array $facets): string|array;

Check failure on line 9 in src/Meilisearch/Builder/FilterBuilderInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The return type of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface#build() changed from array to the non-covariant string|array

Check failure on line 9 in src/Meilisearch/Builder/FilterBuilderInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The return type of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface#build() changed from array to string|array

Check failure on line 9 in src/Meilisearch/Builder/FilterBuilderInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Parameter 0 of Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface#build() changed name from parameters to facets
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could potentially unify the return type, to always return array (no matter if with one or multiple elements)


public function supports(array $facets): bool;
}
6 changes: 4 additions & 2 deletions src/Resources/config/services/meilisearch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
<services>
<!-- Builder -->
<service id="Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface"
alias="Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilder"/>
alias="Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\CompositeFilterBuilder"/>

<service id="Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilder"/>
<service id="Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\CompositeFilterBuilder">
<argument type="tagged_iterator" tag="setono_sylius_meilisearch.filter_builder"/>
</service>

<!-- Synonym resolver -->
<service id="Setono\SyliusMeilisearchPlugin\Meilisearch\SynonymResolverInterface"
Expand Down
13 changes: 13 additions & 0 deletions tests/Application/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en_US

services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

TestApp\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

_instanceof:
Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface:
tags: [ 'setono_sylius_meilisearch.filter_builder' ]
26 changes: 26 additions & 0 deletions tests/Application/src/FilterBuilder/BrandFilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace TestApp\FilterBuilder;

use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface;

final class BrandFilterBuilder implements FilterBuilderInterface
{
public function build(array $facets): string|array
{
$brandQuery = [];
/** @var string $size */
foreach ($facets['brand'] as $size) {
$brandQuery[] = sprintf('brand = "%s"', $size);
}

return '(' . implode(' OR ', $brandQuery) . ')';
}

public function supports(array $facets): bool
{
return isset($facets['brand']);
}
}
20 changes: 20 additions & 0 deletions tests/Application/src/FilterBuilder/OnSaleFilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Tests\Application\src\FilterBuilder;

use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface;

final class OnSaleFilterBuilder implements FilterBuilderInterface
{
public function build(array $facets): string|array
{
return 'onSale = true';
}

public function supports(array $facets): bool
{
return isset($facets['onSale']);
}
}
26 changes: 26 additions & 0 deletions tests/Application/src/FilterBuilder/SizeFilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace TestApp\FilterBuilder;

use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface;

final class SizeFilterBuilder implements FilterBuilderInterface
{
public function build(array $facets): string|array
{
$sizeQuery = [];
/** @var string $size */
foreach ($facets['size'] as $size) {
$sizeQuery[] = sprintf('size = "%s"', $size);
}

return '(' . implode(' OR ', $sizeQuery) . ')';
}

public function supports(array $facets): bool
{
return isset($facets['size']);
}
}
13 changes: 13 additions & 0 deletions tests/Functional/SearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,17 @@ public function testItSortsSearchResultsByNewestDate(): void
$previousKey = $key;
}
}

public function testItAlwaysDisplaysFullFacetDistribution(): void
{
/** @var SearchEngine $searchEngine */
$searchEngine = self::getContainer()->get(SearchEngine::class);
$result = $searchEngine->execute(
'jeans',
['facets' => ['brand' => ['Celsius small']]],
);

$this->assertSame(1, $result->getHitsCount());
$this->assertCount(4, $result->getFacetDistribution()['brand']);
}
}
58 changes: 58 additions & 0 deletions tests/Unit/Meilisearch/Builder/CompositeFilterBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Tests\Unit\Meilisearch\Builder;

use PHPUnit\Framework\TestCase;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\CompositeFilterBuilder;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Builder\FilterBuilderInterface;

final class CompositeFilterBuilderTest extends TestCase
{
public function test_it_returns_filters(): void
{
$brandFilterBuilder = $this->createMock(FilterBuilderInterface::class);
$brandFilterBuilder->method('build')->willReturn('(brand = "brand1")');
$brandFilterBuilder->method('supports')->willReturn(true);

$sizeFilterBuilder = $this->createMock(FilterBuilderInterface::class);
$sizeFilterBuilder->method('build')->willReturn('(size = "size1" OR size = "size2")');
$sizeFilterBuilder->method('supports')->willReturn(true);

$compositeFilterBuilder = new CompositeFilterBuilder([$brandFilterBuilder, $sizeFilterBuilder]);

$filters = $compositeFilterBuilder->build([
'onSale' => true,
'brand' => ['brand1'],
'size' => ['size1', 'size2'],
]);

$this->assertSame([
'(brand = "brand1")',
'(size = "size1" OR size = "size2")',
], $filters);
}

public function test_it_uses_only_supported_filter_builders(): void
{
$brandFilterBuilder = $this->createMock(FilterBuilderInterface::class);
$brandFilterBuilder->expects($this->never())->method('build');
$brandFilterBuilder->method('supports')->willReturn(false);

$sizeFilterBuilder = $this->createMock(FilterBuilderInterface::class);
$sizeFilterBuilder->method('build')->willReturn('(size = "size1" OR size = "size2")');
$sizeFilterBuilder->method('supports')->willReturn(true);

$compositeFilterBuilder = new CompositeFilterBuilder([$brandFilterBuilder, $sizeFilterBuilder]);

$filters = $compositeFilterBuilder->build([
'onSale' => true,
'size' => ['size1', 'size2'],
]);

$this->assertSame([
'(size = "size1" OR size = "size2")',
], $filters);
}
}
Loading