Skip to content

Commit f529c59

Browse files
committed
MC-37351: Cart contents lost after switching to different store with different domain
- Add unit tests
1 parent 55975d2 commit f529c59

File tree

14 files changed

+1101
-21
lines changed

14 files changed

+1101
-21
lines changed

app/code/Magento/Checkout/Model/StoreSwitcher/RedirectDataPreprocessor.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
use Magento\Checkout\Model\Session as CheckoutSession;
1111
use Magento\Customer\Model\Session as CustomerSession;
12-
use Magento\Quote\Api\CartRepositoryInterface;
1312
use Magento\Store\Model\StoreSwitcher\ContextInterface;
1413
use Magento\Store\Model\StoreSwitcher\RedirectDataPreprocessorInterface;
1514

@@ -20,11 +19,6 @@
2019
*/
2120
class RedirectDataPreprocessor implements RedirectDataPreprocessorInterface
2221
{
23-
/**
24-
* @var CartRepositoryInterface
25-
*/
26-
private $quoteRepository;
27-
2822
/**
2923
* @var CustomerSession
3024
*/
@@ -36,16 +30,13 @@ class RedirectDataPreprocessor implements RedirectDataPreprocessorInterface
3630
private $checkoutSession;
3731

3832
/**
39-
* @param CartRepositoryInterface $quoteRepository
4033
* @param CustomerSession $customerSession
4134
* @param CheckoutSession $checkoutSession
4235
*/
4336
public function __construct(
44-
CartRepositoryInterface $quoteRepository,
4537
CustomerSession $customerSession,
4638
CheckoutSession $checkoutSession
4739
) {
48-
$this->quoteRepository = $quoteRepository;
4940
$this->customerSession = $customerSession;
5041
$this->checkoutSession = $checkoutSession;
5142
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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\Checkout\Test\Unit\Model\StoreSwitcher;
9+
10+
use Magento\Checkout\Model\Session as CheckoutSession;
11+
use Magento\Checkout\Model\StoreSwitcher\RedirectDataPostprocessor;
12+
use Magento\Customer\Model\Session as CustomerSession;
13+
use Magento\Quote\Api\CartRepositoryInterface;
14+
use Magento\Quote\Model\Quote;
15+
use Magento\Store\Api\Data\StoreInterface;
16+
use Magento\Store\Model\StoreSwitcher\ContextInterface;
17+
use PHPUnit\Framework\MockObject\MockObject;
18+
use PHPUnit\Framework\TestCase;
19+
use Psr\Log\LoggerInterface;
20+
21+
class RedirectDataPostprocessorTest extends TestCase
22+
{
23+
/**
24+
* @var CartRepositoryInterface
25+
*/
26+
private $quoteRepository;
27+
28+
/**
29+
* @var CustomerSession
30+
*/
31+
private $customerSession;
32+
33+
/**
34+
* @var CheckoutSession
35+
*/
36+
private $checkoutSession;
37+
/**
38+
* @var ContextInterface|MockObject
39+
*/
40+
private $context;
41+
/**
42+
* @var RedirectDataPostprocessor
43+
*/
44+
private $model;
45+
46+
/**
47+
* @inheritDoc
48+
*/
49+
protected function setUp(): void
50+
{
51+
parent::setUp();
52+
53+
$this->quoteRepository = $this->createMock(CartRepositoryInterface::class);
54+
$this->customerSession = $this->createMock(CustomerSession::class);
55+
$this->checkoutSession = $this->createMock(CheckoutSession::class);
56+
$logger = $this->createMock(LoggerInterface::class);
57+
$this->model = new RedirectDataPostprocessor(
58+
$this->quoteRepository,
59+
$this->customerSession,
60+
$this->checkoutSession,
61+
$logger
62+
);
63+
64+
$store1 = $this->createConfiguredMock(
65+
StoreInterface::class,
66+
[
67+
'getCode' => 'en',
68+
'getId' => 1,
69+
]
70+
);
71+
$store2 = $this->createConfiguredMock(
72+
StoreInterface::class,
73+
[
74+
'getCode' => 'fr',
75+
'getId' => 2,
76+
]
77+
);
78+
$this->context = $this->createConfiguredMock(
79+
ContextInterface::class,
80+
[
81+
'getFromStore' => $store2,
82+
'getTargetStore' => $store1,
83+
]
84+
);
85+
}
86+
87+
/**
88+
* @dataProvider processDataProvider
89+
* @param array $mock
90+
* @param array $data
91+
* @param bool $isQuoteSet
92+
*/
93+
public function testProcess(array $mock, array $data, bool $isQuoteSet): void
94+
{
95+
$this->customerSession->method('isLoggedIn')
96+
->willReturn($mock['isLoggedIn']);
97+
$this->checkoutSession->method('getQuoteId')
98+
->willReturn($mock['getQuoteId']);
99+
$this->checkoutSession->method('getQuote')
100+
->willReturnCallback(
101+
function () use ($mock) {
102+
return $this->createQuoteMock($mock);
103+
}
104+
);
105+
$this->quoteRepository->method('get')
106+
->willReturnCallback(
107+
function ($id) use ($mock) {
108+
return $this->createQuoteMock(array_merge($mock, ['getQuoteId' => $id]));
109+
}
110+
);
111+
$this->checkoutSession->expects($isQuoteSet ? $this->once() : $this->never())
112+
->method('setQuoteId')
113+
->with($data['quote_id'] ?? null);
114+
115+
$this->model->process($this->context, $data);
116+
}
117+
118+
/**
119+
* @return array
120+
*/
121+
public function processDataProvider(): array
122+
{
123+
return [
124+
[
125+
['isLoggedIn' => false, 'getQuoteId' => 4],
126+
['quote_id' => 2],
127+
false
128+
],
129+
[
130+
['isLoggedIn' => true, 'getQuoteId' => null],
131+
['quote_id' => 2],
132+
false
133+
],
134+
[
135+
['isLoggedIn' => false, 'getQuoteId' => null],
136+
['quote_id' => 1],
137+
false
138+
],
139+
[
140+
['isLoggedIn' => false, 'getQuoteId' => null, 'getIsActive' => false],
141+
['quote_id' => 2],
142+
false
143+
],
144+
[
145+
['isLoggedIn' => false, 'getQuoteId' => null],
146+
['quote_id' => 2],
147+
true
148+
],
149+
];
150+
}
151+
152+
/**
153+
* @param array $mock
154+
* @return Quote
155+
*/
156+
private function createQuoteMock(array $mock): Quote
157+
{
158+
return $this->createConfiguredMock(
159+
Quote::class,
160+
[
161+
'getIsActive' => $mock['getIsActive'] ?? true,
162+
'getId' => $mock['getQuoteId'],
163+
'getSharedStoreIds' => !($mock['getQuoteId'] % 2) ? [1, 2] : [2],
164+
]
165+
);
166+
}
167+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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\Checkout\Test\Unit\Model\StoreSwitcher;
9+
10+
use Magento\Checkout\Model\Session as CheckoutSession;
11+
use Magento\Checkout\Model\StoreSwitcher\RedirectDataPreprocessor;
12+
use Magento\Customer\Model\Session as CustomerSession;
13+
use Magento\Quote\Model\Quote;
14+
use Magento\Store\Api\Data\StoreInterface;
15+
use Magento\Store\Model\StoreSwitcher\ContextInterface;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class RedirectDataPreprocessorTest extends TestCase
20+
{
21+
/**
22+
* @var CustomerSession
23+
*/
24+
private $customerSession;
25+
/**
26+
* @var CheckoutSession
27+
*/
28+
private $checkoutSession;
29+
/**
30+
* @var RedirectDataPreprocessor
31+
*/
32+
private $model;
33+
/**
34+
* @var ContextInterface|MockObject
35+
*/
36+
private $context;
37+
38+
/**
39+
* @inheritDoc
40+
*/
41+
protected function setUp(): void
42+
{
43+
parent::setUp();
44+
45+
$this->customerSession = $this->createMock(CustomerSession::class);
46+
$this->checkoutSession = $this->createMock(CheckoutSession::class);
47+
$this->model = new RedirectDataPreprocessor(
48+
$this->customerSession,
49+
$this->checkoutSession
50+
);
51+
52+
$store1 = $this->createConfiguredMock(
53+
StoreInterface::class,
54+
[
55+
'getCode' => 'en',
56+
'getId' => 1,
57+
]
58+
);
59+
$store2 = $this->createConfiguredMock(
60+
StoreInterface::class,
61+
[
62+
'getCode' => 'fr',
63+
'getId' => 2,
64+
]
65+
);
66+
$this->context = $this->createConfiguredMock(
67+
ContextInterface::class,
68+
[
69+
'getFromStore' => $store2,
70+
'getTargetStore' => $store1,
71+
]
72+
);
73+
}
74+
75+
/**
76+
* @dataProvider processDataProvider
77+
* @param array $mock
78+
* @param array $data
79+
*/
80+
public function testProcess(array $mock, array $data): void
81+
{
82+
$this->customerSession->method('isLoggedIn')
83+
->willReturn($mock['isLoggedIn']);
84+
$this->checkoutSession->method('getQuoteId')
85+
->willReturn($mock['getQuoteId']);
86+
$this->checkoutSession->method('getQuote')
87+
->willReturnCallback(
88+
function () use ($mock) {
89+
return $this->createConfiguredMock(
90+
Quote::class,
91+
[
92+
'getIsActive' => $mock['getIsActive'] ?? true,
93+
'getId' => $mock['getQuoteId'],
94+
'getSharedStoreIds' => !($mock['getQuoteId'] % 2) ? [1, 2] : [2],
95+
]
96+
);
97+
}
98+
);
99+
$this->assertEquals($data, $this->model->process($this->context, []));
100+
}
101+
102+
/**
103+
* @return array
104+
*/
105+
public function processDataProvider(): array
106+
{
107+
return [
108+
[
109+
['isLoggedIn' => true, 'getQuoteId' => 1],
110+
[]
111+
],
112+
[
113+
['isLoggedIn' => false, 'getQuoteId' => null],
114+
[]
115+
],
116+
[
117+
['isLoggedIn' => false, 'getQuoteId' => 1],
118+
[]
119+
],
120+
[
121+
['isLoggedIn' => false, 'getQuoteId' => 2],
122+
['quote_id' => 2]
123+
],
124+
];
125+
}
126+
}

app/code/Magento/Customer/Model/StoreSwitcher/RedirectDataPostprocessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function process(ContextInterface $context, array $data): void
6868
throw new LocalizedException(__('Failed to sign into the customer account.'), $e);
6969
} catch (LocalizedException $e) {
7070
$this->logger->error($e);
71-
throw new LocalizedException(__('There was an error retrieving the customer record.'), $e);
71+
throw new LocalizedException(__('Failed to sign into the customer account.'), $e);
7272
}
7373
}
7474
}

0 commit comments

Comments
 (0)