Skip to content

Commit 11e23d6

Browse files
committed
Tests enhancements. Added test case for simple product with customizable options
1 parent 01e6312 commit 11e23d6

File tree

4 files changed

+239
-47
lines changed

4 files changed

+239
-47
lines changed

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddDownloadableProductToCartSingleMutationTest.php

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,25 @@ class AddDownloadableProductToCartSingleMutationTest extends GraphQlAbstract
2828
private $objectManager;
2929

3030
/**
31-
* @var GetCustomOptionsWithIDV2ForQueryBySku
31+
* @var GetCustomOptionsWithUIDForQueryBySku
3232
*/
3333
private $getCustomOptionsWithIDV2ForQueryBySku;
3434

35+
/**
36+
* @var GetCartItemOptionsFromUID
37+
*/
38+
private $getCartItemOptionsFromUID;
39+
3540
/**
3641
* @inheritdoc
3742
*/
3843
protected function setUp(): void
3944
{
4045
$this->objectManager = Bootstrap::getObjectManager();
4146
$this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
47+
$this->getCartItemOptionsFromUID = $this->objectManager->get(GetCartItemOptionsFromUID::class);
4248
$this->getCustomOptionsWithIDV2ForQueryBySku =
43-
$this->objectManager->get(GetCustomOptionsWithIDV2ForQueryBySku::class);
49+
$this->objectManager->get(GetCustomOptionsWithUIDForQueryBySku::class);
4450
}
4551

4652
/**
@@ -57,7 +63,14 @@ public function testAddDownloadableProductWithOptions()
5763
$linkId = key($links);
5864

5965
$itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku);
60-
$decodedItemOptions = $this->decodeCustomOptions($itemOptions);
66+
$decodedItemOptions = $this->getCartItemOptionsFromUID->execute($itemOptions);
67+
68+
/* The type field is only required for assertions, it should not be present in query */
69+
foreach ($itemOptions['entered_options'] as &$enteredOption) {
70+
if (isset($enteredOption['type'])) {
71+
unset($enteredOption['type']);
72+
}
73+
}
6174

6275
/* Add downloadable product link data to the "selected_options" */
6376
$itemOptions['selected_options'][] = $this->generateProductLinkSelectedOptions($linkId);
@@ -129,34 +142,6 @@ private function generateProductLinkSelectedOptions(int $linkId): string
129142
return base64_encode("downloadable/$linkId");
130143
}
131144

