diff --git a/features/product/search_products/search_products.feature b/features/product/search_products/search_products.feature
new file mode 100644
index 0000000..09ae982
--- /dev/null
+++ b/features/product/search_products/search_products.feature
@@ -0,0 +1,71 @@
+@search_products
+Feature: Search products
+ In order to find products that fits my needs
+ As a Visitor
+ I want to be able to search products from a keyword
+
+ Background:
+ Given the store operates on a channel named "US Channel" with hostname "127.0.0.1"
+ And that channel allows to shop using "English (United States)" and "Italian (Italy)" locales
+ And it uses the "English (United States)" locale by default
+ And the store operates on another channel named "IT Channel" with hostname "shop.it"
+ And that channel allows to shop using "English (United States)" and "Italian (Italy)" locales
+ And it uses the "Italian (Italy)" locale by default
+
+ And the store has a product "T-Shirt Banana" with code "T_SHIRT_BANANA"
+ And this product is available in "US Channel" channel
+ And this product is also available in "IT Channel" channel
+ And this product is named "Maglietta Banana" in the "Italian (Italy)" locale
+
+ And the store has a product "T-Shirt Apple" available in "US Channel" channel
+ And this product is also available in "IT Channel" channel
+ And this product is named "Maglietta Mela" in the "Italian (Italy)" locale
+
+ And the store has a "T-Shirt Orange" configurable product
+ And this product has a "T-Shirt Orange - Medium size" variant with code "T_SHIRT_ORANGE_M"
+ And this product is available in "US Channel" channel
+ And this product is also available in "IT Channel" channel
+ And this product is named "Maglietta Arancia" in the "Italian (Italy)" locale
+
+ And the store is indexed on Elasticsearch
+ And I am browsing the channel "US Channel"
+
+ @ui
+ Scenario: Search products by code
+ When I search for "T_SHIRT_BANANA"
+ Then I should be redirected to the product "T-Shirt Banana" page
+
+ @ui
+ Scenario: Search products by variant code
+ When I search for "T_SHIRT_ORANGE_M"
+ Then I should be redirected to the product "T-Shirt Orange" page
+
+ @ui
+ Scenario: Search products by name
+ When I search for "shirt"
+ Then I should see "3" results
+ And I should see the product "T-Shirt Banana"
+ And I should see the product "T-Shirt Apple"
+ And I should see the product "T-Shirt Orange"
+
+ @ui
+ Scenario: Search products by name in different locale
+ Given I am browsing the channel "IT Channel"
+ When I search for "maglietta"
+ Then I should see "3" results
+ And I should see the product "Maglietta Banana"
+ And I should see the product "Maglietta Mela"
+ And I should see the product "Maglietta Arancia"
+
+ @ui
+ Scenario: Search products by variant name
+ When I search for "medium"
+ Then I should be redirected to the product "T-Shirt Orange" page
+
+ @ui
+ Scenario: Search only enabled products
+ Given the store has a product "T-Shirt disabled" available in "US Channel" channel
+ And this product has been disabled
+ And the store is indexed on Elasticsearch
+ When I search for "shirt"
+ Then I should see "3" results
diff --git a/src/DocumentType/ProductDocumentType.php b/src/DocumentType/ProductDocumentType.php
index 4897cb4..3d078ac 100644
--- a/src/DocumentType/ProductDocumentType.php
+++ b/src/DocumentType/ProductDocumentType.php
@@ -375,7 +375,7 @@ private function variantProperties(): array
'on-hold' => $this->integer(false),
'is-tracked' => $this->boolean(false),
'shipping-required' => $this->boolean(false),
- 'name' => $this->nestedTranslationKeywords(),
+ 'name' => $this->nestedTranslationTexts(),
'price' => [
'type' => 'object',
'dynamic' => false,
diff --git a/templates/Search/Result/_main.html.twig b/templates/Search/Result/_main.html.twig
index 2c15b3c..54403f7 100644
--- a/templates/Search/Result/_main.html.twig
+++ b/templates/Search/Result/_main.html.twig
@@ -9,7 +9,9 @@
{% if paginator|length > 0 %}
{% for result in paginator %}
- {% include '@SyliusShop/Product/_box.html.twig' with {product: result} %}
+
+ {% include '@SyliusShop/Product/_box.html.twig' with {product: result} %}
+
{% endfor %}
diff --git a/tests/Behat/Context/Ui/Shop/ProductContext.php b/tests/Behat/Context/Ui/Shop/ProductContext.php
index e61401e..2de1687 100644
--- a/tests/Behat/Context/Ui/Shop/ProductContext.php
+++ b/tests/Behat/Context/Ui/Shop/ProductContext.php
@@ -5,6 +5,9 @@
namespace Tests\Webgriffe\SyliusElasticsearchPlugin\Behat\Context\Ui\Shop;
use Behat\Behat\Context\Context;
+use Sylius\Behat\Page\Shop\Product\ShowPageInterface;
+use Sylius\Behat\Service\SharedStorageInterface;
+use Sylius\Component\Core\Model\ProductInterface;
use Tests\Webgriffe\SyliusElasticsearchPlugin\Behat\Page\Shop\Product\IndexPageInterface;
use Webmozart\Assert\Assert;
@@ -12,6 +15,8 @@
{
public function __construct(
private IndexPageInterface $indexPage,
+ private ShowPageInterface $showPage,
+ private SharedStorageInterface $sharedStorage,
) {
}
@@ -40,4 +45,15 @@ public function iFilterProductsByWithValue(string $filterName, string $filterVal
{
$this->indexPage->filterBy($filterName, $filterValue);
}
+
+ /**
+ * @Then /^I should be redirected to the (product "[^"]+") page$/
+ */
+ public function iShouldBeRedirectedToTheProductPage(ProductInterface $product): void
+ {
+ $currentLocaleCode = $this->sharedStorage->get('current_locale_code');
+ $productTranslation = $product->getTranslation($currentLocaleCode);
+
+ Assert::true($this->showPage->isOpen(['_locale' => $currentLocaleCode, 'slug' => $productTranslation->getSlug()]));
+ }
}
diff --git a/tests/Behat/Context/Ui/Shop/SearchContext.php b/tests/Behat/Context/Ui/Shop/SearchContext.php
new file mode 100644
index 0000000..3a8c450
--- /dev/null
+++ b/tests/Behat/Context/Ui/Shop/SearchContext.php
@@ -0,0 +1,37 @@
+sharedStorage->get('current_locale_code');
+
+ $this->searchResultPage->tryToOpen(['_locale' => $currentLocaleCode, 'query' => $searchTerm]);
+ }
+
+ /**
+ * @Then /^I should see "([^"]*)" results$/
+ */
+ public function iShouldSeeResults(int $count): void
+ {
+ Assert::eq($this->searchResultPage->countResults(), $count);
+ }
+}
diff --git a/tests/Behat/Page/Shop/Search/ResultsPage.php b/tests/Behat/Page/Shop/Search/ResultsPage.php
new file mode 100644
index 0000000..862033d
--- /dev/null
+++ b/tests/Behat/Page/Shop/Search/ResultsPage.php
@@ -0,0 +1,20 @@
+getDocument()->findAll('css', '[data-test-result]'));
+ }
+}
diff --git a/tests/Behat/Page/Shop/Search/ResultsPageInterface.php b/tests/Behat/Page/Shop/Search/ResultsPageInterface.php
new file mode 100644
index 0000000..181bec2
--- /dev/null
+++ b/tests/Behat/Page/Shop/Search/ResultsPageInterface.php
@@ -0,0 +1,12 @@
+services();
@@ -12,4 +13,8 @@
$services->set('webgriffe.sylius_elasticsearch_plugin.behat.page.shop.product.index', IndexPage::class)
->parent('sylius.behat.page.shop.product.index')
;
+
+ $services->set('webgriffe.sylius_elasticsearch_plugin.behat.page.shop.search.results', ResultsPage::class)
+ ->parent('sylius.behat.symfony_page')
+ ;
};
diff --git a/tests/Behat/Resources/services/ui.php b/tests/Behat/Resources/services/ui.php
index 407058b..e8f3bbd 100644
--- a/tests/Behat/Resources/services/ui.php
+++ b/tests/Behat/Resources/services/ui.php
@@ -5,6 +5,7 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Tests\Webgriffe\SyliusElasticsearchPlugin\Behat\Context\Ui\Shop\ProductContext;
+use Tests\Webgriffe\SyliusElasticsearchPlugin\Behat\Context\Ui\Shop\SearchContext;
return static function (ContainerConfigurator $containerConfigurator) {
$services = $containerConfigurator->services();
@@ -13,6 +14,16 @@
->public()
->args([
service('webgriffe.sylius_elasticsearch_plugin.behat.page.shop.product.index'),
+ service('sylius.behat.page.shop.product.show'),
+ service('sylius.behat.shared_storage'),
+ ])
+ ;
+
+ $services->set('webgriffe.sylius_elasticsearch_plugin.behat.context.ui.shop.search', SearchContext::class)
+ ->public()
+ ->args([
+ service('webgriffe.sylius_elasticsearch_plugin.behat.page.shop.search.results'),
+ service('sylius.behat.shared_storage'),
])
;
};
diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml
index e56f1b3..01be687 100644
--- a/tests/Behat/Resources/suites.yml
+++ b/tests/Behat/Resources/suites.yml
@@ -1,3 +1,4 @@
imports:
- suites/viewing_products.yaml
- suites/filter_products.yaml
+ - suites/search_products.yaml
diff --git a/tests/Behat/Resources/suites/search_products.yaml b/tests/Behat/Resources/suites/search_products.yaml
new file mode 100644
index 0000000..1b82b44
--- /dev/null
+++ b/tests/Behat/Resources/suites/search_products.yaml
@@ -0,0 +1,53 @@
+default:
+ suites:
+ ui_search_products:
+ contexts:
+ - sylius.behat.context.hook.doctrine_orm
+ - sylius.behat.context.hook.session
+
+ - sylius.behat.context.transform.channel
+ - sylius.behat.context.transform.currency
+ - sylius.behat.context.transform.customer
+ - sylius.behat.context.transform.lexical
+ - sylius.behat.context.transform.locale
+ - sylius.behat.context.transform.product
+ - sylius.behat.context.transform.product_association_type
+ - sylius.behat.context.transform.product_option
+ - sylius.behat.context.transform.product_variant
+ - sylius.behat.context.transform.shared_storage
+ - sylius.behat.context.transform.shipping_category
+ - sylius.behat.context.transform.tax_category
+ - sylius.behat.context.transform.taxon
+ - Sylius\Behat\Context\Transform\CatalogPromotionContext
+
+ - sylius.behat.context.setup.admin_security
+ - sylius.behat.context.setup.admin_user
+ - sylius.behat.context.setup.channel
+ - sylius.behat.context.setup.currency
+ - sylius.behat.context.setup.customer
+ - sylius.behat.context.setup.locale
+ - sylius.behat.context.setup.product
+ - sylius.behat.context.setup.product_association
+ - sylius.behat.context.setup.product_attribute
+ - sylius.behat.context.setup.product_review
+ - sylius.behat.context.setup.product_taxon
+ - sylius.behat.context.setup.shop_security
+ - sylius.behat.context.setup.shipping_category
+ - sylius.behat.context.setup.taxonomy
+ - sylius.behat.context.setup.taxation
+ - sylius.behat.context.setup.product_option
+ - Sylius\Behat\Context\Setup\CatalogPromotionContext
+ - webgriffe.sylius_elasticsearch_plugin.behat.context.setup.elasticsearch
+ - webgriffe.sylius_elasticsearch_plugin.behat.context.setup.product_attribute
+
+ - sylius.behat.context.ui.admin.managing_product_attributes
+ - sylius.behat.context.ui.admin.product_showpage
+ - sylius.behat.context.ui.channel
+ - sylius.behat.context.ui.shop.locale
+ - sylius.behat.context.ui.shop.product
+ - sylius.behat.context.ui.shop.product_attribute
+ - sylius.behat.context.ui.shop.browsing_product
+ - webgriffe.sylius_elasticsearch_plugin.behat.context.ui.shop.product
+ - webgriffe.sylius_elasticsearch_plugin.behat.context.ui.shop.search
+ filters:
+ tags: "@search_products&&@ui"