Skip to content

Commit e19fad5

Browse files
committed
Merge remote-tracking branch 'origin/AC-14690' into spartans_pr_10112025
2 parents ae83efa + aa47a06 commit e19fad5

File tree

3 files changed

+226
-0
lines changed

3 files changed

+226
-0
lines changed

app/code/Magento/Sales/Model/AdminOrder/Create.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,11 @@ public function getQuote()
545545
{
546546
if (!$this->_quote) {
547547
$this->_quote = $this->getSession()->getQuote();
548+
$customerId = (int) $this->_quote->getCustomerId();
549+
if ($customerId > 0) {
550+
$customerData = $this->customerRepository->getById($customerId);
551+
$this->_quote->updateCustomerData($customerData);
552+
}
548553
}
549554

550555
return $this->_quote;

app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Magento\Sales\Model\ResourceModel\Order\Item\Collection as ItemCollection;
3535
use Magento\Store\Api\Data\StoreInterface;
3636
use PHPUnit\Framework\MockObject\MockObject;
37+
use Magento\Customer\Api\CustomerRepositoryInterface;
3738
use PHPUnit\Framework\TestCase;
3839

3940
/**
@@ -638,4 +639,95 @@ public static function setShippingAsBillingDataProvider(): array
638639
]
639640
];
640641
}
642+
643+
public function testGetQuoteAssignsCustomerWhenCustomerIdPresent(): void
644+
{
645+
$quote = $this->getMockBuilder(Quote::class)
646+
->disableOriginalConstructor()
647+
->onlyMethods(['updateCustomerData'])
648+
->addMethods(['getCustomerId'])
649+
->getMock();
650+
651+
$quote->expects($this->once())
652+
->method('getCustomerId')
653+
->willReturn(self::CUSTOMER_ID);
654+
655+
$customerData = $this->getMockBuilder(CustomerInterface::class)
656+
->getMockForAbstractClass();
657+
658+
$customerRepository = $this->getMockBuilder(CustomerRepositoryInterface::class)
659+
->getMockForAbstractClass();
660+
$customerRepository->expects($this->once())
661+
->method('getById')
662+
->with(self::CUSTOMER_ID)
663+
->willReturn($customerData);
664+
665+
$quote->expects($this->once())
666+
->method('updateCustomerData')
667+
->with($customerData);
668+
669+
$this->sessionQuote->expects($this->once())
670+
->method('getQuote')
671+
->willReturn($quote);
672+
673+
$subject = $this->createAdminOrderCreateWithCustomerRepository($customerRepository);
674+
675+
$result = $subject->getQuote();
676+
677+
$this->assertSame($quote, $result);
678+
}
679+
680+
public function testGetQuoteSkipsAssignWhenNoCustomerId(): void
681+
{
682+
$quote = $this->getMockBuilder(Quote::class)
683+
->disableOriginalConstructor()
684+
->onlyMethods(['updateCustomerData'])
685+
->addMethods(['getCustomerId'])
686+
->getMock();
687+
688+
$quote->expects($this->once())
689+
->method('getCustomerId')
690+
->willReturn(0);
691+
692+
$quote->expects($this->never())
693+
->method('updateCustomerData');
694+
695+
$customerRepository = $this->getMockBuilder(CustomerRepositoryInterface::class)
696+
->getMockForAbstractClass();
697+
$customerRepository->expects($this->never())
698+
->method('getById');
699+
700+
$this->sessionQuote->expects($this->once())
701+
->method('getQuote')
702+
->willReturn($quote);
703+
704+
$subject = $this->createAdminOrderCreateWithCustomerRepository($customerRepository);
705+
706+
$result = $subject->getQuote();
707+
708+
$this->assertSame($quote, $result);
709+
}
710+
711+
private function createAdminOrderCreateWithCustomerRepository(
712+
CustomerRepositoryInterface $customerRepository
713+
): Create {
714+
$objectManagerHelper = new ObjectManagerHelper($this);
715+
return $objectManagerHelper->getObject(
716+
Create::class,
717+
[
718+
'_objectManager' => $this->objectManager,
719+
'messageManager' => $this->messageManager,
720+
'quoteSession' => $this->sessionQuote,
721+
'metadataFormFactory' => $this->formFactory,
722+
'customerFactory' => $this->customerFactory,
723+
'groupRepository' => $this->groupRepository,
724+
'quoteItemUpdater' => $this->itemUpdater,
725+
'customerMapper' => $this->customerMapper,
726+
'dataObjectHelper' => $this->dataObjectHelper,
727+
'quoteRepository' => $this->quoteRepository,
728+
'quoteFactory' => $this->quoteFactory,
729+
'customerRepository' => $customerRepository,
730+
]
731+
);
732+
}
641733
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Sales\Model\AdminOrder;
9+
10+
use Magento\Backend\Model\Session\Quote as AdminQuoteSession;
11+
use Magento\Customer\Api\CustomerRepositoryInterface;
12+
use Magento\Customer\Test\Fixture\Customer as CustomerFixture;
13+
use Magento\Quote\Api\CartRepositoryInterface;
14+
use Magento\Quote\Model\QuoteFactory;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\TestFramework\Fixture\DataFixtureStorage;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
use Magento\TestFramework\Fixture\DataFixture;
19+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
20+
use PHPUnit\Framework\TestCase;
21+
22+
class CreateGetQuoteAssignCustomerTest extends TestCase
23+
{
24+
/**
25+
* @var DataFixtureStorage
26+
*/
27+
private $fixtures;
28+
29+
/**
30+
* @var \Magento\Framework\ObjectManagerInterface
31+
*/
32+
private $objectManager;
33+
34+
/**
35+
* @inheritdoc
36+
*/
37+
protected function setUp(): void
38+
{
39+
parent::setUp();
40+
$this->objectManager = Bootstrap::getObjectManager();
41+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
42+
}
43+
44+
/**
45+
* Ensures Create::getQuote() assigns fresh CustomerInterface to the quote
46+
* when a customerId is present on the quote.
47+
*
48+
* @magentoAppArea adminhtml
49+
* @magentoDbIsolation enabled
50+
*/
51+
#[
52+
DataFixture(CustomerFixture::class, as: 'customer')
53+
]
54+
public function testGetQuoteAssignsFreshCustomerDataWhenCustomerIdPresent(): void
55+
{
56+
/** @var StoreManagerInterface $storeManager */
57+
$storeManager = $this->objectManager->get(StoreManagerInterface::class);
58+
$storeId = (int)$storeManager->getStore()->getId();
59+
60+
/** @var CustomerRepositoryInterface $customerRepo */
61+
$customerRepo = $this->objectManager->get(CustomerRepositoryInterface::class);
62+
63+
/** @var \Magento\Customer\Api\Data\CustomerInterface $customer */
64+
$customer = $this->fixtures->get('customer');
65+
$customer = $customerRepo->getById((int)$customer->getId()); // ensure latest
66+
67+
/** @var QuoteFactory $quoteFactory */
68+
$quoteFactory = $this->objectManager->get(QuoteFactory::class);
69+
/** @var CartRepositoryInterface $quoteRepo */
70+
$quoteRepo = $this->objectManager->get(CartRepositoryInterface::class);
71+
/** @var AdminQuoteSession $session */
72+
$session = $this->objectManager->get(AdminQuoteSession::class);
73+
74+
// Create a quote with stale customer-related fields
75+
$quote = $quoteFactory->create();
76+
$quote->setStoreId($storeId);
77+
$quote->setCustomerId((int)$customer->getId());
78+
$quote->setCustomerEmail('[email protected]');
79+
$quoteRepo->save($quote);
80+
81+
$session->setQuoteId((int)$quote->getId());
82+
83+
/** @var Create $create */
84+
$create = $this->objectManager->create(Create::class);
85+
86+
$result = $create->getQuote();
87+
88+
// Assert quote was refreshed from repository via assignCustomer()
89+
$this->assertSame((int)$customer->getId(), (int)$result->getCustomerId());
90+
$this->assertSame($customer->getEmail(), $result->getCustomerEmail());
91+
}
92+
93+
/**
94+
* Ensures Create::getQuote() does not assign a customer when no customerId is present.
95+
*
96+
* @magentoAppArea adminhtml
97+
* @magentoAppIsolation enabled
98+
* @magentoDbIsolation enabled
99+
*/
100+
public function testGetQuoteDoesNotAssignWhenNoCustomerId(): void
101+
{
102+
$session = $this->objectManager->get(\Magento\Backend\Model\Session\Quote::class);
103+
$session->unsQuoteId();
104+
$session->unsCustomerId();
105+
106+
$storeManager = $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class);
107+
$storeId = (int)$storeManager->getStore()->getId();
108+
109+
$quoteFactory = $this->objectManager->get(\Magento\Quote\Model\QuoteFactory::class);
110+
111+
// Create a quote without a customer
112+
$quote = $quoteFactory->create();
113+
$quote->setStoreId($storeId);
114+
$quote->setCustomerId(null);
115+
$quote->setCustomerEmail('[email protected]');
116+
117+
/** @var \Magento\Sales\Model\AdminOrder\Create $create */
118+
$create = $this->objectManager->create(\Magento\Sales\Model\AdminOrder\Create::class);
119+
120+
// Bypass session state by injecting the quote directly
121+
$create->setQuote($quote);
122+
123+
$result = $create->getQuote();
124+
125+
$this->assertSame($quote, $result);
126+
$this->assertEmpty($result->getCustomerId());
127+
$this->assertSame('[email protected]', $result->getCustomerEmail());
128+
}
129+
}

0 commit comments

Comments
 (0)