Skip to content

Commit 5d278cf

Browse files
committed
ACP2E-1650:Create Shipment API
- fixed static issues - added unit tests
1 parent 779f089 commit 5d278cf

File tree

6 files changed

+217
-28
lines changed

6 files changed

+217
-28
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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\Bundle\Test\Unit\Model\Sales\Order;
9+
10+
use Magento\Bundle\Model\Sales\Order\BundleOrderTypeValidator;
11+
use Magento\Framework\Phrase;
12+
use Magento\Sales\Api\Data\OrderItemInterface;
13+
use Magento\Sales\Model\Order\Shipment;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
use Magento\Catalog\Model\Product\Type;
17+
18+
class BundleOrderTypeValidatorTest extends TestCase
19+
{
20+
/**
21+
* @return void
22+
*/
23+
public function testIsValidSuccess(): void
24+
{
25+
$bundleOrderItem = $this->getBundleOrderItemMock();
26+
$bundleOrderItem->expects($this->exactly(2))->method('getItemId')->willReturn(1);
27+
$bundleOrderItem->expects($this->once())->method('isDummy')->with(true)->willReturn(true);
28+
$bundleOrderItem->expects($this->once())->method('getHasChildren')->willReturn(false);
29+
$bundleOrderItem->expects($this->any())->method('getProductType')->willReturn(Type::TYPE_BUNDLE);
30+
$bundleOrderItem->expects($this->any())->method('getSku')->willReturn('bundleSKU');
31+
32+
$simpleProductOrderItem = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
33+
->disableOriginalConstructor()
34+
->addMethods(['getHasChildren'])
35+
->onlyMethods(['getItemId', 'isDummy', 'getProductType'])
36+
->getMock();
37+
$simpleProductOrderItem->expects($this->exactly(2))->method('getItemId')->willReturn(2);
38+
$simpleProductOrderItem->expects($this->once())->method('isDummy')->with(true)->willReturn(true);
39+
$simpleProductOrderItem->expects($this->once())->method('getHasChildren')->willReturn(false);
40+
$simpleProductOrderItem->expects($this->any())->method('getProductType')->willReturn(Type::TYPE_SIMPLE);
41+
42+
$order = $this->createMock(\Magento\Sales\Model\Order::class);
43+
$order->expects($this->once())
44+
->method('getAllItems')
45+
->willReturn([$bundleOrderItem, $simpleProductOrderItem]);
46+
47+
$bundleShipmentItem = $this->createMock(\Magento\Sales\Api\Data\ShipmentItemInterface::class);
48+
$bundleShipmentItem->expects($this->exactly(2))->method('getOrderItemId')->willReturn(1);
49+
$simpleProductShipmentItem = $this->createMock(\Magento\Sales\Api\Data\ShipmentItemInterface::class);
50+
$simpleProductShipmentItem->expects($this->exactly(2))->method('getOrderItemId')->willReturn(2);
51+
52+
$shipment = $this->createMock(Shipment::class);
53+
$shipment->expects($this->exactly(2))
54+
->method('getItems')
55+
->willReturn([$bundleShipmentItem, $simpleProductShipmentItem]);
56+
$shipment->expects($this->once())->method('getOrder')->willReturn($order);
57+
58+
try {
59+
$validator = new BundleOrderTypeValidator();
60+
$validator->isValid($shipment);
61+
$this->assertEmpty($validator->getMessages());
62+
} catch (\Exception $e) {
63+
$this->fail('Could not perform shipment validation. ' . $e->getMessage());
64+
}
65+
}
66+
67+
/**
68+
* @return void
69+
*/
70+
public function testIsValidFailSeparateShipmentType(): void
71+
{
72+
$bundleOrderItem = $this->getBundleOrderItemMock();
73+
$bundleOrderItem->expects($this->once())->method('getItemId')->willReturn(1);
74+
$bundleOrderItem->expects($this->once())->method('isDummy')->with(true)->willReturn(true);
75+
$bundleOrderItem->expects($this->once())->method('getHasChildren')->willReturn(true);
76+
$bundleOrderItem->expects($this->any())->method('getProductType')->willReturn(Type::TYPE_BUNDLE);
77+
$bundleOrderItem->expects($this->any())->method('getSku')->willReturn('bundleSKU');
78+
79+
$order = $this->createMock(\Magento\Sales\Model\Order::class);
80+
$order->expects($this->once())
81+
->method('getAllItems')
82+
->willReturn([$bundleOrderItem]);
83+
84+
$bundleShipmentItem = $this->createMock(\Magento\Sales\Api\Data\ShipmentItemInterface::class);
85+
$bundleShipmentItem->expects($this->once())->method('getOrderItemId')->willReturn(1);
86+
87+
$shipment = $this->createMock(Shipment::class);
88+
$shipment->expects($this->once())
89+
->method('getItems')
90+
->willReturn([$bundleShipmentItem]);
91+
$shipment->expects($this->once())->method('getOrder')->willReturn($order);
92+
93+
try {
94+
$validator = new BundleOrderTypeValidator();
95+
$validator->isValid($shipment);
96+
$messages = $validator->getMessages();
97+
$this->assertNotEmpty($messages);
98+
/** @var Phrase $validationMsg */
99+
$validationMsg = current($messages)[0];
100+
foreach ($validationMsg->getArguments() as $argument) {
101+
if (is_string($argument)) {
102+
$this->assertSame($argument, 'bundleSKU');
103+
} else {
104+
$this->assertTrue(in_array($argument->getText(), ['Separately', 'Bundle product options']));
105+
}
106+
}
107+
} catch (\Exception $e) {
108+
$this->fail('Could not perform shipment validation. ' . $e->getMessage());
109+
}
110+
}
111+
112+
/**
113+
* @return void
114+
*/
115+
public function testIsValidFailTogetherShipmentType(): void
116+
{
117+
$parentItem = $this->createMock(OrderItemInterface::class);
118+
$parentItem->expects($this->once())->method('getProductType')->willReturn(Type::TYPE_BUNDLE);
119+
$parentItem->expects($this->any())->method('getSku')->willReturn('bundleSKU');
120+
121+
$bundleOrderItem = $this->getBundleOrderItemMock();
122+
$bundleOrderItem->expects($this->once())->method('getItemId')->willReturn(1);
123+
$bundleOrderItem->expects($this->once())->method('isDummy')->with(true)->willReturn(true);
124+
$bundleOrderItem->expects($this->once())->method('getHasChildren')->willReturn(false);
125+
$bundleOrderItem->expects($this->any())->method('getProductType')->willReturn(Type::TYPE_BUNDLE);
126+
$bundleOrderItem->expects($this->exactly(3))->method('getParentItem')->willReturn($parentItem);
127+
128+
$order = $this->createMock(\Magento\Sales\Model\Order::class);
129+
$order->expects($this->once())
130+
->method('getAllItems')
131+
->willReturn([$bundleOrderItem]);
132+
133+
$bundleShipmentItem = $this->createMock(\Magento\Sales\Api\Data\ShipmentItemInterface::class);
134+
$bundleShipmentItem->expects($this->once())->method('getOrderItemId')->willReturn(1);
135+
136+
$shipment = $this->createMock(Shipment::class);
137+
$shipment->expects($this->once())
138+
->method('getItems')
139+
->willReturn([$bundleShipmentItem]);
140+
$shipment->expects($this->once())->method('getOrder')->willReturn($order);
141+
142+
try {
143+
$validator = new BundleOrderTypeValidator();
144+
$validator->isValid($shipment);
145+
$messages = $validator->getMessages();
146+
$this->assertNotEmpty($messages);
147+
/** @var Phrase $validationMsg */
148+
$validationMsg = current($messages)[0];
149+
foreach ($validationMsg->getArguments() as $argument) {
150+
if (is_string($argument)) {
151+
$this->assertSame($argument, 'bundleSKU');
152+
} else {
153+
$this->assertTrue(in_array($argument->getText(), ['Together', 'Bundle product itself']));
154+
}
155+
}
156+
} catch (\Exception $e) {
157+
$this->fail('Could not perform shipment validation. ' . $e->getMessage());
158+
}
159+
}
160+
161+
/**
162+
* @return MockObject
163+
*/
164+
private function getBundleOrderItemMock(): MockObject
165+
{
166+
return $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class)
167+
->disableOriginalConstructor()
168+
->addMethods(['getHasChildren'])
169+
->onlyMethods(['getItemId', 'isDummy', 'getProductType', 'getSku', 'getParentItem'])
170+
->getMock();
171+
}
172+
}

