Skip to content

Commit 937a3e2

Browse files
PWA-1740: Populating customer session for GraphQl
1 parent ed2ffad commit 937a3e2

14 files changed

+702
-2
lines changed

app/code/Magento/CustomerGraphQl/Model/Context/AddUserInfoToContext.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
namespace Magento\CustomerGraphQl\Model\Context;
99

1010
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\Customer\Model\ResourceModel\CustomerRepository;
12+
use Magento\Customer\Model\Session;
1113
use Magento\GraphQl\Model\Query\ContextParametersInterface;
1214
use Magento\GraphQl\Model\Query\ContextParametersProcessorInterface;
1315

@@ -21,13 +23,29 @@ class AddUserInfoToContext implements ContextParametersProcessorInterface
2123
*/
2224
private $userContext;
2325

26+
/**
27+
* @var Session
28+
*/
29+
private $session;
30+
31+
/**
32+
* @var CustomerRepository
33+
*/
34+
private $customerRepository;
35+
2436
/**
2537
* @param UserContextInterface $userContext
38+
* @param Session $session
39+
* @param CustomerRepository $customerRepository
2640
*/
2741
public function __construct(
28-
UserContextInterface $userContext
42+
UserContextInterface $userContext,
43+
Session $session,
44+
CustomerRepository $customerRepository
2945
) {
3046
$this->userContext = $userContext;
47+
$this->session = $session;
48+
$this->customerRepository = $customerRepository;
3149
}
3250

3351
/**
@@ -47,7 +65,13 @@ public function execute(ContextParametersInterface $contextParameters): ContextP
4765
}
4866
$contextParameters->setUserType($currentUserType);
4967

50-
$contextParameters->addExtensionAttribute('is_customer', $this->isCustomer($currentUserId, $currentUserType));
68+
$isCustomer = $this->isCustomer($currentUserId, $currentUserType);
69+
$contextParameters->addExtensionAttribute('is_customer', $isCustomer);
70+
if ($isCustomer) {
71+
$customer = $this->customerRepository->getById($currentUserId);
72+
$this->session->setCustomerData($customer);
73+
$this->session->setCustomerGroupId($customer->getGroupId());
74+
}
5175
return $contextParameters;
5276
}
5377

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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\CustomerGraphQl\Plugin;
9+
10+
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\Customer\Model\ResourceModel\CustomerRepository;
12+
use Magento\Customer\Model\Session as CustomerSession;
13+
use Magento\Framework\App\ResponseInterface;
14+
use Magento\Framework\Exception\LocalizedException;
15+
use Magento\Framework\Exception\NoSuchEntityException;
16+
use Magento\GraphQl\Controller\GraphQl as GraphQlController;
17+
18+
/**
19+
* Clear the user data out of the session object before returning the GraphQL response
20+
*/
21+
class ClearCustomerSessionAfterRequest
22+
{
23+
/**
24+
* @var UserContextInterface
25+
*/
26+
private $userContext;
27+
28+
/**
29+
* @var CustomerSession
30+
*/
31+
private $customerSession;
32+
33+
/**
34+
* @var CustomerRepository
35+
*/
36+
private $customerRepository;
37+
38+
/**
39+
* @param UserContextInterface $userContext
40+
* @param CustomerSession $customerSession
41+
* @param CustomerRepository $customerRepository
42+
*/
43+
public function __construct(
44+
UserContextInterface $userContext,
45+
CustomerSession $customerSession,
46+
CustomerRepository $customerRepository
47+
) {
48+
$this->userContext = $userContext;
49+
$this->customerSession = $customerSession;
50+
$this->customerRepository = $customerRepository;
51+
}
52+
53+
/**
54+
* Clear the customer data from the session after business logic has completed
55+
*
56+
* @param GraphQlController $controller
57+
* @param ResponseInterface $response
58+
* @return ResponseInterface
59+
*
60+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
61+
*/
62+
public function afterDispatch(GraphQlController $controller, ResponseInterface $response): ResponseInterface
63+
{
64+
$this->customerSession->setCustomerId(null);
65+
$this->customerSession->setCustomerGroupId(null);
66+
return $response;
67+
}
68+
}

