Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
CustomAttributeFilterTest.php
Go to the documentation of this file.
1 <?php
7 
11 use Magento\Eav\Model\Config as EavConfig;
16 
17 class CustomAttributeFilterTest extends \PHPUnit\Framework\TestCase
18 {
20  private $objectManager;
21 
23  private $resource;
24 
26  private $customAttributeFilter;
27 
29  private $eavConfigMock;
30 
32  private $storeManager;
33 
35  private $conditionManager;
36 
37  protected function setUp()
38  {
40  $this->resource = $this->objectManager->create(ResourceConnection::class);
41  $this->storeManager = $this->objectManager->create(StoreManagerInterface::class);
42  $this->conditionManager = $this->objectManager->create(ConditionManager::class);
43 
44  $this->eavConfigMock = $this->getMockBuilder(EavConfig::class)
45  ->disableOriginalConstructor()
46  ->getMock();
47 
48  $this->customAttributeFilter = $this->objectManager->create(
49  CustomAttributeFilter::class,
50  [
51  'eavConfig' => $this->eavConfigMock
52  ]
53  );
54  }
55 
56  public function testApplyWithoutFilters()
57  {
58  $select = $this->resource->getConnection()->select();
59  $filters = [];
60 
61  $resultSelect = $this->customAttributeFilter->apply($select, ...$filters);
62 
63  $this->assertEquals(
64  (string) $select,
65  (string) $resultSelect,
66  'Select queries must be the same in case when we have no filters to apply.'
67  );
68  }
69 
75  {
76  $select = $this->resource->getConnection()->select();
77  $filters = $this->mockFilters();
78  $firstFilter = reset($filters);
79 
80  $this->eavConfigMock
81  ->method('getAttribute')
82  ->with(Product::ENTITY, $firstFilter->getField())
83  ->willReturn(null);
84 
85  $this->customAttributeFilter->apply($select, ...$filters);
86  }
87 
88  public function testApplyByOneFilter()
89  {
90  $select = $this->resource->getConnection()->select();
91  $select->from(
92  ['some_index' => 'some_table'],
93  ['entity_id' => 'entity_id']
94  );
95 
96  $filters = $this->mockFilters();
97  $firstFilter = reset($filters);
98 
99  $attributes = $this->mockAttributes();
100  $firstAttribute = reset($attributes);
101 
102  $this->eavConfigMock
103  ->method('getAttribute')
104  ->with(Product::ENTITY, $firstFilter->getField())
105  ->willReturn($firstAttribute);
106 
107  $resultSelect = $this->customAttributeFilter->apply($select, ...[$firstFilter]);
108 
109  $expectedSelect = $this->getSqlForOneAttributeSearch();
110 
111  $this->assertEquals(
112  (string) $expectedSelect,
113  (string) $resultSelect,
114  'Select queries must be the same in case when we have one filter to apply.'
115  );
116  }
117 
118  public function testApplyByTwoFilters()
119  {
120  $select = $this->resource->getConnection()->select();
121  $select->from(
122  ['some_index' => 'some_table'],
123  ['entity_id' => 'entity_id']
124  );
125 
126  $filters = $this->mockFilters();
127  $attributes = $this->mockAttributes();
128 
129  $this->eavConfigMock
130  ->method('getAttribute')
131  ->withConsecutive(
132  [Product::ENTITY, $filters[0]->getField()],
133  [Product::ENTITY, $filters[1]->getField()]
134  )->will(
135  $this->onConsecutiveCalls(...$attributes)
136  );
137 
138  $resultSelect = $this->customAttributeFilter->apply($select, ...$filters);
139 
140  $expectedSelect = $this->getSqlForTwoAttributeSearch();
141 
142  $this->assertEquals(
143  (string) $expectedSelect,
144  (string) $resultSelect,
145  'Select queries must be the same in case when we have two filters to apply.'
146  );
147  }
148 
149  private function getSqlForOneAttributeSearch()
150  {
151  $filters = $this->mockFilters();
152  $firstFilter = reset($filters);
153  $attributes = $this->mockAttributes();
154  $firstAttribute = reset($attributes);
155 
156  $joinConditions = [
157  '`some_index`.`entity_id` = `field1_filter`.`entity_id`',
158  '`some_index`.`source_id` = `field1_filter`.`source_id`',
159  sprintf('`field1_filter`.`attribute_id` = %s', $firstAttribute->getId()),
160  sprintf('`field1_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId())
161  ];
162 
163  $select = $this->resource->getConnection()->select();
164  $select->from(
165  ['some_index' => 'some_table'],
166  ['entity_id' => 'entity_id']
167  )->joinInner(
168  ['field1_filter' => $this->resource->getTableName('catalog_product_index_eav')],
169  $this->conditionManager->combineQueries($joinConditions, Select::SQL_AND),
170  []
171  )->where(sprintf('`some_index`.`attribute_id` = %s', $firstAttribute->getId()))
172  ->where(sprintf("`some_index`.`value` = '%s'", $firstFilter->getValue()));
173 
174  return $select;
175  }
176 
177  private function getSqlForTwoAttributeSearch()
178  {
179  $attributes = $this->mockAttributes();
180  $firstAttribute = array_shift($attributes);
181  $secondAttribute = array_shift($attributes);
182 
183  $joinConditions1 = [
184  '`some_index`.`entity_id` = `field1_filter`.`entity_id`',
185  '`some_index`.`source_id` = `field1_filter`.`source_id`',
186  sprintf('`field1_filter`.`attribute_id` = %s', $firstAttribute->getId()),
187  sprintf('`field1_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId())
188  ];
189 
190  $joinConditions2 = [
191  '`some_index`.`entity_id` = `field2_filter`.`entity_id`',
192  '`some_index`.`source_id` = `field2_filter`.`source_id`',
193  sprintf('`field2_filter`.`attribute_id` = %s', $secondAttribute->getId()),
194  sprintf('`field2_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId())
195  ];
196 
197  $select = $this->resource->getConnection()->select();
198  $select->from(
199  ['some_index' => 'some_table'],
200  ['entity_id' => 'entity_id']
201  )->joinInner(
202  ['field1_filter' => $this->resource->getTableName('catalog_product_index_eav')],
203  $this->conditionManager->combineQueries($joinConditions1, Select::SQL_AND),
204  []
205  )->joinInner(
206  ['field2_filter' => $this->resource->getTableName('catalog_product_index_eav')],
207  $this->conditionManager->combineQueries($joinConditions2, Select::SQL_AND),
208  []
209  );
210 
211  return $select;
212  }
213 
214  private function mockFilters()
215  {
216  $filters = [];
217 
218  $filters[] = $this->getMockBuilder(Term::class)
219  ->setConstructorArgs(['name2', 'value2', 'field1'])
220  ->setMethods(null)
221  ->getMock();
222 
223  $filters[] = $this->getMockBuilder(Term::class)
224  ->setConstructorArgs(['name3', 'value3', 'field2'])
225  ->setMethods(null)
226  ->getMock();
227 
228  return $filters;
229  }
230 
231  private function mockAttributes()
232  {
233  $attribute1 = $this->getMockBuilder(AbstractAttribute::class)
234  ->disableOriginalConstructor()
235  ->setMethods(['getId'])
236  ->getMockForAbstractClass();
237 
239  ->method('getId')
240  ->willReturn(42);
241 
242  $attribute2 = $this->getMockBuilder(AbstractAttribute::class)
243  ->disableOriginalConstructor()
244  ->setMethods(['getId'])
245  ->getMockForAbstractClass();
246 
248  ->method('getId')
249  ->willReturn(450);
250 
251  return [$attribute1, $attribute2];
252  }
253 }
const SQL_AND
Definition: Select.php:77
$attributes
Definition: matrix.phtml:13
$filters
Definition: uploader.phtml:11