Skip to content

Commit d3b2ef0

Browse files
authored
Merge pull request #732 from magento-gl/aegis_spartans_pr_01042026
[Aegis Spartans] BugFixes Delivery
2 parents 3bd09c3 + 6a5bf6e commit d3b2ef0

2 files changed

Lines changed: 130 additions & 1 deletion

File tree

InventorySales/Plugin/Quote/CartManagementPlugin.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ public function aroundPlaceOrder(
9999
return $proceed($cartId, $paymentMethod);
100100
}
101101

102-
$quote = $this->cartRepository->getActive($cartId);
102+
try {
103+
$quote = $this->cartRepository->getActive($cartId);
104+
} catch (NoSuchEntityException $exception) {
105+
// Async order processing can work with an inactive quote after checkout message submission.
106+
$quote = $this->cartRepository->get($cartId);
107+
}
103108
$websiteId = (int)$this->storeManager->getStore($quote->getStoreId())->getWebsiteId();
104109
$stockId = (int)$this->stockByWebsiteIdResolver->execute($websiteId)->getStockId();
105110

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
/**
3+
* Copyright 2026 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\InventorySales\Test\Unit\Plugin\Quote;
9+
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\InventoryApi\Api\Data\StockInterface;
12+
use Magento\InventoryCatalogApi\Model\GetSkusByProductIdsInterface;
13+
use Magento\InventorySales\Model\ReservationExecutionInterface;
14+
use Magento\InventorySales\Model\ResourceModel\AcquireInventoryLock;
15+
use Magento\InventorySales\Plugin\Quote\CartManagementPlugin;
16+
use Magento\InventorySalesApi\Model\StockByWebsiteIdResolverInterface;
17+
use Magento\Quote\Api\CartManagementInterface;
18+
use Magento\Quote\Api\CartRepositoryInterface;
19+
use Magento\Quote\Model\Quote;
20+
use Magento\Store\Api\Data\StoreInterface;
21+
use Magento\Store\Model\StoreManagerInterface;
22+
use PHPUnit\Framework\MockObject\MockObject;
23+
use PHPUnit\Framework\TestCase;
24+
25+
class CartManagementPluginTest extends TestCase
26+
{
27+
/**
28+
* @var CartRepositoryInterface|MockObject
29+
*/
30+
private $cartRepository;
31+
32+
/**
33+
* @var GetSkusByProductIdsInterface|MockObject
34+
*/
35+
private $getSkusByProductIds;
36+
37+
/**
38+
* @var AcquireInventoryLock|MockObject
39+
*/
40+
private $acquireInventoryLock;
41+
42+
/**
43+
* @var StockByWebsiteIdResolverInterface|MockObject
44+
*/
45+
private $stockByWebsiteIdResolver;
46+
47+
/**
48+
* @var StoreManagerInterface|MockObject
49+
*/
50+
private $storeManager;
51+
52+
/**
53+
* @var ReservationExecutionInterface|MockObject
54+
*/
55+
private $reservationExecution;
56+
57+
/**
58+
* @var CartManagementPlugin
59+
*/
60+
private $plugin;
61+
62+
protected function setUp(): void
63+
{
64+
$this->cartRepository = $this->createMock(CartRepositoryInterface::class);
65+
$this->getSkusByProductIds = $this->createMock(GetSkusByProductIdsInterface::class);
66+
$this->acquireInventoryLock = $this->createMock(AcquireInventoryLock::class);
67+
$this->stockByWebsiteIdResolver = $this->createMock(StockByWebsiteIdResolverInterface::class);
68+
$this->storeManager = $this->createMock(StoreManagerInterface::class);
69+
$this->reservationExecution = $this->createMock(ReservationExecutionInterface::class);
70+
71+
$this->plugin = new CartManagementPlugin(
72+
$this->cartRepository,
73+
$this->getSkusByProductIds,
74+
$this->acquireInventoryLock,
75+
$this->stockByWebsiteIdResolver,
76+
$this->storeManager,
77+
$this->reservationExecution
78+
);
79+
}
80+
81+
public function testAroundPlaceOrderFallsBackToGetForInactiveQuote(): void
82+
{
83+
$cartId = 36;
84+
$expectedOrderId = 1001;
85+
86+
$subject = $this->createMock(CartManagementInterface::class);
87+
88+
$quote = $this->createMock(Quote::class);
89+
$quote->method('getStoreId')->willReturn(1);
90+
$item = new class {
91+
public function getProductId(): int
92+
{
93+
return 42;
94+
}
95+
};
96+
$quote->method('getAllVisibleItems')->willReturn([$item]);
97+
98+
$store = $this->createConfiguredMock(StoreInterface::class, ['getWebsiteId' => 2]);
99+
$stock = $this->createConfiguredMock(StockInterface::class, ['getStockId' => 3]);
100+
101+
$this->reservationExecution->method('isDeferred')->willReturn(true);
102+
$this->cartRepository->expects($this->once())
103+
->method('getActive')
104+
->with($cartId)
105+
->willThrowException(NoSuchEntityException::singleField('cartId', $cartId));
106+
$this->cartRepository->expects($this->once())
107+
->method('get')
108+
->with($cartId)
109+
->willReturn($quote);
110+
$this->storeManager->method('getStore')->with(1)->willReturn($store);
111+
$this->stockByWebsiteIdResolver->method('execute')->with(2)->willReturn($stock);
112+
$this->getSkusByProductIds->method('execute')->with([42])->willReturn(['simple-1']);
113+
$this->acquireInventoryLock->method('execute')->with('simple-1', 3)->willReturn(true);
114+
$this->acquireInventoryLock->expects($this->once())->method('release')->with('simple-1', 3);
115+
116+
$proceed = function (int $receivedCartId) use ($cartId, $expectedOrderId): int {
117+
$this->assertSame($cartId, $receivedCartId);
118+
return $expectedOrderId;
119+
};
120+
121+
$result = $this->plugin->aroundPlaceOrder($subject, $proceed, $cartId);
122+
$this->assertSame($expectedOrderId, $result);
123+
}
124+
}

0 commit comments

Comments
 (0)