Skip to content

Commit 64916e5

Browse files
ENGCOM-5767: graphQl-825: Add downloadable product to Cart with customizable options #869
- Merge Pull Request magento/graphql-ce#869 from magento/graphql-ce:GraphQl-825-testAddDownloadableProductWithOptions - Merged commits: 1. a918fa9 2. 9d2c606
2 parents db43c11 + 9d2c606 commit 64916e5

File tree

6 files changed

+387
-73
lines changed

6 files changed

+387
-73
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
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\Framework\ObjectManager\ObjectManager;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\TestCase\GraphQlAbstract;
14+
15+
/**
16+
* Test cases for adding downloadable product with custom options to cart.
17+
*/
18+
class AddDownloadableProductWithCustomOptionsToCartTest extends GraphQlAbstract
19+
{
20+
/**
21+
* @var GetMaskedQuoteIdByReservedOrderId
22+
*/
23+
private $getMaskedQuoteIdByReservedOrderId;
24+
25+
/**
26+
* @var ObjectManager
27+
*/
28+
private $objectManager;
29+
30+
/**
31+
* @var GetCustomOptionsValuesForQueryBySku
32+
*/
33+
private $getCustomOptionsValuesForQueryBySku;
34+
35+
/**
36+
* @inheritdoc
37+
*/
38+
protected function setUp()
39+
{
40+
$this->objectManager = Bootstrap::getObjectManager();
41+
$this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
42+
$this->getCustomOptionsValuesForQueryBySku =
43+
$this->objectManager->get(GetCustomOptionsValuesForQueryBySku::class);
44+
}
45+
46+
/**
47+
* @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php
48+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
49+
*/
50+
public function testAddDownloadableProductWithOptions()
51+
{
52+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
53+
54+
$sku = 'downloadable-product-with-purchased-separately-links';
55+
$qty = 1;
56+
$links = $this->getProductsLinks($sku);
57+
$linkId = key($links);
58+
59+
$customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku);
60+
/* Generate customizable options fragment for GraphQl request */
61+
$queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
62+
$customizableOptions = "customizable_options: {$queryCustomizableOptionValues}";
63+
64+
$query = $this->getQuery($maskedQuoteId, $qty, $sku, $customizableOptions, $linkId);
65+
66+
$response = $this->graphQlMutation($query);
67+
self::assertArrayHasKey('items', $response['addDownloadableProductsToCart']['cart']);
68+
self::assertCount($qty, $response['addDownloadableProductsToCart']['cart']);
69+
$customizableOptionsOutput =
70+
$response['addDownloadableProductsToCart']['cart']['items'][0]['customizable_options'];
71+
$assignedOptionsCount = count($customOptionsValues);
72+
for ($counter = 0; $counter < $assignedOptionsCount; $counter++) {
73+
$expectedValues = $this->buildExpectedValuesArray($customOptionsValues[$counter]['value_string']);
74+
self::assertEquals(
75+
$expectedValues,
76+
$customizableOptionsOutput[$counter]['values']
77+
);
78+
}
79+
}
80+
81+
/**
82+
* @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php
83+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
84+
*/
85+
public function testAddDownloadableProductWithMissedRequiredOptionsSet()
86+
{
87+
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
88+
89+
$sku = 'downloadable-product-with-purchased-separately-links';
90+
$qty = 1;
91+
$links = $this->getProductsLinks($sku);
92+
$linkId = key($links);
93+
$customizableOptions = '';
94+
95+
$query = $this->getQuery($maskedQuoteId, $qty, $sku, $customizableOptions, $linkId);
96+
97+
$this->expectException(\Exception::class);
98+
$this->expectExceptionMessage(
99+
'The product\'s required option(s) weren\'t entered. Make sure the options are entered and try again.'
100+
);
101+
102+
$this->graphQlMutation($query);
103+
}
104+
105+
/**
106+
* Function returns array of all product's links
107+
*
108+
* @param string $sku
109+
* @return array
110+
*/
111+
private function getProductsLinks(string $sku) : array
112+
{
113+
$result = [];
114+
$productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
115+
116+
$product = $productRepository->get($sku, false, null, true);
117+
118+
foreach ($product->getDownloadableLinks() as $linkObject) {
119+
$result[$linkObject->getLinkId()] = [
120+
'title' => $linkObject->getTitle(),
121+
'link_type' => null, //deprecated field
122+
'price' => $linkObject->getPrice(),
123+
];
124+
}
125+
126+
return $result;
127+
}
128+
129+
/**
130+
* Build the part of expected response.
131+
*
132+
* @param string $assignedValue
133+
* @return array
134+
*/
135+
private function buildExpectedValuesArray(string $assignedValue) : array
136+
{
137+
$assignedOptionsArray = explode(',', trim($assignedValue, '[]'));
138+
$expectedArray = [];
139+
foreach ($assignedOptionsArray as $assignedOption) {
140+
$expectedArray[] = ['value' => $assignedOption];
141+
}
142+
return $expectedArray;
143+
}
144+
145+
/**
146+
* Returns GraphQl query string
147+
*
148+
* @param string $maskedQuoteId
149+
* @param int $qty
150+
* @param string $sku
151+
* @param string $customizableOptions
152+
* @param $linkId
153+
* @return string
154+
*/
155+
private function getQuery(
156+
string $maskedQuoteId,
157+
int $qty,
158+
string $sku,
159+
string $customizableOptions,
160+
$linkId
161+
): string {
162+
$query = <<<MUTATION
163+
mutation {
164+
addDownloadableProductsToCart(
165+
input: {
166+
cart_id: "{$maskedQuoteId}",
167+
cart_items: [
168+
{
169+
data: {
170+
quantity: {$qty},
171+
sku: "{$sku}"
172+
},
173+
{$customizableOptions}
174+
downloadable_product_links: [
175+
{
176+
link_id: {$linkId}
177+
}
178+
]
179+
}
180+
]
181+
}
182+
) {
183+
cart {
184+
items {
185+
quantity
186+
... on DownloadableCartItem {
187+
customizable_options {
188+
label
189+
values {
190+
value
191+
}
192+
}
193+
}
194+
}
195+
}
196+
}
197+
}
198+
MUTATION;
199+
return $query;
200+
}
201+
}

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

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class AddSimpleProductWithCustomOptionsToCartTest extends GraphQlAbstract
2626
*/
2727
private $productCustomOptionsRepository;
2828

29+
/**
30+
* @var GetCustomOptionsValuesForQueryBySku
31+
*/
32+
private $getCustomOptionsValuesForQueryBySku;
33+
2934
/**
3035
* @inheritdoc
3136
*/
@@ -34,6 +39,7 @@ protected function setUp()
3439
$objectManager = Bootstrap::getObjectManager();
3540
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
3641
$this->productCustomOptionsRepository = $objectManager->get(ProductCustomOptionRepositoryInterface::class);
42+
$this->getCustomOptionsValuesForQueryBySku = $objectManager->get(GetCustomOptionsValuesForQueryBySku::class);
3743
}
3844

3945
/**
@@ -49,7 +55,7 @@ public function testAddSimpleProductWithOptions()
4955
$quantity = 1;
5056
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
5157

52-
$customOptionsValues = $this->getCustomOptionsValuesForQuery($sku);
58+
$customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku);
5359
/* Generate customizable options fragment for GraphQl request */
5460
$queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
5561

@@ -135,41 +141,6 @@ private function getQuery(string $maskedQuoteId, string $sku, float $quantity, s
135141
QUERY;
136142
}
137143

138-
/**
139-
* Generate an array with test values for customizable options
140-
* based on the option type
141-
*
142-
* @param string $sku
143-
* @return array
144-
*/
145-
private function getCustomOptionsValuesForQuery(string $sku): array
146-
{
147-
$customOptions = $this->productCustomOptionsRepository->getList($sku);
148-
$customOptionsValues = [];
149-
150-
foreach ($customOptions as $customOption) {
151-
$optionType = $customOption->getType();
152-
if ($optionType == 'field' || $optionType == 'area') {
153-
$customOptionsValues[] = [
154-
'id' => (int)$customOption->getOptionId(),
155-
'value_string' => 'test'
156-
];
157-
} elseif ($optionType == 'drop_down') {
158-
$optionSelectValues = $customOption->getValues();
159-
$customOptionsValues[] = [
160-
'id' => (int)$customOption->getOptionId(),
161-
'value_string' => reset($optionSelectValues)->getOptionTypeId()
162-
];
163-
} elseif ($optionType == 'multiple') {
164-
$customOptionsValues[] = [
165-
'id' => (int)$customOption->getOptionId(),
166-
'value_string' => '[' . implode(',', array_keys($customOption->getValues())) . ']'
167-
];
168-
}
169-
}
170-
return $customOptionsValues;
171-
}
172-
173144
/**
174145
* Build the part of expected response.
175146
*

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

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class AddVirtualProductWithCustomOptionsToCartTest extends GraphQlAbstract
2626
*/
2727
private $productCustomOptionsRepository;
2828