app/code/Magento/Sales/Model/Order/Shipment.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,26 @@
2828
*/
2929
class Shipment extends AbstractModel implements EntityInterface, ShipmentInterface
3030
{
31-
const STATUS_NEW = 1;
31+
public const STATUS_NEW = 1;
3232

33-
const REPORT_DATE_TYPE_ORDER_CREATED = 'order_created';
33+
public const REPORT_DATE_TYPE_ORDER_CREATED = 'order_created';
3434

35-
const REPORT_DATE_TYPE_SHIPMENT_CREATED = 'shipment_created';
35+
public const REPORT_DATE_TYPE_SHIPMENT_CREATED = 'shipment_created';
3636

3737
/**
3838
* Store address
3939
*/
40-
const XML_PATH_STORE_ADDRESS1 = 'shipping/origin/street_line1';
40+
public const XML_PATH_STORE_ADDRESS1 = 'shipping/origin/street_line1';
4141

42-
const XML_PATH_STORE_ADDRESS2 = 'shipping/origin/street_line2';
42+
public const XML_PATH_STORE_ADDRESS2 = 'shipping/origin/street_line2';
4343

44-
const XML_PATH_STORE_CITY = 'shipping/origin/city';
44+
public const XML_PATH_STORE_CITY = 'shipping/origin/city';
4545

46-
const XML_PATH_STORE_REGION_ID = 'shipping/origin/region_id';
46+
public const XML_PATH_STORE_REGION_ID = 'shipping/origin/region_id';
4747

48-
const XML_PATH_STORE_ZIP = 'shipping/origin/postcode';
48+
public const XML_PATH_STORE_ZIP = 'shipping/origin/postcode';
4949

50-
const XML_PATH_STORE_COUNTRY_ID = 'shipping/origin/country_id';
50+
public const XML_PATH_STORE_COUNTRY_ID = 'shipping/origin/country_id';
5151

5252
/**
5353
* Order entity type

app/code/Magento/Sales/Model/Order/ShipmentRepository.php

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class ShipmentRepository implements \Magento\Sales\Api\ShipmentRepositoryInterfa
4444
/**
4545
* @param Metadata $metadata
4646
* @param SearchResultFactory $searchResultFactory
47-
* @param CollectionProcessorInterface $collectionProcessor
47+
* @param CollectionProcessorInterface|null $collectionProcessor
4848
*/
4949
public function __construct(
5050
Metadata $metadata,
@@ -53,7 +53,9 @@ public function __construct(
5353
) {
5454
$this->metadata = $metadata;
5555
$this->searchResultFactory = $searchResultFactory;
56-
$this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor();
56+
$this->collectionProcessor = $collectionProcessor ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
57+
\Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class
58+
);
5759
}
5860

5961
/**
@@ -164,20 +166,4 @@ public function create()
164166
{
165167
return $this->metadata->getNewInstance();
166168
}
167-
168-
/**
169-
* Retrieve collection processor
170-
*
171-
* @deprecated 101.0.0
172-
* @return CollectionProcessorInterface
173-
*/
174-
private function getCollectionProcessor()
175-
{
176-
if (!$this->collectionProcessor) {
177-
$this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get(
178-
\Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class
179-
);
180-
}
181-
return $this->collectionProcessor;
182-
}
183169
}