132-
/**
133-
* Decodes ID_v2 for customizable options and returns [ID] = value pairs
134-
*
135-
* @param array $encodedCustomOptions
136-
* @return array
137-
*/
138-
private function decodeCustomOptions(array $encodedCustomOptions): array
139-
{
140-
$customOptions = [];
141-
142-
foreach ($encodedCustomOptions['selected_options'] as $selectedOption) {
143-
[,$optionId, $optionValueId] = explode('/', base64_decode($selectedOption));
144-
if (isset($customOptions[$optionId])) {
145-
$customOptions[$optionId] = [$customOptions[$optionId], $optionValueId];
146-
} else {
147-
$customOptions[$optionId] = $optionValueId;
148-
}
149-
150-
}
151-
152-
foreach ($encodedCustomOptions['entered_options'] as $enteredOption) {
153-
[,$optionId] = explode('/', base64_decode($enteredOption['id']));
154-
$customOptions[$optionId] = $enteredOption['value'];
155-
}
156-
157-
return $customOptions;
158-
}
159-
160145
/**
161146
* Returns GraphQl query string
162147
*
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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\TestFramework\Helper\Bootstrap;
11+
use Magento\TestFramework\TestCase\GraphQlAbstract;
12+
13+
/**
14+
* Add simple product with custom options to cart using the unified mutation for adding different product types
15+
*/
16+
class AddSimpleProductToCartSingleMutationTest extends GraphQlAbstract
17+
{
18+
/**
19+
* @var GetCustomOptionsWithUIDForQueryBySku
20+
*/
21+
private $getCustomOptionsWithIDV2ForQueryBySku;
22+
23+
/**
24+
* @var GetMaskedQuoteIdByReservedOrderId
25+
*/
26+
private $getMaskedQuoteIdByReservedOrderId;
27+
28+
/**
29+
* @var GetCartItemOptionsFromUID
30+
*/
31+
private $getCartItemOptionsFromUID;
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
protected function setUp(): void
37+
{
38+
$objectManager = Bootstrap::getObjectManager();
39+
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
40+
$this->getCartItemOptionsFromUID = $objectManager->get(GetCartItemOptionsFromUID::class);
41+
$this->getCustomOptionsWithIDV2ForQueryBySku = $objectManager->get(
42+
GetCustomOptionsWithUIDForQueryBySku::class
43+
);
44+
}
45+
46+
/**
47+
* Test adding a simple product to the shopping cart with all supported
48+
* customizable options assigned
49+
*
50+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_options.php
51+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
52+
*/
53+
public function testAddSimpleProductWithOptions()
54+
{
55+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
56+
57+
$sku = 'simple';
58+
$qty = 1;
59+
60+
$itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku);
61+
$decodedItemOptions = $this->getCartItemOptionsFromUID->execute($itemOptions);
62+
63+
/* The type field is only required for assertions, it should not be present in query */
64+
foreach ($itemOptions['entered_options'] as &$enteredOption) {
65+
if (isset($enteredOption['type'])) {
66+
unset($enteredOption['type']);
67+
}
68+
}
69+
70+
$productOptionsQuery = preg_replace(
71+
'/"([^"]+)"\s*:\s*/',
72+
'$1:',
73+
json_encode($itemOptions)
74+
);
75+
76+
$query = $this->getQuery($maskedQuoteId, $qty, $sku, trim($productOptionsQuery, '{}'));
77+
$response = $this->graphQlMutation($query);
78+
79+
self::assertArrayHasKey('items', $response['addProductsToCart']['cart']);
80+
self::assertCount($qty, $response['addProductsToCart']['cart']);
81+
$customizableOptionsOutput =
82+
$response['addProductsToCart']['cart']['items'][0]['customizable_options'];
83+
84+
foreach ($customizableOptionsOutput as $customizableOptionOutput) {
85+
$customizableOptionOutputValues = [];
86+
foreach ($customizableOptionOutput['values'] as $customizableOptionOutputValue) {
87+
$customizableOptionOutputValues[] = $customizableOptionOutputValue['value'];
88+
}
89+
if (count($customizableOptionOutputValues) === 1) {
90+
$customizableOptionOutputValues = $customizableOptionOutputValues[0];
91+
}
92+
93+
self::assertEquals(
94+
$decodedItemOptions[$customizableOptionOutput['id']],
95+
$customizableOptionOutputValues
96+
);
97+
}
98+
}
99+
100+
/**
101+
* Returns GraphQl query string
102+
*
103+
* @param string $maskedQuoteId
104+
* @param int $qty
105+
* @param string $sku
106+
* @param string $customizableOptions
107+
* @return string
108+
*/
109+
private function getQuery(
110+
string $maskedQuoteId,
111+
int $qty,
112+
string $sku,
113+
string $customizableOptions
114+
): string {
115+
return <<<MUTATION
116+
mutation {
117+
addProductsToCart(
118+
cartId: "{$maskedQuoteId}",
119+
cartItems: [
120+
{
121+
sku: "{$sku}"
122+
quantity: {$qty}
123+
{$customizableOptions}
124+
}
125+
]
126+
) {
127+
cart {
128+
items {
129+
quantity
130+
... on SimpleCartItem {
131+
customizable_options {
132+
label
133+
id
134+
values {
135+
value
136+
}
137+
}
138+
}
139+
}
140+
},
141+
userInputErrors {
142+
message
143+
}
144+
}
145+
}
146+
MUTATION;
147+
}
148+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
/**
11+
* Extracts cart item options from UID
12+
*/
13+
class GetCartItemOptionsFromUID
14+
{
15+
/**
16+
* Gets an array of encoded item options with UID, extracts and decodes the values
17+
*
18+
* @param array $encodedCustomOptions
19+
* @return array
20+
*/
21+
public function execute(array $encodedCustomOptions): array
22+
{
23+
$customOptions = [];
24+
25+
foreach ($encodedCustomOptions['selected_options'] as $selectedOption) {
26+
[,$optionId, $optionValueId] = explode('/', base64_decode($selectedOption));
27+
if (isset($customOptions[$optionId])) {
28+
$customOptions[$optionId] = [$customOptions[$optionId], $optionValueId];
29+
} else {
30+
$customOptions[$optionId] = $optionValueId;
31+
}
32+
33+
}
34+
35+
foreach ($encodedCustomOptions['entered_options'] as $enteredOption) {
36+
/* The date normalization is required since the attribute might value is formatted by the system */
37+
if ($enteredOption['type'] === 'date') {
38+
$enteredOption['value'] = date('M d, Y', strtotime($enteredOption['value']));
39+
}
40+
[,$optionId] = explode('/', base64_decode($enteredOption['id']));
41+
$customOptions[$optionId] = $enteredOption['value'];
42+
}
43+
44+
return $customOptions;
45+
}
46+
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsWithIDV2ForQueryBySku.php renamed to dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsWithUIDForQueryBySku.php

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
* Generate an array with test values for customizable options with encoded id_v2 value
1414
*/
15-
class GetCustomOptionsWithIDV2ForQueryBySku
15+
class GetCustomOptionsWithUIDForQueryBySku
1616
{
1717
/**
1818
* @var ProductCustomOptionRepositoryInterface
@@ -42,24 +42,37 @@ public function execute(string $sku): array
4242
foreach ($customOptions as $customOption) {
4343
$optionType = $customOption->getType();
4444

45-
if ($optionType === 'field' || $optionType === 'area' || $optionType === 'date') {
46-
$enteredOptions[] = [
47-
'id' => $this->encodeEnteredOption((int) $customOption->getOptionId()),
48-
'value' => '2012-12-12'
49-
];
50-
} elseif ($optionType === 'drop_down') {
51-
$optionSelectValues = $customOption->getValues();
52-
$selectedOptions[] = $this->encodeSelectedOption(
53-
(int) $customOption->getOptionId(),
54-
(int) reset($optionSelectValues)->getOptionTypeId()
55-
);
56-
} elseif ($optionType === 'multiple') {
57-
foreach ($customOption->getValues() as $optionValue) {
45+
switch ($optionType) {
46+
case 'field':
47+
case 'area':
48+
$enteredOptions[] = [
49+
'type' => 'field',
50+
'id' => $this->encodeEnteredOption((int) $customOption->getOptionId()),
51+
'value' => 'test'
52+
];
53+
break;
54+
case 'date':
55+
$enteredOptions[] = [
56+
'type' => 'date',
57+
'id' => $this->encodeEnteredOption((int) $customOption->getOptionId()),
58+
'value' => '2012-12-12 00:00:00'
59+
];
60+
break;
61+
case 'drop_down':
62+
$optionSelectValues = $customOption->getValues();
5863
$selectedOptions[] = $this->encodeSelectedOption(
5964
(int) $customOption->getOptionId(),
60-
(int) $optionValue->getOptionTypeId()
65+
(int) reset($optionSelectValues)->getOptionTypeId()
6166
);
62-
}
67+
break;
68+
case 'multiple':
69+
foreach ($customOption->getValues() as $optionValue) {
70+
$selectedOptions[] = $this->encodeSelectedOption(
71+
(int) $customOption->getOptionId(),
72+
(int) $optionValue->getOptionTypeId()
73+
);
74+
}
75+
break;
6376
}
6477
}
6578

0 commit comments

Comments
 (0)