first commit

This commit is contained in:
2024-11-11 18:46:54 +01:00
commit a630d17338
25634 changed files with 4923715 additions and 0 deletions

View File

@@ -0,0 +1,408 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\FacetedSearch\Tests\Product;
use Configuration;
use Context;
use Db;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use PrestaShop\Module\FacetedSearch\Filters\Converter;
use PrestaShop\Module\FacetedSearch\Product\SearchProvider;
use PrestaShop\Module\FacetedSearch\URLSerializer;
use PrestaShop\PrestaShop\Core\Product\Search\Facet;
use PrestaShop\PrestaShop\Core\Product\Search\FacetCollection;
use PrestaShop\PrestaShop\Core\Product\Search\Filter;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
use Ps_Facetedsearch;
use Smarty;
use Tools;
class SearchProviderTest extends MockeryTestCase
{
/**
* @var Search
*/
private $provider;
/**
* @var Db
*/
private $database;
/**
* @var Context
*/
private $context;
/**
* @var URLSerializer
*/
private $serializer;
/**
* @var FacetCollection
*/
private $facetCollection;
/**
* @var Ps_Facetedsearch
*/
private $module;
private function mockFacet($label, $data = ['filters' => []], $widgetType = 'checkbox')
{
$facet = Mockery::mock(Facet::class);
$facet->shouldReceive('getLabel')
->andReturn($label);
$facet->shouldReceive('toArray')
->andReturn($data);
$facet->shouldReceive('getWidgetType')
->andReturn($widgetType);
return $facet;
}
private function mockFilter($label, $active = false, $value = null, $properties = [])
{
$filter = Mockery::mock(Filter::class);
$filter->shouldReceive('getLabel')
->andReturn($label);
$filter->shouldReceive('isActive')
->andReturn($active);
if ($value !== null) {
$filter->shouldReceive('getValue')
->andReturn($value);
}
$filter->shouldReceive('getProperty')
->andReturnUsing(
function ($arg) use ($properties) {
return $properties[$arg];
}
);
return $filter;
}
protected function setUp()
{
$this->database = Mockery::mock(Db::class);
$this->context = Mockery::mock(Context::class);
$this->converter = Mockery::mock(Converter::class);
$this->serializer = Mockery::mock(URLSerializer::class);
$this->facetCollection = Mockery::mock(FacetCollection::class);
$this->module = Mockery::mock(Ps_Facetedsearch::class);
$this->module->shouldReceive('getDatabase')
->andReturn($this->database);
$this->module->shouldReceive('getContext')
->andReturn($this->context);
$this->module->shouldReceive('isAjax')
->andReturn(true);
$mock = Mockery::mock(Configuration::class);
$mock->shouldReceive('get')
->andReturnUsing(function ($arg) {
$valueMap = [
'PS_LAYERED_SHOW_QTIES' => true,
];
return $valueMap[$arg];
});
Configuration::setStaticExpectations($mock);
$toolsMock = Mockery::mock(Tools::class);
$toolsMock->shouldReceive('getCurrentUrlProtocolPrefix')
->andReturn('http://');
Tools::setStaticExpectations($toolsMock);
$this->provider = new SearchProvider(
$this->module,
$this->converter,
$this->serializer
);
}
public function testRenderFacetsWithoutFacetsCollection()
{
$productContext = Mockery::mock(ProductSearchContext::class);
$productSearchResult = Mockery::mock(ProductSearchResult::class);
$productSearchResult->shouldReceive('getFacetCollection')
->once()
->andReturn(null);
$this->assertEquals(
'',
$this->provider->renderFacets(
$productContext,
$productSearchResult
)
);
}
public function testRenderFacetsWithFacetsCollection()
{
$productContext = Mockery::mock(ProductSearchContext::class);
$smarty = Mockery::mock(Smarty::class);
$smarty->shouldReceive('assign')
->once()
->with(
[
'show_quantities' => true,
'facets' => [
[
'filters' => [],
],
],
'js_enabled' => true,
'displayedFacets' => [],
'activeFilters' => [],
'sort_order' => 'product.position.asc',
'clear_all_link' => 'http://shop.prestashop.com/catalog?from=scratch',
]
);
$this->context->smarty = $smarty;
$sortOrder = Mockery::mock(SortOrder::class);
$sortOrder->shouldReceive('toString')
->once()
->andReturn('product.position.asc');
$productSearchResult = Mockery::mock(ProductSearchResult::class);
$productSearchResult->shouldReceive('getFacetCollection')
->once()
->andReturn($this->facetCollection);
$productSearchResult->shouldReceive('getCurrentSortOrder')
->once()
->andReturn($sortOrder);
$facet = $this->mockFacet('Test');
$this->facetCollection->shouldReceive('getFacets')
->once()
->andReturn(
[
$facet,
]
);
$this->module->shouldReceive('fetch')
->once()
->with(
'module:ps_facetedsearch/views/templates/front/catalog/facets.tpl'
)
->andReturn('');
$this->assertEquals(
'',
$this->provider->renderFacets(
$productContext,
$productSearchResult
)
);
}
public function testRenderFacetsWithFacetsCollectionAndFilters()
{
$productContext = Mockery::mock(ProductSearchContext::class);
$smarty = Mockery::mock(Smarty::class);
$smarty->shouldReceive('assign')
->once()
->with(
[
'show_quantities' => true,
'facets' => [
[
'displayed' => true,
'filters' => [
[
'label' => 'Men',
'type' => 'category',
'nextEncodedFacets' => 'Categories-Men',
'active' => false,
'facetLabel' => 'Test',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch&q=Categories-Men',
],
[
'label' => 'Women',
'type' => 'category',
'nextEncodedFacets' => '',
'active' => true,
'facetLabel' => 'Test',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch&page=1',
],
],
],
[
'displayed' => true,
'filters' => [
[
'label' => '£22.00 - £35.00',
'type' => 'price',
'active' => false,
'displayed' => true,
'properties' => [],
'magnitude' => 2,
'value' => 0,
'nextEncodedFacets' => '',
'facetLabel' => 'Price',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch',
],
],
],
],
'js_enabled' => true,
'displayedFacets' => [
[
'displayed' => true,
'filters' => [
[
'label' => 'Men',
'type' => 'category',
'nextEncodedFacets' => 'Categories-Men',
'active' => false,
'facetLabel' => 'Test',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch&q=Categories-Men',
],
[
'label' => 'Women',
'type' => 'category',
'nextEncodedFacets' => '',
'active' => true,
'facetLabel' => 'Test',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch&page=1',
],
],
],
[
'displayed' => true,
'filters' => [
[
'label' => '£22.00 - £35.00',
'type' => 'price',
'active' => false,
'displayed' => true,
'properties' => [],
'magnitude' => 2,
'value' => 0,
'nextEncodedFacets' => '',
'facetLabel' => 'Price',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch',
],
],
],
],
'activeFilters' => [
[
'label' => 'Women',
'type' => 'category',
'nextEncodedFacets' => '',
'active' => true,
'facetLabel' => 'Test',
'nextEncodedFacetsURL' => 'http://shop.prestashop.com/catalog?from=scratch&page=1',
],
],
'sort_order' => 'product.position.asc',
'clear_all_link' => 'http://shop.prestashop.com/catalog?from=scratch',
]
);
$this->context->smarty = $smarty;
$sortOrder = Mockery::mock(SortOrder::class);
$sortOrder->shouldReceive('toString')
->once()
->andReturn('product.position.asc');
$productSearchResult = Mockery::mock(ProductSearchResult::class);
$productSearchResult->shouldReceive('getFacetCollection')
->once()
->andReturn($this->facetCollection);
$productSearchResult->shouldReceive('getCurrentSortOrder')
->once()
->andReturn($sortOrder);
$facet = $this->mockFacet(
'Test',
[
'displayed' => true,
'filters' => [
[
'label' => 'Men',
'type' => 'category',
'nextEncodedFacets' => 'Categories-Men',
'active' => false,
],
[
'label' => 'Women',
'type' => 'category',
'nextEncodedFacets' => '',
'active' => true,
],
],
]
);
$facetSlider = $this->mockFacet(
'Price',
[
'displayed' => true,
'filters' => [
[
'label' => '£22.00 - £35.00',
'type' => 'price',
'active' => false,
'displayed' => true,
'properties' => [],
'magnitude' => 2,
'value' => 0,
'nextEncodedFacets' => '',
],
],
],
'slider'
);
$this->facetCollection->shouldReceive('getFacets')
->once()
->andReturn(
[
$facet,
$facetSlider,
]
);
$this->module->shouldReceive('fetch')
->once()
->with(
'module:ps_facetedsearch/views/templates/front/catalog/facets.tpl'
)
->andReturn('');
$this->assertEquals(
'',
$this->provider->renderFacets(
$productContext,
$productSearchResult
)
);
}
}