app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentRepositoryTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\Exception\InputException;
1313
use Magento\Framework\Exception\NoSuchEntityException;
1414
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
15+
use Magento\Framework\Phrase;
1516
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1617
use Magento\Sales\Api\Data\ShipmentSearchResultInterfaceFactory;
1718
use Magento\Sales\Model\Order\Shipment;
@@ -264,6 +265,34 @@ public function testSaveWithException()
264265
$this->assertEquals($shipment, $this->subject->save($shipment));
265266
}
266267

268+
public function testSaveWithValidatorException()
269+
{
270+
$this->expectException('Magento\Framework\Exception\CouldNotSaveException');
271+
$shipment = $this->createPartialMock(Shipment::class, ['getEntityId']);
272+
$shipment->expects($this->never())
273+
->method('getEntityId');
274+
275+
$mapper = $this->getMockForAbstractClass(
276+
AbstractDb::class,
277+
[],
278+
'',
279+
false,
280+
true,
281+
true,
282+
['save']
283+
);
284+
$phraseMock = $this->createMock(Phrase::class);
285+
$mapper->expects($this->once())
286+
->method('save')
287+
->willThrowException(new \Magento\Framework\Validator\Exception());
288+
289+
$this->metadata->expects($this->any())
290+
->method('getMapper')
291+
->willReturn($mapper);
292+
293+
$this->assertEquals($shipment, $this->subject->save($shipment));
294+
}
295+
267296
public function testCreate()
268297
{
269298
$shipment = $this->createMock(Shipment::class);

lib/internal/Magento/Framework/Model/AbstractModel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,8 @@ protected function _createValidatorBeforeSave()
777777
}
778778

779779
/**
780+
* Create validator instance
781+
*
780782
* @return ValidatorChain
781783
*/
782784
private function getValidator(): ValidatorChain

lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ public function save(\Magento\Framework\Model\AbstractModel $object)
407407
$this->rollBack();
408408
$object->setHasDataChanges(true);
409409
throw new AlreadyExistsException(new Phrase('Unique constraint violation found'), $e);
410-
} catch (\Exception $e) {
410+
} catch (\Magento\Framework\Validator\Exception | \Exception $e) {
411411
$this->rollBack();
412412
$object->setHasDataChanges(true);
413413
throw $e;

0 commit comments

Comments
 (0)