app/code/Magento/CustomerGraphQl/etc/graphql/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@
4040
</argument>
4141
</arguments>
4242
</type>
43+
<type name="Magento\GraphQl\Controller\GraphQl">
44+
<plugin name="ClearCustomerSessionAfterRequest" type="Magento\CustomerGraphQl\Plugin\ClearCustomerSessionAfterRequest" sortOrder="1" disabled="false" />
45+
</type>
4346
</config>

dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogGraphQl/PriceRangeTest.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,114 @@ public function testCheckIfCatalogRuleIsAppliedForTierPriceForGuest(): void
113113
$this->assertEquals(10, $priceRange['maximum_price']['discount']['percent_off']);
114114
}
115115

116+
/**
117+
* Test to make sure tax amount is displayed correctly for a logged-in user
118+
*
119+
* @magentoConfigFixture default_store tax/display/type 2
120+
*
121+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
122+
* @magentoApiDataFixture Magento/Customer/_files/customer_shipping_address_36104.php
123+
* @magentoApiDataFixture Magento/Tax/_files/tax_rule_postal_36104.php
124+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
125+
*/
126+
public function testTaxDisplayAppliesToCustomer(): void
127+
{
128+
$productSku = 'simple';
129+
$query = $this->getProductSearchQuery($productSku);
130+
$response = $this->graphQlQuery(
131+
$query,
132+
[],
133+
'',
134+
$this->getCustomerAuthenticationHeader->execute('[email protected]', 'password')
135+
);
136+
137+
$this->assertNotEmpty($response['products']);
138+
$priceRange = $response['products']['items'][0]['price_range'];
139+
$this->assertEquals(10.75, round($priceRange['minimum_price']['regular_price']['value'], 2));
140+
$this->assertEquals(10.75, round($priceRange['minimum_price']['final_price']['value'], 2));
141+
$this->assertEquals(10.75, round($priceRange['maximum_price']['regular_price']['value'], 2));
142+
$this->assertEquals(10.75, round($priceRange['maximum_price']['final_price']['value'], 2));
143+
}
144+
145+
/**
146+
* Test to make sure tax rule is not applied in display for guest
147+
*
148+
* @magentoConfigFixture default_store tax/display/type 2
149+
*
150+
* @magentoApiDataFixture Magento/Tax/_files/tax_rule_postal_36104.php
151+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
152+
*/
153+
public function testTaxDisplayDoesNotApplyToGuest(): void
154+
{
155+
$productSku = 'simple';
156+
$query = $this->getProductSearchQuery($productSku);
157+
$response = $this->graphQlQuery($query);
158+
159+
$this->assertNotEmpty($response['products']);
160+
$priceRange = $response['products']['items'][0]['price_range'];
161+
$this->assertEquals(10, $priceRange['minimum_price']['regular_price']['value']);
162+
$this->assertEquals(10, $priceRange['minimum_price']['final_price']['value']);
163+
$this->assertEquals(10, $priceRange['maximum_price']['regular_price']['value']);
164+
$this->assertEquals(10, $priceRange['maximum_price']['final_price']['value']);
165+
}
166+
167+
/**
168+
* Test to make sure tax rule is applied for customer group
169+
*
170+
* @magentoConfigFixture default_store tax/display/type 2
171+
*
172+
* @magentoApiDataFixture Magento/Customer/_files/customer_with_group_and_address.php
173+
* @magentoApiDataFixture Magento/Tax/_files/tax_class_customer_group.php
174+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
175+
*/
176+
public function testTaxDisplayAppliesToCustomerGroup()
177+
{
178+
$productSku = 'simple';
179+
$query = $this->getProductSearchQuery($productSku);
180+
$response = $this->graphQlQuery(
181+
$query,
182+
[],
183+
'',
184+
$this->getCustomerAuthenticationHeader->execute('[email protected]', 'password')
185+
);
186+
187+
$this->assertNotEmpty($response['products']);
188+
$priceRange = $response['products']['items'][0]['price_range'];
189+
$this->assertEquals(10.75, round($priceRange['minimum_price']['regular_price']['value'], 2));
190+
$this->assertEquals(10.75, round($priceRange['minimum_price']['final_price']['value'], 2));
191+
$this->assertEquals(10.75, round($priceRange['maximum_price']['regular_price']['value'], 2));
192+
$this->assertEquals(10.75, round($priceRange['maximum_price']['final_price']['value'], 2));
193+
}
194+
195+
/**
196+
* Test to make sure tax rule is not applied for a customer in the wrong group
197+
*
198+
* @magentoConfigFixture default_store tax/display/type 2
199+
*
200+
* @magentoApiDataFixture Magento/Customer/_files/customer_with_group_and_address.php
201+
* @magentoApiDataFixture Magento/Customer/_files/second_customer_with_group_and_address.php
202+
* @magentoApiDataFixture Magento/Tax/_files/tax_class_customer_group.php
203+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
204+
*/
205+
public function testTaxDisplayDoesNotApplyToWrongCustomerGroup(): void
206+
{
207+
$productSku = 'simple';
208+
$query = $this->getProductSearchQuery($productSku);
209+
$response = $this->graphQlQuery(
210+
$query,
211+
[],
212+
'',
213+
$this->getCustomerAuthenticationHeader->execute('[email protected]', 'password')
214+
);
215+
216+
$this->assertNotEmpty($response['products']);
217+
$priceRange = $response['products']['items'][0]['price_range'];
218+
$this->assertEquals(10, $priceRange['minimum_price']['regular_price']['value']);
219+
$this->assertEquals(10, $priceRange['minimum_price']['final_price']['value']);
220+
$this->assertEquals(10, $priceRange['maximum_price']['regular_price']['value']);
221+
$this->assertEquals(10, $priceRange['maximum_price']['final_price']['value']);
222+
}
223+
116224
/**
117225
* Get a query which user filter for product sku and returns price_tiers
118226
*
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Customer address fixture with postcode 36104
4+
*
5+
* Copyright © Magento, Inc. All rights reserved.
6+
* See COPYING.txt for license details.
7+
*/
8+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
9+
/** @var \Magento\Customer\Model\Address $customerAddress */
10+
$customerAddress = $objectManager->create(\Magento\Customer\Model\Address::class);
11+
/** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */
12+
$customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class);
13+
$customerAddress->isObjectNew(true);
14+
$customerAddress->setData(
15+
[
16+
'entity_id' => 1,
17+
'attribute_set_id' => 2,
18+
'telephone' => 3342423935,
19+
'postcode' => 36104,
20+
'country_id' => 'US',
21+
'city' => 'Montgomery',
22+
'company' => 'Govt',
23+
'street' => 'Alabama State Capitol',
24+
'lastname' => 'Smith',
25+
'firstname' => 'John',
26+
'parent_id' => 1,
27+
'region_id' => 1,
28+
]
29+
);
30+
$customerAddress->save();
31+
32+
/** @var \Magento\Customer\Api\AddressRepositoryInterface $addressRepository */
33+
$addressRepository = $objectManager->get(\Magento\Customer\Api\AddressRepositoryInterface::class);
34+
$customerAddress = $addressRepository->getById(1);
35+
$customerAddress->setCustomerId(1);
36+
$customerAddress = $addressRepository->save($customerAddress);
37+
38+
39+
/** @var \Magento\Customer\Model\Customer $customer */
40+
$customer = $objectManager->create(
41+
\Magento\Customer\Model\Customer::class
42+
)->load($customerAddress->getCustomerId());
43+
$customer->setDefaultShipping(1);
44+
$customer->save();
45+
46+
$customerRegistry->remove($customerAddress->getCustomerId());
47+
/** @var \Magento\Customer\Model\AddressRegistry $addressRegistry */
48+
$addressRegistry = $objectManager->get(\Magento\Customer\Model\AddressRegistry::class);
49+
$addressRegistry->remove($customerAddress->getId());
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
/** @var \Magento\Framework\Registry $registry */
8+
$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
9+
$registry->unregister('isSecureArea');
10+
$registry->register('isSecureArea', true);
11+
12+
/** @var \Magento\Customer\Model\Address $customerAddress */
13+
$customerAddress = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
14+
->create(\Magento\Customer\Model\Address::class);
15+
$customerAddress->load(1);
16+
if ($customerAddress->getId()) {
17+
$customerAddress->delete();
18+
}
19+
20+
$registry->unregister('isSecureArea');
21+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)