View File

@@ -0,0 +1,481 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
namespace PrestaShop\Module\FacetedSearch\Tests\Product;
use Configuration;
use Context;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use PrestaShop\Module\FacetedSearch\Adapter\MySQL;
use PrestaShop\Module\FacetedSearch\Product\Search;
use stdClass;
use Tools;
class SearchTest extends MockeryTestCase
{
/**
* @var Search
*/
private $search;
protected function setUp()
{
$mock = Mockery::mock(Configuration::class);
$mock->shouldReceive('get')
->andReturnUsing(function ($arg) {
$valueMap = [
'PS_STOCK_MANAGEMENT' => true,
'PS_ORDER_OUT_OF_STOCK' => true,
'PS_HOME_CATEGORY' => true,
'PS_LAYERED_FULL_TREE' => false,
'PS_LAYERED_FILTER_BY_DEFAULT_CATEGORY' => true,
];
return $valueMap[$arg];
});
Configuration::setStaticExpectations($mock);
$contextMock = Mockery::mock(Context::class);
$contextMock->shop = new stdClass();
$contextMock->shop->id = 1;
Context::setStaticExpectations($contextMock);
$this->search = new Search($contextMock);
}
public function testGetFacetedSearchTypeAdapter()
{
$this->assertInstanceOf(
MySQL::class,
$this->search->getSearchAdapter()
);
}
public function testInitSearchWithEmptyFilters()
{
$toolsMock = Mockery::mock(Tools::class);
$toolsMock->shouldReceive('getValue')
->andReturnUsing(function ($arg) {
$valueMap = [
'id_category' => 12,
'id_category_layered' => 11,
];
return $valueMap[$arg];
});
Tools::setStaticExpectations($toolsMock);
$this->search->initSearch([]);
$this->assertEquals([], $this->search->getSearchAdapter()->getFilters()->toArray());
$this->assertEquals([], $this->search->getSearchAdapter()->getOperationsFilters()->toArray());
$this->assertEquals(
[
'id_category_default' => [
'=' => [
[
null,
],
],
],
'id_category' => [
'=' => [
[
null,
],
],
],
'id_shop' => [
'=' => [
[
1,
],
],
],
'visibility' => [
'=' => [
[
'both',
'catalog',
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getFilters()->toArray()
);
$this->assertEquals([], $this->search->getSearchAdapter()->getInitialPopulation()->getOperationsFilters()->toArray());
}
public function testInitSearchWithAllFilters()
{
$toolsMock = Mockery::mock(Tools::class);
$toolsMock->shouldReceive('getValue')
->andReturnUsing(function ($arg) {
$valueMap = [
'id_category' => 12,
'id_category_layered' => 11,
];
return $valueMap[$arg];
});
Tools::setStaticExpectations($toolsMock);
$this->search->initSearch(
[
'id_feature' => [
[1, 2],
],
'id_attribute_group' => [
[4, 5],
],
'category' => [
[6],
],
'quantity' => [
0,
],
'weight' => [
'10',
'40',
],
'price' => [
'50',
'200',
],
'manufacturer' => [
'10',
],
'condition' => [
'1',
],
]
);
$this->assertEquals([], $this->search->getSearchAdapter()->getFilters()->toArray());
$this->assertEquals([], $this->search->getSearchAdapter()->getOperationsFilters()->toArray());
$this->assertEquals(
[
'weight' => [
'>=' => [
[
10.0,
],
],
'<=' => [
[
40.0,
],
],
],
'price_min' => [
'>=' => [
[
50.0,
],
],
],
'price_max' => [
'<=' => [
[
200.0,
],
],
],
'id_manufacturer' => [
'=' => [
[
'10',
],
],
],
'condition' => [
'=' => [
[
'1',
],
],
],
'id_shop' => [
'=' => [
[
1,
],
],
],
'visibility' => [
'=' => [
[
'both',
'catalog',
],
],
],
'id_category' => [
'=' => [
[
null,
],
[
6,
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getFilters()->toArray()
);
$this->assertEquals(
[
'with_stock_management' => [
[
[
'quantity',
[
0,
],
'<=',
],
[
'out_of_stock',
[
0,
],
'=',
],
],
],
'with_attributes_0' => [
[
[
'id_attribute',
[
4,
5,
],
],
],
],
'with_features_0' => [
[
[
'id_feature_value',
[
1,
2,
],
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getOperationsFilters()->toArray()
);
}
public function testInitSearchWithManyFeatures()
{
$toolsMock = Mockery::mock(Tools::class);
$toolsMock->shouldReceive('getValue')
->andReturnUsing(function ($arg) {
$valueMap = [
'id_category' => 12,
'id_category_layered' => 11,
];
return $valueMap[$arg];
});
Tools::setStaticExpectations($toolsMock);
$this->search->initSearch(
[
'id_feature' => [
[1],
[2, 3, 4],
],
]
);
$this->assertEquals([], $this->search->getSearchAdapter()->getFilters()->toArray());
$this->assertEquals([], $this->search->getSearchAdapter()->getOperationsFilters()->toArray());
$this->assertEquals(
[
'id_shop' => [
'=' => [
[
1,
],
],
],
'visibility' => [
'=' => [
[
'both',
'catalog',
],
],
],
'id_category_default' => [
'=' => [
[
null,
],
],
],
'id_category' => [
'=' => [
[
null,
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getFilters()->toArray()
);
$this->assertEquals(
[
'with_features_0' => [
[
[
'id_feature_value',
[
1,
],
],
],
],
'with_features_1' => [
[
[
'id_feature_value',
[
2,
3,
4,
],
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getOperationsFilters()->toArray()
);
}
public function testInitSearchWithManyAttributes()
{
$toolsMock = Mockery::mock(Tools::class);
$toolsMock->shouldReceive('getValue')
->andReturnUsing(function ($arg) {
$valueMap = [
'id_category' => 12,
'id_category_layered' => 11,
];
return $valueMap[$arg];
});
Tools::setStaticExpectations($toolsMock);
$this->search->initSearch(
[
'id_attribute_group' => [
[1],
[2, 3, 4],
],
]
);
$this->assertEquals([], $this->search->getSearchAdapter()->getFilters()->toArray());
$this->assertEquals([], $this->search->getSearchAdapter()->getOperationsFilters()->toArray());
$this->assertEquals(
[
'id_shop' => [
'=' => [
[
1,
],
],
],
'visibility' => [
'=' => [
[
'both',
'catalog',
],
],
],
'id_category_default' => [
'=' => [
[
null,
],
],
],
'id_category' => [
'=' => [
[
null,
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getFilters()->toArray()
);
$this->assertEquals(
[
'with_attributes_0' => [
[
[
'id_attribute',
[
1,
],
],
],
],
'with_attributes_1' => [
[
[
'id_attribute',
[
2,
3,
4,
],
],
],
],
],
$this->search->getSearchAdapter()->getInitialPopulation()->getOperationsFilters()->toArray()
);
}
public function testAddFilter()
{
$this->search->addFilter('weight', [10, 20]);
$this->search->addFilter('id_feature', [[10, 20]]);
}
}