29+
/**
30+
* @var GetCustomOptionsValuesForQueryBySku
31+
*/
32+
private $getCustomOptionsValuesForQueryBySku;
33+
2934
/**
3035
* @inheritdoc
3136
*/
@@ -34,6 +39,7 @@ protected function setUp()
3439
$objectManager = Bootstrap::getObjectManager();
3540
$this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
3641
$this->productCustomOptionsRepository = $objectManager->get(ProductCustomOptionRepositoryInterface::class);
42+
$this->getCustomOptionsValuesForQueryBySku = $objectManager->get(GetCustomOptionsValuesForQueryBySku::class);
3743
}
3844

3945
/**
@@ -49,7 +55,7 @@ public function testAddVirtualProductWithOptions()
4955
$quantity = 1;
5056
$maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1');
5157

52-
$customOptionsValues = $this->getCustomOptionsValuesForQuery($sku);
58+
$customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku);
5359
/* Generate customizable options fragment for GraphQl request */
5460
$queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues));
5561

@@ -135,42 +141,6 @@ private function getQuery(string $maskedQuoteId, string $sku, float $quantity, s
135141
QUERY;
136142
}
137143

138-
/**
139-
* Generate an array with test values for customizable options
140-
* based on the option type
141-
*
142-
* @param string $sku
143-
* @return array
144-
*/
145-
private function getCustomOptionsValuesForQuery(string $sku): array
146-
{
147-
$customOptions = $this->productCustomOptionsRepository->getList($sku);
148-
$customOptionsValues = [];
149-
150-
foreach ($customOptions as $customOption) {
151-
$optionType = $customOption->getType();
152-
if ($optionType == 'field' || $optionType == 'area') {
153-
$customOptionsValues[] = [
154-
'id' => (int)$customOption->getOptionId(),
155-
'value_string' => 'test'
156-
];
157-
} elseif ($optionType == 'drop_down') {
158-
$optionSelectValues = $customOption->getValues();
159-
$customOptionsValues[] = [
160-
'id' => (int)$customOption->getOptionId(),
161-
'value_string' => reset($optionSelectValues)->getOptionTypeId()
162-
];
163-
} elseif ($optionType == 'multiple') {
164-
$customOptionsValues[] = [
165-
'id' => (int)$customOption->getOptionId(),
166-
'value_string' => '[' . implode(',', array_keys($customOption->getValues())) . ']'
167-
];
168-
}
169-
}
170-
171-
return $customOptionsValues;
172-
}
173-
174144
/**
175145
* Build the part of expected response.
176146
*

0 commit comments

Comments
 (0)