Skip to content

Commit 611ebad

Browse files
ENGCOM-6115: Fix: add to cart grouped product when exists a sold out option #24955
2 parents 8f1413e + 7ff220b commit 611ebad

File tree

2 files changed

+139
-28
lines changed

2 files changed

+139
-28
lines changed

app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr
344344
}
345345
foreach ($associatedProducts as $subProduct) {
346346
if (!isset($productsInfo[$subProduct->getId()])) {
347-
if ($isStrictProcessMode && !$subProduct->getQty()) {
347+
if ($isStrictProcessMode && !$subProduct->getQty() && $subProduct->isSalable()) {
348348
return __('Please specify the quantity of product(s).')->render();
349349
}
350350
$productsInfo[$subProduct->getId()] = $subProduct->isSalable() ? (float)$subProduct->getQty() : 0;

app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php

Lines changed: 138 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Magento\GroupedProduct\Model\Product\Type\Grouped;
99

1010
/**
11+
* Tests for Grouped product
12+
*
1113
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1214
*/
1315
class GroupedTest extends \PHPUnit\Framework\TestCase
@@ -42,6 +44,9 @@ class GroupedTest extends \PHPUnit\Framework\TestCase
4244
*/
4345
private $serializer;
4446

47+
/**
48+
* @inheritdoc
49+
*/
4550
protected function setUp()
4651
{
4752
$this->objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -74,12 +79,22 @@ protected function setUp()
7479
);
7580
}
7681

77-
public function testHasWeightFalse()
82+
/**
83+
* Verify has weight is false
84+
*
85+
* @return void
86+
*/
87+
public function testHasWeightFalse(): void
7888
{
7989
$this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not');
8090
}
8191

82-
public function testGetChildrenIds()
92+
/**
93+
* Verify children ids.
94+
*
95+
* @return void
96+
*/
97+
public function testGetChildrenIds(): void
8398
{
8499
$parentId = 12345;
85100
$childrenIds = [100, 200, 300];
@@ -96,7 +111,12 @@ public function testGetChildrenIds()
96111
$this->assertEquals($childrenIds, $this->_model->getChildrenIds($parentId));
97112
}
98113

99-
public function testGetParentIdsByChild()
114+
/**
115+
* Verify get parents by child products
116+
*
117+
* @return void
118+
*/
119+
public function testGetParentIdsByChild(): void
100120
{
101121
$childId = 12345;
102122
$parentIds = [100, 200, 300];
@@ -113,7 +133,12 @@ public function testGetParentIdsByChild()
113133
$this->assertEquals($parentIds, $this->_model->getParentIdsByChild($childId));
114134
}
115135

116-
public function testGetAssociatedProducts()
136+
/**
137+
* Verify get associated products
138+
*
139+
* @return void
140+
*/
141+
public function testGetAssociatedProducts(): void
117142
{
118143
$cached = true;
119144
$associatedProducts = [5, 7, 11, 13, 17];
@@ -123,27 +148,36 @@ public function testGetAssociatedProducts()
123148
}
124149

125150
/**
151+
* Verify able to set status filter
152+
*
126153
* @param int $status
127154
* @param array $filters
128155
* @param array $result
129156
* @dataProvider addStatusFilterDataProvider
130157
*/
131-
public function testAddStatusFilter($status, $filters, $result)
158+
public function testAddStatusFilter($status, $filters, $result): void
132159
{
133160
$this->product->expects($this->once())->method('getData')->will($this->returnValue($filters));
134161
$this->product->expects($this->once())->method('setData')->with('_cache_instance_status_filters', $result);
135162
$this->assertEquals($this->_model, $this->_model->addStatusFilter($status, $this->product));
136163
}
137164

138165
/**
166+
* Data Provider for Status Filter
167+
*
139168
* @return array
140169
*/
141-
public function addStatusFilterDataProvider()
170+
public function addStatusFilterDataProvider(): array
142171
{
143172
return [[1, [], [1]], [1, false, [1]]];
144173
}
145174

146-
public function testSetSaleableStatus()
175+
/**
176+
* Verify able to set salable status
177+
*
178+
* @return void
179+
*/
180+
public function testSetSaleableStatus(): void
147181
{
148182
$key = '_cache_instance_status_filters';
149183
$saleableIds = [300, 800, 500];
@@ -159,7 +193,12 @@ public function testSetSaleableStatus()
159193
$this->assertEquals($this->_model, $this->_model->setSaleableStatus($this->product));
160194
}
161195

162-
public function testGetStatusFiltersNoData()
196+
/**
197+
* Verify status filter with no data.
198+
*
199+
* @return void
200+
*/
201+
public function testGetStatusFiltersNoData(): void
163202
{
164203
$result = [
165204
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED,
@@ -169,7 +208,12 @@ public function testGetStatusFiltersNoData()
169208
$this->assertEquals($result, $this->_model->getStatusFilters($this->product));
170209
}
171210

172-
public function testGetStatusFiltersWithData()
211+
/**
212+
* Verify status filter with data
213+
*
214+
* @return void
215+
*/
216+
public function testGetStatusFiltersWithData(): void
173217
{
174218
$result = [
175219
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED,
@@ -180,7 +224,12 @@ public function testGetStatusFiltersWithData()
180224
$this->assertEquals($result, $this->_model->getStatusFilters($this->product));
181225
}
182226

183-
public function testGetAssociatedProductIdsCached()
227+
/**
228+
* Verify AssociatedProducts Ids with cache
229+
*
230+
* @return void
231+
*/
232+
public function testGetAssociatedProductIdsCached(): void
184233
{
185234
$key = '_cache_instance_associated_product_ids';
186235
$cachedData = [300, 303, 306];
@@ -192,7 +241,12 @@ public function testGetAssociatedProductIdsCached()
192241
$this->assertEquals($cachedData, $this->_model->getAssociatedProductIds($this->product));
193242
}
194243

195-
public function testGetAssociatedProductIdsNonCached()
244+
/**
245+
* Verify AssociatedProducts Ids with no cached.
246+
*
247+
* @return void
248+
*/
249+
public function testGetAssociatedProductIdsNonCached(): void
196250
{
197251
$args = $this->objectHelper->getConstructArguments(
198252
\Magento\GroupedProduct\Model\Product\Type\Grouped::class,
@@ -236,7 +290,12 @@ public function testGetAssociatedProductIdsNonCached()
236290
$this->assertEquals($associatedIds, $model->getAssociatedProductIds($this->product));
237291
}
238292

239-
public function testGetAssociatedProductCollection()
293+
/**
294+
* Verify Associated Product collection
295+
*
296+
* @return void
297+
*/
298+
public function testGetAssociatedProductCollection(): void
240299
{
241300
$link = $this->createPartialMock(
242301
\Magento\Catalog\Model\Product\Link::class,
@@ -261,6 +320,8 @@ public function testGetAssociatedProductCollection()
261320
}
262321

263322
/**
323+
* Verify Proccess buy request
324+
*
264325
* @param array $superGroup
265326
* @param array $result
266327
* @dataProvider processBuyRequestDataProvider
@@ -274,9 +335,11 @@ public function testProcessBuyRequest($superGroup, $result)
274335
}
275336

276337
/**
338+
* dataProvider for buy request
339+
*
277340
* @return array
278341
*/
279-
public function processBuyRequestDataProvider()
342+
public function processBuyRequestDataProvider(): array
280343
{
281344
return [
282345
'positive' => [[1, 2, 3], ['super_group' => [1, 2, 3]]],
@@ -285,9 +348,12 @@ public function processBuyRequestDataProvider()
285348
}
286349

287350
/**
351+
* Get Children Msrp when children product with Msrp
352+
*
353+
* @return void
288354
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
289355
*/
290-
public function testGetChildrenMsrpWhenNoChildrenWithMsrp()
356+
public function testGetChildrenMsrpWhenNoChildrenWithMsrp(): void
291357
{
292358
$key = '_cache_instance_associated_products';
293359

@@ -298,7 +364,12 @@ public function testGetChildrenMsrpWhenNoChildrenWithMsrp()
298364
$this->assertEquals(0, $this->_model->getChildrenMsrp($this->product));
299365
}
300366

301-
public function testPrepareForCartAdvancedEmpty()
367+
/**
368+
* Prepare for card method with advanced empty
369+
*
370+
* @return void
371+
*/
372+
public function testPrepareForCartAdvancedEmpty(): void
302373
{
303374
$this->product = $this->createMock(\Magento\Catalog\Model\Product::class);
304375
$buyRequest = new \Magento\Framework\DataObject();
@@ -381,7 +452,12 @@ public function testPrepareForCartAdvancedEmpty()
381452
);
382453
}
383454

384-
public function testPrepareForCartAdvancedNoProductsStrictTrue()
455+
/**
456+
* Prepare for card with no products set strict option true
457+
*
458+
* @return void
459+
*/
460+
public function testPrepareForCartAdvancedNoProductsStrictTrue(): void
385461
{
386462
$buyRequest = new \Magento\Framework\DataObject();
387463
$buyRequest->setSuperGroup([0 => 0]);
@@ -404,7 +480,12 @@ public function testPrepareForCartAdvancedNoProductsStrictTrue()
404480
);
405481
}
406482

407-
public function testPrepareForCartAdvancedNoProductsStrictFalse()
483+
/**
484+
* Prepare for card with no products and set strict to false
485+
*
486+
* @return void
487+
*/
488+
public function testPrepareForCartAdvancedNoProductsStrictFalse(): void
408489
{
409490
$buyRequest = new \Magento\Framework\DataObject();
410491
$buyRequest->setSuperGroup([0 => 0]);
@@ -429,7 +510,12 @@ public function testPrepareForCartAdvancedNoProductsStrictFalse()
429510
);
430511
}
431512

432-
public function testPrepareForCartAdvancedWithProductsStrictFalseStringResult()
513+
/**
514+
* Verify Prepare for cart product with Product strict flase and string result
515+
*
516+
* @return false
517+
*/
518+
public function testPrepareForCartAdvancedWithProductsStrictFalseStringResult(): void
433519
{
434520
$associatedProduct = $this->createMock(\Magento\Catalog\Model\Product::class);
435521
$associatedId = 9384;
@@ -463,7 +549,12 @@ public function testPrepareForCartAdvancedWithProductsStrictFalseStringResult()
463549
);
464550
}
465551

466-
public function testPrepareForCartAdvancedWithProductsStrictFalseEmptyArrayResult()
552+
/**
553+
* Verify prepare for cart with strict option set to false and empty array
554+
*
555+
* @return void
556+
*/
557+
public function testPrepareForCartAdvancedWithProductsStrictFalseEmptyArrayResult(): void
467558
{
468559
$expectedMsg = "Cannot process the item.";
469560
$associatedProduct = $this->createMock(\Magento\Catalog\Model\Product::class);
@@ -498,7 +589,12 @@ public function testPrepareForCartAdvancedWithProductsStrictFalseEmptyArrayResul
498589
);
499590
}
500591

501-
public function testPrepareForCartAdvancedWithProductsStrictFalse()
592+
/**
593+
* Prepare for cart product with Product strict option st to false.
594+
*
595+
* @return void
596+
*/
597+
public function testPrepareForCartAdvancedWithProductsStrictFalse(): void
502598
{
503599
$associatedProduct = $this->createMock(\Magento\Catalog\Model\Product::class);
504600
$associatedId = 9384;
@@ -541,7 +637,12 @@ public function testPrepareForCartAdvancedWithProductsStrictFalse()
541637
);
542638
}
543639

544-
public function testPrepareForCartAdvancedWithProductsStrictTrue()
640+
/**
641+
* Verify prepare for cart with Product strict option true
642+
*
643+
* @return void
644+
*/
645+
public function testPrepareForCartAdvancedWithProductsStrictTrue(): void
545646
{
546647
$associatedProduct = $this->createMock(\Magento\Catalog\Model\Product::class);
547648
$associatedId = 9384;
@@ -587,15 +688,20 @@ public function testPrepareForCartAdvancedWithProductsStrictTrue()
587688
);
588689
}
589690

