Skip to content

Commit a07aabd

Browse files
committed
ACP2E-3986: After applying ACP2E-3841, free shipping isn't always applied properly for multi address checkout
- added unit test
1 parent 242500b commit a07aabd

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ public function validate(AbstractModel $model)
168168
$subSelectConditionsFlag = $this->validateSubSelectConditions($item);
169169
}
170170
$total = $this->getBaseRowTotalForChildrenProduct($item, $attr, $total);
171-
if ($subSelectConditionsFlag && $this->validateAttribute($total)) return true;
171+
if ($subSelectConditionsFlag && $this->validateAttribute($total)) {
172+
return true;
173+
}
172174
}
173175
return $subSelectConditionsFlag && $this->validateAttribute($total);
174176
}

app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/Product/SubselectTest.php

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,160 @@ public function testValidateForFixedBundleProduct(
197197
$this->assertEquals($expectedResult, $this->model->validate($this->abstractModel));
198198
}
199199

200+
/**
201+
* Tests validate for fixed bundle product
202+
*
203+
* @param array|null $attributeDetails
204+
* @param array $productDetails
205+
* @param bool $isMultiShipping
206+
* @param bool $expectedResult
207+
* @return void
208+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
209+
* @dataProvider dataProviderForBundleAndSimpleProducts
210+
*/
211+
public function testValidateForBundleAndSimpleProducts(
212+
array $attributeDetails,
213+
array $productsDetails,
214+
bool $isMultiShipping,
215+
bool $expectedResult
216+
): void {
217+
$attributeResource = new DataObject();
218+
$childrenQuoteItemsMock = [];
219+
foreach ($productsDetails as $productDetails) {
220+
$attributeResource->setAttribute($attributeDetails['id']);
221+
$this->ruleConditionMock->expects($this->any())
222+
->method('setName')
223+
->willReturn($attributeDetails['name']);
224+
$this->ruleConditionMock->expects($this->any())
225+
->method('setAttributeScope')
226+
->willReturn($attributeDetails['attributeScope']);
227+
$this->ruleConditionMock->expects($this->any())
228+
->method('getAttribute')
229+
->willReturn($attributeDetails['id']);
230+
$this->model->setData('conditions', [$this->ruleConditionMock]);
231+
$this->model->setData('attribute', $attributeDetails['id']);
232+
$this->model->setData('value', $productDetails['valueParsed']);
233+
$this->model->setData('operator', $attributeDetails['attributeOperator']);
234+
$this->productMock->expects($this->any())
235+
->method('hasData')
236+
->with($attributeDetails['id'])
237+
->willReturn(!empty($productDetails));
238+
$this->productMock->expects($this->any())
239+
->method('getData')
240+
->with($attributeDetails['id'])
241+
->willReturn($productDetails['price']);
242+
$this->ruleConditionMock->expects($this->any())
243+
->method('getValueParsed')
244+
->willReturn($productDetails['valueParsed']);
245+
$this->ruleConditionMock->expects($this->any())->method('getOperatorForValidate')
246+
->willReturn($attributeDetails['attributeOperator']);
247+
248+
$this->quoteMock->expects($this->any())
249+
->method('getIsMultiShipping')
250+
->willReturn($isMultiShipping);
251+
$this->quoteItemMock->expects($this->any())
252+
->method('getProductType')
253+
->willReturn($productDetails['type']);
254+
255+
/* @var AbstractItem|MockObject $quoteItemMock */
256+
$childQuoteItemMock = $this->getMockBuilder(AbstractItem::class)
257+
->onlyMethods(['getProduct', 'getData', 'getPrice', 'getQty'])
258+
->addMethods(['getBaseRowTotal'])
259+
->disableOriginalConstructor()
260+
->getMockForAbstractClass();
261+
$childQuoteItemMock->expects($this->any())
262+
->method('getProduct')
263+
->willReturn($this->productMock);
264+
$childQuoteItemMock->expects($this->any())
265+
->method('getQty')
266+
->willReturn($productDetails['qty']);
267+
$childQuoteItemMock->expects($this->any())
268+
->method('getPrice')
269+
->willReturn($productDetails['price']);
270+
$childQuoteItemMock->expects($this->any())
271+
->method('getBaseRowTotal')
272+
->willReturn($productDetails['baseRowTotal']);
273+
$this->productMock->expects($this->any())
274+
->method('getResource')
275+
->willReturn($attributeResource);
276+
$this->quoteItemMock->expects($this->any())
277+
->method('getProduct')
278+
->willReturn($this->productMock);
279+
$this->quoteItemMock->expects($this->any())
280+
->method('getHasChildren')
281+
->willReturn($productDetails['hasChildren']);
282+
$this->quoteItemMock->expects($this->any())
283+
->method('getChildren')
284+
->willReturn([$childQuoteItemMock]);
285+
$this->quoteItemMock->expects($this->any())
286+
->method('getProductId')
287+
->willReturn($productDetails['id']);
288+
$this->quoteItemMock->expects($this->any())
289+
->method('getChildren')
290+
->willReturn([$childQuoteItemMock]);
291+
$this->quoteItemMock->expects($this->any())
292+
->method('getData')
293+
->willReturn($productDetails['baseRowTotal']);
294+
$childrenQuoteItemsMock[] = clone $this->quoteItemMock;
295+
}
296+
297+
$abstractModel = $this->getMockBuilder(AbstractModel::class)
298+
->disableOriginalConstructor()
299+
->addMethods(['getQuote', 'getAllItems', 'getProduct'])
300+
->getMockForAbstractClass();
301+
$abstractModel->expects($this->any())
302+
->method('getQuote')
303+
->willReturn($this->quoteMock);
304+
$abstractModel->expects($this->any())
305+
->method('getAllItems')
306+
->willReturn($childrenQuoteItemsMock);
307+
$this->assertEquals($expectedResult, $this->model->validate($abstractModel));
308+
}
309+
310+
/**
311+
* Get data provider array for validate bundle and simple products
312+
*
313+
* @return array
314+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
315+
*/
316+
public static function dataProviderForBundleAndSimpleProducts(): array
317+
{
318+
return [
319+
'validate true for multiple products with conditions
320+
for attribute base_row_total with multi shipping' =>
321+
[
322+
[
323+
'id' => 'attribute_set_id',
324+
'name' => 'test conditions',
325+
'attributeScope' => 'frontend',
326+
'attributeOperator' => '=='
327+
],
328+
[
329+
[
330+
'id'=> 1,
331+
'type' => ProductType::TYPE_SIMPLE,
332+
'qty' => 1,
333+
'price' => 100,
334+
'hasChildren' => false ,
335+
'baseRowTotal' => 100,
336+
'valueParsed' => 100
337+
],
338+
[
339+
'id'=> 1,
340+
'type' => ProductType::TYPE_BUNDLE,
341+
'qty' => 1,
342+
'price' => 100,
343+
'hasChildren' => true,
344+
'baseRowTotal' => 100,
345+
'valueParsed' => 100
346+
],
347+
],
348+
true,
349+
true
350+
],
351+
];
352+
}
353+
200354
/**
201355
* Get data provider array for validate bundle product
202356
*

0 commit comments

Comments
 (0)