Skip to content

Commit 06e9c78

Browse files
committed
Merge remote-tracking branch 'origin/MC-19519' into 2.2.10-develop-pr113
2 parents 54e96be + dd02241 commit 06e9c78

File tree

5 files changed

+273
-10
lines changed

5 files changed

+273
-10
lines changed

app/code/Magento/Shipping/Model/Shipping.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Shipping\Model;
78

89
use Magento\Framework\App\ObjectManager;
@@ -241,7 +242,7 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req
241242
}
242243

243244
/**
244-
* Collect rates of given carrier
245+
* Prepare carrier to find rates.
245246
*
246247
* @param string $carrierCode
247248
* @param \Magento\Quote\Model\Quote\Address\RateRequest $request
@@ -251,7 +252,9 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req
251252
*/
252253
public function collectCarrierRates($carrierCode, $request)
253254
{
254-
$carrier = $this->_carrierFactory->create($carrierCode, $request->getQuoteStoreId());
255+
$carrier = $this->isShippingCarrierAvailable($carrierCode)
256+
? $this->_carrierFactory->create($carrierCode, $request->getStoreId())
257+
: null;
255258
if (!$carrier) {
256259
return $this;
257260
}
@@ -321,6 +324,7 @@ public function collectCarrierRates($carrierCode, $request)
321324

322325
/**
323326
* Compose Packages For Carrier.
327+
*
324328
* Divides order into items and items into parts if it's necessary
325329
*
326330
* @param \Magento\Shipping\Model\Carrier\AbstractCarrier $carrier
@@ -333,6 +337,7 @@ public function composePackagesForCarrier($carrier, $request)
333337
{
334338
$allItems = $request->getAllItems();
335339
$fullItems = [];
340+
$weightItems = [];
336341

337342
$maxWeight = (double)$carrier->getConfigData('max_package_weight');
338343

@@ -403,22 +408,21 @@ public function composePackagesForCarrier($carrier, $request)
403408

404409
if (!empty($decimalItems)) {
405410
foreach ($decimalItems as $decimalItem) {
406-
$fullItems = array_merge(
407-
$fullItems,
408-
array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight'])
409-
);
411+
$weightItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']);
410412
}
411413
} else {
412-
$fullItems = array_merge($fullItems, array_fill(0, $qty, $itemWeight));
414+
$weightItems[] = array_fill(0, $qty, $itemWeight);
413415
}
414416
}
417+
$fullItems = array_merge($fullItems, ...$weightItems);
415418
sort($fullItems);
416419

417420
return $this->_makePieces($fullItems, $maxWeight);
418421
}
419422

420423
/**
421-
* Make pieces
424+
* Make pieces.
425+
*
422426
* Compose packages list based on given items, so that each package is as heavy as possible
423427
*
424428
* @param array $items
@@ -509,4 +513,18 @@ public function setCarrierAvailabilityConfigField($code = 'active')
509513
$this->_availabilityConfigField = $code;
510514
return $this;
511515
}
516+
517+
/**
518+
* Checks availability of carrier.
519+
*
520+
* @param string $carrierCode
521+
* @return bool
522+
*/
523+
private function isShippingCarrierAvailable(string $carrierCode): bool
524+
{
525+
return $this->_scopeConfig->isSetFlag(
526+
'carriers/' . $carrierCode . '/' . $this->_availabilityConfigField,
527+
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
528+
);
529+
}
512530
}

app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Shipping\Test\Unit\Model;
78

89
use Magento\Catalog\Model\Product;
910
use Magento\Catalog\Model\Product\Type as ProductType;
1011
use Magento\CatalogInventory\Model\Stock\Item as StockItem;
1112
use Magento\CatalogInventory\Model\StockRegistry;
13+
use Magento\Framework\App\Config\ScopeConfigInterface;
1214
use Magento\Quote\Model\Quote\Item as QuoteItem;
1315
use Magento\Shipping\Model\Carrier\AbstractCarrier;
1416
use Magento\Shipping\Model\Carrier\AbstractCarrierInterface;
@@ -20,10 +22,15 @@
2022
use Magento\Store\Model\Store;
2123
use PHPUnit_Framework_MockObject_MockObject as MockObject;
2224