590-
public function testPrepareForCartAdvancedZeroQty()
691+
/**
692+
* Verify prepare for card with sold out option
693+
*
694+
* @return void
695+
*/
696+
public function testPrepareForCartAdvancedZeroQtyAndSoldOutOption(): void
591697
{
592698
$expectedMsg = "Please specify the quantity of product(s).";
593-
$associatedId = 9384;
699+
$associatedId = 91;
594700
$associatedProduct = $this->createMock(\Magento\Catalog\Model\Product::class);
595-
$associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($associatedId));
596-
701+
$associatedProduct->expects($this->atLeastOnce())->method('getId')->will($this->returnValue(90));
702+
$associatedProduct->expects($this->once())->method('isSalable')->willReturn(true);
597703
$buyRequest = new \Magento\Framework\DataObject();
598-
$buyRequest->setSuperGroup([$associatedId => 0]);
704+
$buyRequest->setSuperGroup([$associatedId => 90]);
599705

600706
$cached = true;
601707
$this->product
@@ -609,7 +715,12 @@ public function testPrepareForCartAdvancedZeroQty()
609715
$this->assertEquals($expectedMsg, $this->_model->prepareForCartAdvanced($buyRequest, $this->product));
610716
}
611717

612-
public function testFlushAssociatedProductsCache()
718+
/**
719+
* Verify flush cache for associated products
720+
*
721+
* @return void
722+
*/
723+
public function testFlushAssociatedProductsCache(): void
613724
{
614725
$productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['unsetData']);
615726
$productMock->expects($this->once())

0 commit comments

Comments
 (0)