Skip to content

Commit 5bd198b

Browse files
Merge pull request #5294 in SW/shopware from sw-19524/5.3/fix-article-box-with-numeric-numbers to 5.3
* commit '40d5170296184668e0ba2bbbac7e4203bbb4d1e9': SW-19524 - Fix article box with numeric numbers
2 parents dc7562d + 40d5170 commit 5bd198b

File tree

4 files changed

+342
-164
lines changed

4 files changed

+342
-164
lines changed

engine/Shopware/Bundle/SearchBundle/BatchProductNumberSearch.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public function search(BatchProductNumberSearchRequest $request, ShopContextInte
8686
* @param BaseProduct[] $baseProducts
8787
* @param int $numberOfProducts
8888
*
89-
* @return array
89+
* @return BaseProduct[]
9090
*/
9191
private function getBaseProductsRange($key, array $baseProducts, $numberOfProducts = 0)
9292
{
@@ -131,7 +131,12 @@ private function getBaseProductsByCriteriaList(array $criteriaList, ShopContextI
131131

132132
$this->pointer[$key] = 0;
133133
foreach ($criteriaMeta['requests'] as $request) {
134-
$products[$request['key']] = $this->getBaseProductsRange($key, $baseProducts, $request['criteria']->getLimit());
134+
$products[$request['key']] = [];
135+
$productRange = $this->getBaseProductsRange($key, $baseProducts, $request['criteria']->getLimit());
136+
137+
foreach ($productRange as $product) {
138+
$products[$request['key']][$product->getNumber()] = $product;
139+
}
135140
}
136141
}
137142

engine/Shopware/Bundle/SearchBundle/BatchProductNumberSearchResult.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,15 @@ public function getProductNumbers()
7878
return $this->storage;
7979
}
8080

81-
$productNumbers = array_merge(...array_values($this->storage));
81+
$productNumbers = [];
8282

83-
return array_keys($productNumbers);
83+
/** @var BaseProduct[] $products */
84+
foreach ($this->storage as $products) {
85+
foreach ($products as $product) {
86+
$productNumbers[] = $product->getNumber();
87+
}
88+
}
89+
90+
return $productNumbers;
8491
}
8592
}
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
<?php
2+
/**
3+
* Shopware 5
4+
* Copyright (c) shopware AG
5+
*
6+
* According to our dual licensing model, this program can be used either
7+
* under the terms of the GNU Affero General Public License, version 3,
8+
* or under a proprietary license.
9+
*
10+
* The texts of the GNU Affero General Public License with an additional
11+
* permission and of our proprietary license can be found at and
12+
* in the LICENSE file you have received along with this program.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* "Shopware" is a registered trademark of shopware AG.
20+
* The licensing of the program under the AGPLv3 does not imply a
21+
* trademark license. Therefore any rights, title and interest in
22+
* our trademarks remain entirely with us.
23+
*/
24+
25+
namespace Shopware\Tests\Functional\Bundle\SearchBundle;
26+
27+
use Doctrine\DBAL\Connection;
28+
use Shopware\Bundle\SearchBundle\BatchProductNumberSearch;
29+
use Shopware\Bundle\SearchBundle\BatchProductNumberSearchRequest;
30+
use Shopware\Bundle\SearchBundle\Condition\CategoryCondition;
31+
use Shopware\Bundle\SearchBundle\Condition\PriceCondition;
32+
use Shopware\Bundle\SearchBundle\Criteria;
33+
use Shopware\Bundle\SearchBundle\Sorting\ProductNameSorting;
34+
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContext;
35+
use Shopware\Models\Category\Category;
36+
use Shopware\Tests\Functional\Bundle\StoreFrontBundle\TestCase;
37+
38+
/**
39+
* @group elasticSearch
40+
*/
41+
class BatchProductNumberSearchTest extends TestCase
42+
{
43+
/**
44+
* @var BatchProductNumberSearch
45+
*/
46+
private $batchSearch;
47+
48+
/**
49+
* @var Connection
50+
*/
51+
private $connection;
52+
53+
protected function setUp()
54+
{
55+
$this->connection = Shopware()->Container()->get('dbal_connection');
56+
$this->connection->beginTransaction();
57+
$this->batchSearch = Shopware()->Container()->get('shopware_search.batch_product_number_search');
58+
59+
parent::setUp();
60+
}
61+
62+
public function tearDown()
63+
{
64+
$this->connection->rollBack();
65+
66+
parent::tearDown();
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
public function createProducts($products, ShopContext $context, Category $category)
73+
{
74+
$articles = parent::createProducts($products, $context, $category);
75+
76+
$this->helper->refreshSearchIndexes($context->getShop());
77+
78+
return $articles;
79+
}
80+
81+
public function testSearchWithMatchingProducts()
82+
{
83+
$context = $this->getContext();
84+
$category = $this->helper->createCategory();
85+
$this->createProducts(['BATCH-1' => [], 'BATCH-2' => []], $context, $category);
86+
87+
$request = new BatchProductNumberSearchRequest();
88+
$request->setProductNumbers('test-1', ['BATCH-1', 'BATCH-2']);
89+
90+
$result = $this->batchSearch->search($request, $context);
91+
92+
$products = $result->get('test-1');
93+
94+
$this->assertCount(2, $products);
95+
$this->assertProductNumbersExists($products, ['BATCH-1', 'BATCH-2']);
96+
}
97+
98+
public function testSearchIncludingMissingProducts()
99+
{
100+
$context = $this->getContext();
101+
$category = $this->helper->createCategory();
102+
$this->createProducts(['BATCH-1' => [], 'BATCH-2' => []], $context, $category);
103+
104+
$request = new BatchProductNumberSearchRequest();
105+
$request->setProductNumbers('test-1', ['BATCH-1', 'BATCH-2', 'NOT_EXISTING']);
106+
$request->setProductNumbers('test-2', ['NOT_EXISTING']);
107+
108+
$result = $this->batchSearch->search($request, $context);
109+
$products = $result->get('test-1');
110+
$this->assertCount(2, $products);
111+
$this->assertProductNumbersExists($products, ['BATCH-1', 'BATCH-2']);
112+
113+
$this->assertSame([], $result->get('test-2'));
114+
}
115+
116+
public function testSearchWithCriteria()
117+
{
118+
$context = $this->getContext();
119+
$category = $this->helper->createCategory();
120+
$this->createProducts(['BATCH-A' => [], 'BATCH-B' => [], 'BATCH-C' => []], $context, $category);
121+
122+
$criteria = new Criteria();
123+
$criteria->addCondition(new CategoryCondition([$category->getId()]));
124+
$criteria->limit(3);
125+
126+
$request = new BatchProductNumberSearchRequest();
127+
$request->setCriteria('test-criteria-1', $criteria);
128+
129+
$result = $this->batchSearch->search($request, $context);
130+
131+
$products = $result->get('test-criteria-1');
132+
$this->assertCount(3, $products);
133+
$this->assertProductNumbersExists($products, ['BATCH-A', 'BATCH-B', 'BATCH-C']);
134+
}
135+
136+
public function testSearchWithMultipleCriteria()
137+
{
138+
$context = $this->getContext();
139+
$category = $this->helper->createCategory();
140+
$this->createProducts(
141+
[
142+
'BATCH-A' => ['name' => 'BATCH-A'],
143+
'BATCH-B' => ['name' => 'BATCH-B'],
144+
'BATCH-C' => ['name' => 'BATCH-C'],
145+
'BATCH-D' => ['name' => 'BATCH-D'],
146+
'BATCH-E' => ['name' => 'BATCH-E'],
147+
'BATCH-F' => ['name' => 'BATCH-F'],
148+
'BATCH-G' => ['name' => 'BATCH-G'],
149+
],
150+
$context,
151+
$category
152+
);
153+
154+
$criteria = new Criteria();
155+
$criteria->addCondition(new CategoryCondition([$category->getId()]));
156+
$criteria->addSorting(new ProductNameSorting());
157+
$criteria->limit(3);
158+
159+
$criteria2 = new Criteria();
160+
$criteria2->addCondition(new CategoryCondition([$category->getId()]));
161+
$criteria2->addSorting(new ProductNameSorting());
162+
$criteria2->limit(4);
163+
164+
$request = new BatchProductNumberSearchRequest();
165+
$request->setCriteria('test-criteria-1', $criteria);
166+
$request->setCriteria('test-criteria-2', $criteria2);
167+
168+
$result = $this->batchSearch->search($request, $context);
169+
170+
$products = $result->get('test-criteria-1');
171+
$this->assertCount(3, $products);
172+
$this->assertProductNumbersExists($products, ['BATCH-A', 'BATCH-B', 'BATCH-C']);
173+
174+
$products = $result->get('test-criteria-2');
175+
$this->assertCount(4, $products);
176+
$this->assertProductNumbersExists($products, ['BATCH-D', 'BATCH-E', 'BATCH-F', 'BATCH-G']);
177+
}
178+
179+
public function testSearchWithMultipleCriteriaAndProductNumbers()
180+
{
181+
$context = $this->getContext();
182+
$category = $this->helper->createCategory();
183+
$this->createProducts(
184+
[
185+
'BATCH-A' => ['name' => 'BATCH-A'],
186+
'BATCH-B' => ['name' => 'BATCH-B'],
187+
'BATCH-C' => ['name' => 'BATCH-C'],
188+
'BATCH-D' => ['name' => 'BATCH-D'],
189+
'BATCH-E' => ['name' => 'BATCH-E'],
190+
'BATCH-F' => ['name' => 'BATCH-F'],
191+
'BATCH-G' => ['name' => 'BATCH-G'],
192+
'BATCH-H' => ['name' => 'BATCH-H'],
193+
'BATCH-I' => ['name' => 'BATCH-I'],
194+
'BATCH-J' => ['name' => 'BATCH-J'],
195+
],
196+
$context,
197+
$category
198+
);
199+
200+
$criteria = new Criteria();
201+
$criteria->addCondition(new CategoryCondition([$category->getId()]));
202+
$criteria->addSorting(new ProductNameSorting());
203+
$criteria->limit(3);
204+
205+
$criteria2 = new Criteria();
206+
$criteria2->addCondition(new CategoryCondition([$category->getId()]));
207+
$criteria2->addSorting(new ProductNameSorting());
208+
$criteria2->limit(4);
209+
210+
$request = new BatchProductNumberSearchRequest();
211+
$request->setCriteria('test-criteria-1', $criteria);
212+
$request->setCriteria('test-criteria-2', $criteria2);
213+
$request->setProductNumbers('test-1', ['BATCH-A', 'BATCH-H', 'BATCH-J']);
214+
215+
$result = $this->batchSearch->search($request, $context);
216+
217+
$products = $result->get('test-criteria-1');
218+
$this->assertCount(3, $products);
219+
$this->assertProductNumbersExists($products, ['BATCH-A', 'BATCH-B', 'BATCH-C']);
220+
221+
$products = $result->get('test-criteria-2');
222+
$this->assertCount(4, $products);
223+
$this->assertProductNumbersExists($products, ['BATCH-D', 'BATCH-E', 'BATCH-F', 'BATCH-G']);
224+
225+
$products = $result->get('test-1');
226+
$this->assertCount(3, $products);
227+
$this->assertProductNumbersExists($products, ['BATCH-A', 'BATCH-H', 'BATCH-J']);
228+
}
229+
230+
public function testNotExistingKeyShouldThrowException()
231+
{
232+
$context = $this->getContext();
233+
$request = new BatchProductNumberSearchRequest();
234+
235+
$result = $this->batchSearch->search($request, $context);
236+
237+
$this->expectException(\OutOfBoundsException::class);
238+
$result->get('not_existing');
239+
}
240+
241+
public function testNonMatchingProductNumbersShouldReturnEmptyArray()
242+
{
243+
$context = $this->getContext();
244+
$request = new BatchProductNumberSearchRequest();
245+
$request->setProductNumbers('test-1', ['NOT_EXISTING']);
246+
247+
$result = $this->batchSearch->search($request, $context);
248+
249+
$this->assertSame([], $result->get('test-1'));
250+
}
251+
252+
public function testNonMatchingConditionShouldReturnEmptyArray()
253+
{
254+
$criteria = new Criteria();
255+
$criteria->addCondition(new PriceCondition(99999999));
256+
$criteria->limit(1);
257+
258+
$context = $this->getContext();
259+
$request = new BatchProductNumberSearchRequest();
260+
$request->setCriteria('test-1', $criteria);
261+
262+
$result = $this->batchSearch->search($request, $context);
263+
264+
$this->assertSame([], $result->get('test-1'));
265+
}
266+
267+
/**
268+
* @param array $result
269+
* @param string[] $numbers
270+
*/
271+
private function assertProductNumbersExists(array $result, array $numbers)
272+
{
273+
array_walk($numbers, function ($number) use ($result) {
274+
$this->assertArrayHasKey($number, $result, sprintf('Expected "%s" to be in [%s]', $number, implode(', ', array_keys($result))));
275+
$this->assertSame($number, $result[$number]->getNumber());
276+
});
277+
}
278+
}

0 commit comments

Comments
 (0)