25+
/**
26+
* Unit tests for \Magento\Shipping\Model\Shipping class.
27+
*
28+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29+
*/
2330
class ShippingTest extends \PHPUnit\Framework\TestCase
2431
{
2532
/**
26-
* Test identification number of product
33+
* Test identification number of product.
2734
*
2835
* @var int
2936
*/
@@ -49,22 +56,34 @@ class ShippingTest extends \PHPUnit\Framework\TestCase
4956
*/
5057
private $carrier;
5158

59+
/**
60+
* @var ScopeConfigInterface|MockObject
61+
*/
62+
private $scopeConfig;
63+
64+
/**
65+
* @inheritdoc
66+
*/
5267
protected function setUp()
5368
{
5469
$this->stockRegistry = $this->createMock(StockRegistry::class);
5570
$this->stockItemData = $this->createMock(StockItem::class);
71+
$this->scopeConfig = $this->createMock(ScopeConfigInterface::class);
5672

5773
$this->shipping = (new ObjectManagerHelper($this))->getObject(
5874
Shipping::class,
5975
[
6076
'stockRegistry' => $this->stockRegistry,
6177
'carrierFactory' => $this->getCarrierFactory(),
78+
'scopeConfig' => $this->scopeConfig,
6279
]
6380
);
6481
}
6582

6683
/**
84+
* Compose Packages For Carrier.
6785
*
86+
* @return void
6887
*/
6988
public function testComposePackages()
7089
{
@@ -122,14 +141,25 @@ public function testComposePackages()
122141

123142
/**
124143
* Active flag should be set before collecting carrier rates.
144+
*
145+
* @return void
125146
*/
126147
public function testCollectCarrierRatesSetActiveFlag()
127148
{
149+
$carrierCode = 'carrier';
150+
$scopeStore = 'store';
151+
$this->scopeConfig->expects($this->once())
152+
->method('isSetFlag')
153+
->with(
154+
'carriers/' . $carrierCode . '/active',
155+
$scopeStore
156+
)
157+
->willReturn(true);
128158
$this->carrier->expects($this->atLeastOnce())
129159
->method('setActiveFlag')
130160
->with('active');
131161

132-
$this->shipping->collectCarrierRates('carrier', new RateRequest());
162+
$this->shipping->collectCarrierRates($carrierCode, new RateRequest());
133163
}
134164

135165
/**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\OfflineShipping\Model;
9+
10+
/**
11+
* Integration tests for offline shipping carriers.
12+
* @magentoAppIsolation enabled
13+
*/
14+
class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesAbstract
15+
{
16+
/**
17+
* @var string
18+
*/
19+
protected $carrier = 'flatrate';
20+
21+
/**
22+
* @var string
23+
*/
24+
protected $errorMessage = 'This shipping method is not available. To use this shipping method, please contact us.';
25+
26+
/**
27+
* @magentoConfigFixture default_store carriers/flatrate/active 1
28+
* @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1
29+
* @magentoConfigFixture default_store carriers/flatrate/specificcountry UK
30+
* @magentoConfigFixture default_store carriers/flatrate/showmethod 1
31+
*/
32+
public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable()
33+
{
34+
parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable();
35+
}
36+
37+
/**
38+
* @magentoConfigFixture default_store carriers/flatrate/active 0
39+
* @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1
40+
* @magentoConfigFixture default_store carriers/flatrate/specificcountry UK
41+
* @magentoConfigFixture default_store carriers/flatrate/showmethod 1
42+
*/
43+
public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable()
44+
{
45+
parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable();
46+
}
47+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Shipping\Model;
9+
10+
use Magento\Framework\DataObject;
11+
use Magento\Framework\ObjectManagerInterface;
12+
use Magento\Quote\Model\Quote\Address\RateResult\Error;
13+
use Magento\Quote\Model\Quote\Address\RateResult\Method;
14+
use Magento\Shipping\Model\Rate\Result;
15+
use Magento\TestFramework\Helper\Bootstrap;
16+
17+
/**
18+
* Abstract class for testing shipping carriers.
19+
*/
20+
abstract class CollectRatesAbstract extends \PHPUnit\Framework\TestCase
21+
{
22+
/**
23+
* @var ObjectManagerInterface
24+
*/
25+
private $objectManager;
26+
27+
/**
28+
* @var Shipping
29+
*/
30+
protected $shipping;
31+
32+
/**
33+
* @var string
34+
*/
35+
protected $carrier = '';
36+
37+
/**
38+
* @var string
39+
*/
40+
protected $errorMessage = '';
41+
42+
/**
43+
* @inheritdoc
44+
*/
45+
protected function setUp()
46+
{
47+
$this->objectManager = Bootstrap::getObjectManager();
48+
$this->shipping = $this->objectManager->get(Shipping::class);
49+
}
50+
51+
/**
52+
* Tests that an error message is displayed when the shipping method is enabled and not applicable.
53+
*
54+
* @return void
55+
*/
56+
public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable()
57+
{
58+
$result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier);
59+
$rate = $this->getRate($result->getResult());
60+
61+
static::assertEquals($this->carrier, $rate->getData('carrier'));
62+
static::assertEquals($this->errorMessage, $rate->getData('error_message'));
63+
}
64+
65+
/**
66+
* Tests that shipping rates don't return when the shipping method is disabled and not applicable.
67+
*
68+
* @return void
69+
*/
70+
public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable()
71+
{
72+
$result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier);
73+
$rate = $this->getRate($result->getResult());
74+
75+
static::assertNull($rate);
76+
}
77+
78+
/**
79+
* Returns customer address.
80+
*
81+
* @return DataObject
82+
*/
83+
private function getAddress(): DataObject
84+
{
85+
$address = $this->objectManager->create(
86+
DataObject::class,
87+
[
88+
'data' => [
89+
'region_id' => 'CA',
90+
'postcode' => '11111',
91+
'lastname' => 'John',
92+
'firstname' => 'Doe',
93+
'street' => 'Some street',
94+
'city' => 'Los Angeles',
95+
'email' => 'john.doe@example.com',
96+
'telephone' => '11111111',
97+
'country_id' => 'US',
98+
'item_qty' => 1,
99+
],
100+
]
101+
);
102+
103+
return $address;
104+
}
105+
106+
/**
107+
* Returns shipping rate by the result.
108+
*
109+
* @param Result $result
110+
* @return Method|Error
111+
*/
112+
private function getRate(Result $result)
113+
{
114+
$rates = $result->getAllRates();
115+
116+
return array_pop($rates);
117+
}
118+
}

0 commit comments

Comments
 (0)