Skip to content

Instantly share code, notes, and snippets.

@aohorodnyk
Created October 14, 2014 11:19
Show Gist options
  • Save aohorodnyk/5189c451c10480850916 to your computer and use it in GitHub Desktop.
Save aohorodnyk/5189c451c10480850916 to your computer and use it in GitHub Desktop.
<?php
/**
* {license_notice}
*
* @copyright {copyright}
* @license {license_link}
*/
namespace Magento\Framework\Search\Adapter\Mysql\Filter;
use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
use Magento\Framework\Search\Request\FilterInterface;
use Magento\Framework\Search\Request\Query\Bool as RequestBoolQuery;
use Magento\TestFramework\Helper\ObjectManager;
class BuilderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Magento\Framework\Search\Adapter\Mysql\Filter\Builder
*/
private $builder;
/**
* Set up
*/
protected function setUp()
{
$objectManager = new ObjectManager($this);
/** @var ConditionManager|\PHPUnit_Framework_MockObject_MockObject $conditionManager */
$conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
->disableOriginalConstructor()
->setMethods(['generateCondition', 'combineQueries', 'wrapBrackets'])
->getMock();
$conditionManager->expects($this->any())
->method('generateCondition')
->will(
$this->returnCallback(
function ($field, $operator, $value) {
return sprintf('%s %s %s', $field, $operator, $value);
}
)
);
$conditionManager->expects($this->any())
->method('combineQueries')
->will(
$this->returnCallback(
function ($queries, $operator) {
return implode(
' ' . $operator . ' ',
array_filter($queries, 'strlen')
);
}
)
);
$conditionManager->expects($this->any())
->method('wrapBrackets')
->will(
$this->returnCallback(
function ($query) {
return !empty($query) ? sprintf('(%s)', $query) : '';
}
)
);
$rangeBuilder = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Range')
->setMethods(['buildFilter'])
->disableOriginalConstructor()
->getMock();
$rangeBuilder->expects($this->any())
->method('buildFilter')
->will(
$this->returnCallback(
function (FilterInterface $filter, $isNegation) use (
$conditionManager
) {
/**
* @var \Magento\Framework\Search\Request\Filter\Range $filter
* @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter
*/
$fromCondition = '';
if (!is_null($filter->getFrom())) {
$fromCondition = $conditionManager->generateCondition(
$filter->getField(),
($isNegation ? '<' : '>='),
$filter->getFrom()
);
}
$toCondition = '';
if (!is_null($filter->getTo())) {
$toCondition = $conditionManager->generateCondition(
$filter->getField(),
($isNegation ? '>=' : '<'),
$filter->getTo()
);
}
$unionOperator = $isNegation ? \Zend_Db_Select::SQL_OR : \Zend_Db_Select::SQL_AND;
return $conditionManager->combineQueries([$fromCondition, $toCondition], $unionOperator);
}
)
);
$termBuilder = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Term')
->setMethods(['buildFilter'])
->disableOriginalConstructor()
->getMock();
$termBuilder->expects($this->any())
->method('buildFilter')
->will(
$this->returnCallback(
function (FilterInterface $filter, $isNegation) use (
$conditionManager
) {
/**
* @var \Magento\Framework\Search\Request\Filter\Term $filter
* @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter
*/
return $conditionManager->generateCondition(
$filter->getField(),
($isNegation ? '!=' : '='),
$filter->getValue()
);
}
)
);
$this->builder = $objectManager->getObject(
'Magento\Framework\Search\Adapter\Mysql\Filter\Builder',
[
'range' => $rangeBuilder,
'term' => $termBuilder,
'conditionManager' => $conditionManager,
]
);
}
/**
* @param FilterInterface|\PHPUnit_Framework_MockObject_MockObject $filter
* @param string $conditionType
* @param string $expectedResult
* @dataProvider buildFilterDataProvider
*/
public function testBuildFilter($filter, $conditionType, $expectedResult)
{
$actualResult = $this->builder->build($filter, $conditionType);
$this->assertEquals($expectedResult, $actualResult);
}
/**
* @return array
*/
public function buildFilterDataProvider()
{
return array_merge(
$this->buildTermFilterDataProvider(),
$this->buildRangeFilterDataProvider(),
$this->buildBoolFilterDataProvider()
);
}
/**
* @return array
*/
public function buildTermFilterDataProvider()
{
return [
'termFilter' => [
'filter' => $this->createTermFilter('term1', 123),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '(term1 = 123)',
],
'termFilterNegative' => [
'filter' => $this->createTermFilter('term1', 123),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_NOT,
'expectedResult' => '(term1 != 123)',
],
];
}
/**
* @param $field
* @param $value
* @return \Magento\Framework\Search\Request\Filter\Bool|\PHPUnit_Framework_MockObject_MockObject
*/
private function createTermFilter($field, $value)
{
$filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Term')
->setMethods(['getField', 'getValue'])
->disableOriginalConstructor()
->getMock();
$filter->expects($this->exactly(1))
->method('getField')
->will($this->returnValue($field));
$filter->expects($this->once())
->method('getValue')
->will($this->returnValue($value));
return $filter;
}
/**
* Data provider for BuildFilter
*
* @return array
*/
public function buildRangeFilterDataProvider()
{
return [
'rangeFilter' => [
'filter' => $this->createRangeFilter('range1', 0, 10),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '(range1 >= 0 AND range1 < 10)',
],
'rangeFilterNegative' => [
'filter' => $this->createRangeFilter('range1', 0, 10),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_NOT,
'expectedResult' => '(range1 < 0 OR range1 >= 10)',
]
];
}
/**
* @param $field
* @param $from
* @param $to
* @return \Magento\Framework\Search\Request\Filter\Bool|\PHPUnit_Framework_MockObject_MockObject
*/
private function createRangeFilter($field, $from, $to)
{
$filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Range')
->setMethods(['getField', 'getFrom', 'getTo'])
->disableOriginalConstructor()
->getMock();
$filter->expects($this->exactly(2))
->method('getField')
->will($this->returnValue($field));
$filter->expects($this->atLeastOnce())
->method('getFrom')
->will($this->returnValue($from));
$filter->expects($this->atLeastOnce())
->method('getTo')
->will($this->returnValue($to));
return $filter;
}
/**
* @return array
*/
public function buildBoolFilterDataProvider()
{
return [
'boolFilterWithMust' => [
'filter' => $this->createBoolFilter(
[ //must
$this->createTermFilter('term1', 1),
$this->createRangeFilter('range1', 0, 10),
],
[], //should
[] // mustNot
),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10))',
],
'boolFilterWithShould' => [
'filter' => $this->createBoolFilter(
[], //must
[ //should
$this->createTermFilter('term1', 1),
$this->createRangeFilter('range1', 0, 10),
],
[] // mustNot
),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '(((term1 = 1) OR (range1 >= 0 AND range1 < 10)))',
],
'boolFilterWithMustNot' => [
'filter' => $this->createBoolFilter(
[], //must
[], //should
[ // mustNot
$this->createTermFilter('term1', 1),
$this->createRangeFilter('range1', 0, 10),
]
),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '(((term1 != 1) AND (range1 < 0 OR range1 >= 10)))',
],
'boolFilterWithAllFields' => [
'filter' => $this->createBoolFilter(
[ //must
$this->createTermFilter('term1', 1),
$this->createRangeFilter('range1', 0, 10),
],
[ //should
$this->createTermFilter('term2', 1),
$this->createRangeFilter('range2', 0, 10),
],
[ // mustNot
$this->createTermFilter('term3', 1),
$this->createRangeFilter('range3', 0, 10),
]
),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10)'
. ' AND ((term2 = 1) OR (range2 >= 0 AND range2 < 10))'
. ' AND ((term3 != 1) AND (range3 < 0 OR range3 >= 10)))',
],
'boolFilterInBoolFilter' => [
'filter' => $this->createBoolFilter(
[ //must
$this->createTermFilter('term1', 1),
$this->createRangeFilter('range1', 0, 10),
],
[ //should
$this->createTermFilter('term2', 1),
$this->createRangeFilter('range2', 0, 10),
],
[ // mustNot
$this->createTermFilter('term3', 1),
$this->createRangeFilter('range3', 0, 10),
$this->createBoolFilter(
[ //must
$this->createTermFilter('term4', 1),
$this->createRangeFilter('range4', 0, 10),
],
[ //should
$this->createTermFilter('term5', 1),
$this->createRangeFilter('range5', 0, 10),
],
[ // mustNot
$this->createTermFilter('term6', 1),
$this->createRangeFilter('range6', 0, 10),
]
),
]
),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10)'
. ' AND ((term2 = 1) OR (range2 >= 0 AND range2 < 10))'
. ' AND ((term3 != 1) AND (range3 < 0 OR range3 >= 10)'
. ' AND ((term4 != 1) AND (range4 < 0 OR range4 >= 10)'
. ' AND ((term5 != 1) OR (range5 < 0 OR range5 >= 10))'
. ' AND ((term6 = 1) AND (range6 >= 0 AND range6 < 10)))'
. '))',
],
'boolEmpty' => [
'filter' => $this->createBoolFilter([], [], []),
'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
'expectedResult' => '',
]
];
}
/**
* @param array $must
* @param array $should
* @param array $mustNot
* @return \Magento\Framework\Search\Request\Filter\Bool|\PHPUnit_Framework_MockObject_MockObject
*/
private function createBoolFilter(array $must, array $should, array $mustNot)
{
$filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Bool')
->setMethods(['getMust', 'getShould', 'getMustNot'])
->disableOriginalConstructor()
->getMock();
$filter->expects($this->once())
->method('getMust')
->will($this->returnValue($must));
$filter->expects($this->once())
->method('getShould')
->will($this->returnValue($should));
$filter->expects($this->once())
->method('getMustNot')
->will($this->returnValue($mustNot));
return $filter;
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Unknown filter type 'unknownType'
*/
public function testUnknownFilterType()
{
/** @var FilterInterface|\PHPUnit_Framework_MockObject_MockObject $filter */
$filter = $this->getMockBuilder('Magento\Framework\Search\Request\FilterInterface')
->setMethods(['getType'])
->getMockForAbstractClass();
$filter->expects($this->exactly(2))
->method('getType')
->will($this->returnValue('unknownType'));
$this->builder->build($filter, RequestBoolQuery::QUERY_CONDITION_MUST);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment