Skip to content

Commit 87652b1

Browse files
committed
Merge branch 'ACP2E-2098' of https://github.com/magento-l3/magento2ce into PR-L3-2023-07-14
2 parents 8dc8c7e + 03bdd31 commit 87652b1

File tree

5 files changed

+373
-14
lines changed

5 files changed

+373
-14
lines changed

app/code/Magento/QuoteGraphQl/Plugin/ProductAttributesExtender.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class ProductAttributesExtender
2626
*/
2727
private $attributeCollectionFactory;
2828

29+
/**
30+
* @var array
31+
*/
32+
private $attributes;
33+
2934
/**
3035
* @param Fields $fields
3136
* @param AttributeCollectionFactory $attributeCollectionFactory
@@ -48,12 +53,15 @@ public function __construct(
4853
*/
4954
public function afterGetProductAttributes(QuoteConfig $subject, array $result): array
5055
{
51-
$attributeCollection = $this->attributeCollectionFactory->create()
52-
->removeAllFieldsFromSelect()
53-
->addFieldToSelect('attribute_code')
54-
->setCodeFilter($this->fields->getFieldsUsedInQuery())
55-
->load();
56-
$attributes = $attributeCollection->getColumnValues('attribute_code');
56+
if (!$this->attributes) {
57+
$attributeCollection = $this->attributeCollectionFactory->create()
58+
->removeAllFieldsFromSelect()
59+
->addFieldToSelect('attribute_code')
60+
->setCodeFilter($this->fields->getFieldsUsedInQuery())
61+
->load();
62+
$this->attributes = $attributeCollection->getColumnValues('attribute_code');
63+
}
64+
$attributes = $this->attributes;
5765

5866
return array_unique(array_merge($result, $attributes));
5967
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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\GraphQl\Quote;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Test\Fixture\Attribute as AttributeFixture;
12+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
13+
use Magento\Framework\Exception\NoSuchEntityException;
14+
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
15+
use Magento\Quote\Test\Fixture\GuestCart as GuestCartFixture;
16+
use Magento\TestFramework\Fixture\DataFixture;
17+
use Magento\TestFramework\Fixture\DataFixtureStorage;
18+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
19+
use Magento\TestFramework\Helper\Bootstrap;
20+
use Magento\TestFramework\TestCase\GraphQlAbstract;
21+
22+
/**
23+
* Get add to cart through GraphQl query and variables
24+
*/
25+
class AddProductsToCartWithVariablesTest extends GraphQlAbstract
26+
{
27+
/**
28+
* @var ProductRepositoryInterface
29+
*/
30+
private $productRepository;
31+
32+
/**
33+
* @var DataFixtureStorage
34+
*/
35+
private $fixtures;
36+
37+
/**
38+
* @var QuoteIdToMaskedQuoteIdInterface
39+
*/
40+
private $quoteIdToMaskedQuoteIdInterface;
41+
42+
/**
43+
* @inheritdoc
44+
*/
45+
protected function setUp(): void
46+
{
47+
$objectManager = Bootstrap::getObjectManager();
48+
49+
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
50+
$this->quoteIdToMaskedQuoteIdInterface = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class);
51+
$this->fixtures = $objectManager->get(DataFixtureStorageManager::class)->getStorage();
52+
}
53+
54+
/**
55+
* @throws NoSuchEntityException
56+
* @throws \Exception
57+
*/
58+
#[
59+
DataFixture(AttributeFixture::class, ['is_visible_on_front' => true], as: 'attr'),
60+
DataFixture(ProductFixture::class, [
61+
'attribute_set_id' => 4,
62+
'$attr.attribute_code$' => 'default_value'
63+
], as: 'product'),
64+
DataFixture(GuestCartFixture::class, as: 'cart'),
65+
]
66+
public function testAddProductsToEmptyCartWithVariables(): void
67+
{
68+
$attribute = $this->fixtures->get('attr');
69+
$product = $this->fixtures->get('product');
70+
71+
$this->cleanCache();
72+
73+
$cart = $this->fixtures->get('cart');
74+
$maskedQuoteId = $this->quoteIdToMaskedQuoteIdInterface->execute((int) $cart->getId());
75+
$query = $this->getAddToCartMutation($attribute->getAttributeCode());
76+
$variables = $this->getAddToCartVariables($maskedQuoteId, 1, $product->getSku());
77+
$response = $this->graphQlMutation($query, $variables);
78+
$result = $response['addProductsToCart'];
79+
80+
self::assertEmpty($result['user_errors']);
81+
self::assertCount(1, $result['cart']['items']);
82+
83+
$cartItem = $result['cart']['items'][0];
84+
self::assertEquals($product->getSku(), $cartItem['product']['sku']);
85+
self::assertEquals('default_value', $cartItem['product'][$attribute->getAttributeCode()]);
86+
self::assertEquals(1, $cartItem['quantity']);
87+
self::assertEquals($product->getFinalPrice(), $cartItem['prices']['price']['value']);
88+
}
89+
90+
/**
91+
* Returns GraphQl mutation for adding item to cart
92+
*
93+
* @param string $customAttributeCode
94+
* @return string
95+
*/
96+
private function getAddToCartMutation(string $customAttributeCode): string
97+
{
98+
return <<<MUTATION
99+
mutation (\$cartId: String!, \$products: [CartItemInput!]!) {
100+
addProductsToCart(cartId: \$cartId, cartItems: \$products) {
101+
cart {
102+
id
103+
items {
104+
uid
105+
quantity
106+
product {
107+
sku
108+
name
109+
{$customAttributeCode}
110+
thumbnail {
111+
url
112+
__typename
113+
}
114+
__typename
115+
}
116+
prices {
117+
price {
118+
value
119+
currency
120+
}
121+
}
122+
}
123+
}
124+
user_errors {
125+
code
126+
message
127+
}
128+
}
129+
}
130+
MUTATION;
131+
}
132+
133+
private function getAddToCartVariables(
134+
string $maskedQuoteId,
135+
int $qty,
136+
string $sku
137+
): array {
138+
return
139+
[
140+
'cartId' => $maskedQuoteId,
141+
'products' => [
142+
[
143+
'sku' => $sku,
144+
'parent_sku' => $sku,
145+
'quantity' => $qty
146+
]
147+
]
148+
];
149+
}
150+
}

dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureSetup.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\TestFramework\Annotation;
99

1010
use Magento\Framework\DataObject;
11+
use Magento\Framework\Exception\LocalizedException;
1112
use Magento\Framework\Exception\NoSuchEntityException;
1213
use Magento\Framework\Registry;
1314
use Magento\TestFramework\Fixture\DataFixtureFactory;
@@ -37,6 +38,7 @@ public function __construct(
3738
*
3839
* @param array $fixture
3940
* @return DataObject|null
41+
* @throws LocalizedException
4042
*/
4143
public function apply(array $fixture): ?DataObject
4244
{
@@ -96,25 +98,52 @@ public function revert(array $fixture): void
9698
*
9799
* @param array $data
98100
* @return array
99-
* @throws \Magento\Framework\Exception\LocalizedException
101+
* @throws LocalizedException
100102
*/
101103
private function resolveVariables(array $data): array
102104
{
103105
foreach ($data as $key => $value) {
104106
if (is_array($value)) {
105107
$data[$key] = $this->resolveVariables($value);
106108
} else {
107-
if (is_string($value) && preg_match('/^\$\w+(\.\w+)?\$$/', $value)) {
108-
list($fixtureName, $attribute) = array_pad(explode('.', trim($value, '$')), 2, null);
109-
$fixtureData = DataFixtureStorageManager::getStorage()->get($fixtureName);
110-
if (!$fixtureData) {
111-
throw new \InvalidArgumentException("Unable to resolve fixture reference '$value'");
109+
if (is_string($value)) {
110+
$value = $this->parseFixtureKeyValue($value);
111+
if ($value) {
112+
$data[$key] = $value;
112113
}
113-
$data[$key] = $attribute ? $fixtureData->getDataUsingMethod($attribute) : $fixtureData;
114+
}
115+
}
116+
117+
if (is_string($key)) {
118+
$newKey = $this->parseFixtureKeyValue($key);
119+
if (is_string($newKey)) {
120+
$value = $data[$key];
121+
unset($data[$key]);
122+
$data[$newKey] = $value;
114123
}
115124
}
116125
}
117126

118127
return $data;
119128
}
129+
130+
/**
131+
* Parse either key or value of the fixture data
132+
*
133+
* @param string $data
134+
* @return DataObject|mixed|void
135+
* @throws LocalizedException
136+
*/
137+
private function parseFixtureKeyValue(string $data)
138+
{
139+
if (preg_match('/^\$\w+(\.\w+)?\$$/', $data)) {
140+
list($fixtureName, $attribute) = array_pad(explode('.', trim($data, '$')), 2, null);
141+
$fixtureData = DataFixtureStorageManager::getStorage()->get($fixtureName);
142+
if (!$fixtureData) {
143+
throw new \InvalidArgumentException("Unable to resolve fixture reference '$data'");
144+
}
145+
return $attribute ? $fixtureData->getDataUsingMethod($attribute) : $fixtureData;
146+
}
147+
return false;
148+
}
120149
}

lib/internal/Magento/Framework/GraphQl/Query/Fields.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ private function extractVariables(array &$fields, array $variables): void
101101
foreach ($variables as $key => $value) {
102102
if (is_array($value)) {
103103
$this->extractVariables($fields, $value);
104+
} else {
105+
$fields[$key] = $key;
104106
}
105-
$fields[$key] = $key;
106107
}
107108
}
108109

0 commit comments

Comments
 (0)