1212use Magento \Quote \Model \Quote ;
1313use Magento \Quote \Model \QuoteIdToMaskedQuoteIdInterface ;
1414use Magento \Quote \Model \ResourceModel \Quote as QuoteResource ;
15+ use Magento \Catalog \Api \ProductCustomOptionRepositoryInterface ;
1516
1617class AddSimpleProductToCartTest extends GraphQlAbstract
1718{
@@ -30,6 +31,11 @@ class AddSimpleProductToCartTest extends GraphQlAbstract
3031 */
3132 private $ quoteIdToMaskedId ;
3233
34+ /**
35+ * @var ProductCustomOptionRepositoryInterface
36+ */
37+ private $ productCustomOptionsRepository ;
38+
3339 /**
3440 * @inheritdoc
3541 */
@@ -39,6 +45,79 @@ protected function setUp()
3945 $ this ->quoteResource = $ objectManager ->get (QuoteResource::class);
4046 $ this ->quote = $ objectManager ->create (Quote::class);
4147 $ this ->quoteIdToMaskedId = $ objectManager ->get (QuoteIdToMaskedQuoteIdInterface::class);
48+ $ this ->productCustomOptionsRepository = $ objectManager ->get (ProductCustomOptionRepositoryInterface::class);
49+ }
50+
51+ /**
52+ * Test adding a simple product to the shopping cart with all supported
53+ * customizable options assigned
54+ *
55+ * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_options.php
56+ * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
57+ */
58+ public function testAddSimpleProductWithOptions ()
59+ {
60+ $ sku = 'simple ' ;
61+ $ qty = 1 ;
62+
63+ $ customOptionsValues = $ this ->getCustomOptionsValuesForQuery ($ sku );
64+
65+ /* Generate customizable options fragment for GraphQl request */
66+ $ queryCustomizableOptions = preg_replace ('/"([^"]+)"\s*:\s*/ ' , '$1: ' , json_encode ($ customOptionsValues ));
67+
68+ $ this ->quoteResource ->load (
69+ $ this ->quote ,
70+ 'test_order_1 ' ,
71+ 'reserved_order_id '
72+ );
73+
74+ $ maskedQuoteId = $ this ->quoteIdToMaskedId ->execute ((int )$ this ->quote ->getId ());
75+
76+ $ query = <<<QUERY
77+ mutation {
78+ addSimpleProductsToCart(
79+ input: {
80+ cart_id: " {$ maskedQuoteId }",
81+ cartItems: [
82+ {
83+ data: {
84+ qty: $ qty
85+ sku: " $ sku"
86+ },
87+ customizable_options: $ queryCustomizableOptions
88+ }
89+ ]
90+ }
91+ ) {
92+ cart {
93+ items {
94+ ... on SimpleCartItem {
95+ customizable_options {
96+ label
97+ values {
98+ value
99+ }
100+ }
101+ }
102+ }
103+ }
104+ }
105+ }
106+ QUERY ;
107+
108+ $ response = $ this ->graphQlQuery ($ query );
109+
110+ self ::assertArrayHasKey ('items ' , $ response ['addSimpleProductsToCart ' ]['cart ' ]);
111+ self ::assertCount (1 , $ response ['addSimpleProductsToCart ' ]['cart ' ]);
112+
113+ $ customizableOptionsOutput = $ response ['addSimpleProductsToCart ' ]['cart ' ]['items ' ][0 ]['customizable_options ' ];
114+ $ assignedOptionsCount = count ($ customOptionsValues );
115+ for ($ counter = 0 ; $ counter < $ assignedOptionsCount ; $ counter ++) {
116+ self ::assertEquals (
117+ $ customOptionsValues [$ counter ]['value ' ],
118+ $ customizableOptionsOutput [$ counter ]['values ' ][0 ]['value ' ]
119+ );
120+ }
42121 }
43122
44123 /**
@@ -83,4 +162,92 @@ public function testAddProductIfQuantityIsNotAvailable()
83162
84163 $ this ->graphQlQuery ($ query );
85164 }
165+
166+ /**
167+ * Test adding a simple product with empty values for required options
168+ *
169+ * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_options.php
170+ * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
171+ */
172+ public function testAddSimpleProductWithNoRequiredOptionsSet ()
173+ {
174+ $ sku = 'simple ' ;
175+ $ qty = 1 ;
176+
177+ $ this ->quoteResource ->load (
178+ $ this ->quote ,
179+ 'test_order_1 ' ,
180+ 'reserved_order_id '
181+ );
182+
183+ $ maskedQuoteId = $ this ->quoteIdToMaskedId ->execute ((int )$ this ->quote ->getId ());
184+
185+ $ query = <<<QUERY
186+ mutation {
187+ addSimpleProductsToCart(
188+ input: {
189+ cart_id: " {$ maskedQuoteId }",
190+ cartItems: [
191+ {
192+ data: {
193+ qty: $ qty
194+ sku: " $ sku"
195+ }
196+ }
197+ ]
198+ }
199+ ) {
200+ cart {
201+ items {
202+ ... on SimpleCartItem {
203+ customizable_options {
204+ label
205+ values {
206+ value
207+ }
208+ }
209+ }
210+ }
211+ }
212+ }
213+ }
214+ QUERY ;
215+
216+ self ::expectExceptionMessage (
217+ 'The product \'s required option(s) weren \'t entered. Make sure the options are entered and try again. '
218+ );
219+
220+ $ this ->graphQlQuery ($ query );
221+ }
222+
223+ /**
224+ * Generate an array with test values for customizable options
225+ * based on the option type
226+ *
227+ * @param string $sku
228+ * @return array
229+ */
230+ private function getCustomOptionsValuesForQuery (string $ sku ): array
231+ {
232+ $ customOptions = $ this ->productCustomOptionsRepository ->getList ($ sku );
233+ $ customOptionsValues = [];
234+
235+ foreach ($ customOptions as $ customOption ) {
236+ $ optionType = $ customOption ->getType ();
237+ if ($ optionType == 'field ' || $ optionType == 'area ' ) {
238+ $ customOptionsValues [] = [
239+ 'id ' => (int ) $ customOption ->getOptionId (),
240+ 'value ' => 'test '
241+ ];
242+ } elseif ($ optionType == 'drop_down ' ) {
243+ $ optionSelectValues = $ customOption ->getValues ();
244+ $ customOptionsValues [] = [
245+ 'id ' => (int ) $ customOption ->getOptionId (),
246+ 'value ' => reset ($ optionSelectValues )->getOptionTypeId ()
247+ ];
248+ }
249+ }
250+
251+ return $ customOptionsValues ;
252+ }
86253}
0 commit comments