3
3
* Copyright © Magento, Inc. All rights reserved.
4
4
* See COPYING.txt for license details.
5
5
*/
6
+
6
7
namespace Magento \ConfigurableProduct \Api ;
7
8
8
9
use Magento \Catalog \Api \Data \ProductInterface ;
9
10
use Magento \Catalog \Api \ProductRepositoryInterface ;
10
11
use Magento \Catalog \Model \Entity \Attribute ;
12
+ use Magento \ConfigurableProduct \Model \Product \Type \Configurable ;
11
13
use Magento \Eav \Model \Config ;
12
14
use Magento \Eav \Model \ResourceModel \Entity \Attribute \Option \Collection ;
13
15
use Magento \Framework \Api \ExtensibleDataInterface ;
14
16
use Magento \Framework \ObjectManagerInterface ;
15
17
use Magento \Framework \Webapi \Rest \Request ;
16
18
use Magento \TestFramework \Helper \Bootstrap ;
17
- use Magento \ConfigurableProduct \Model \Product \Type \Configurable ;
18
19
use Magento \TestFramework \TestCase \WebapiAbstract ;
19
20
20
21
/**
@@ -102,18 +103,18 @@ protected function createConfigurableProduct()
102
103
103
104
$ configurableProductOptions = [
104
105
[
105
- "attribute_id " => $ this ->configurableAttribute ->getId (),
106
+ "attribute_id " => $ this ->configurableAttribute ->getId (),
106
107
"label " => $ label ,
107
108
"position " => 0 ,
108
109
"values " => [
109
110
[
110
- "value_index " => $ options [0 ]['option_id ' ],
111
+ "value_index " => $ options [0 ]['option_id ' ],
111
112
],
112
113
[
113
- "value_index " => $ options [1 ]['option_id ' ],
114
- ]
114
+ "value_index " => $ options [1 ]['option_id ' ],
115
+ ],
115
116
],
116
- ]
117
+ ],
117
118
];
118
119
119
120
$ product = [
@@ -173,6 +174,20 @@ public function testCreateConfigurableProduct()
173
174
$ this ->assertEquals ([$ productId1 , $ productId2 ], $ resultConfigurableProductLinks );
174
175
}
175
176
177
+ /**
178
+ * Verify configurable product creation passes validation with required attribute not specified in product itself.
179
+ *
180
+ * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
181
+ */
182
+ public function testCreateConfigurableProductWithRequiredAttribute (): void
183
+ {
184
+ $ configurableAttribute = $ this ->eavConfig ->getAttribute ('catalog_product ' , 'test_configurable ' );
185
+ $ configurableAttribute ->setIsRequired (true );
186
+ $ configurableAttribute ->save ();
187
+ $ response = $ this ->createConfigurableProductWithRequiredAttribute ();
188
+ $ this ->assertEquals (self ::CONFIGURABLE_PRODUCT_SKU , $ response [ProductInterface::SKU ]);
189
+ }
190
+
176
191
/**
177
192
* Create configurable with simple which has zero attribute value
178
193
*
@@ -340,10 +355,10 @@ public function testUpdateConfigurableProductLinks()
340
355
= [$ productId1 , $ productId2 ];
341
356
//set the value for required attribute
342
357
$ response ["custom_attributes " ][] =
343
- [
344
- "attribute_code " => $ this ->configurableAttribute ->getAttributeCode (),
345
- "value " => $ resultConfigurableProductOptions [0 ]['values ' ][0 ]['value_index ' ],
346
- ];
358
+ [
359
+ "attribute_code " => $ this ->configurableAttribute ->getAttributeCode (),
360
+ "value " => $ resultConfigurableProductOptions [0 ]['values ' ][0 ]['value_index ' ],
361
+ ];
347
362
348
363
$ response = $ this ->saveProduct ($ response );
349
364
@@ -364,7 +379,8 @@ public function testUpdateConfigurableProductLinksWithNonExistingProduct()
364
379
//leave existing option untouched
365
380
unset($ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_options ' ]);
366
381
$ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_links ' ] = [
367
- $ productId1 , $ nonExistingId
382
+ $ productId1 ,
383
+ $ nonExistingId ,
368
384
];
369
385
370
386
$ expectedMessage = 'The product that was requested doesn \'t exist. Verify the product and try again. ' ;
@@ -400,14 +416,15 @@ public function testUpdateConfigurableProductLinksWithDuplicateAttributes()
400
416
[
401
417
'attribute_code ' => 'test_configurable ' ,
402
418
'value ' => $ optionValue1 ,
403
- ]
419
+ ],
404
420
];
405
421
$ this ->saveProduct ($ product2 );
406
422
407
423
//leave existing option untouched
408
424
unset($ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_options ' ]);
409
425
$ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_links ' ] = [
410
- $ productId1 , $ productId2
426
+ $ productId1 ,
427
+ $ productId2 ,
411
428
];
412
429
413
430
$ expectedMessage = 'Products "%1" and "%2" have the same set of attribute values. ' ;
@@ -440,7 +457,8 @@ public function testUpdateConfigurableProductLinksWithWithoutVariationAttributes
440
457
/** delete all variation attribute */
441
458
$ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_options ' ] = [];
442
459
$ response [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY ]['configurable_product_links ' ] = [
443
- $ productId1 , $ productId2
460
+ $ productId1 ,
461
+ $ productId2 ,
444
462
];
445
463
446
464
$ expectedMessage = 'The product that was requested doesn \'t exist. Verify the product and try again. ' ;
@@ -496,7 +514,7 @@ protected function createProduct($product)
496
514
$ serviceInfo = [
497
515
'rest ' => [
498
516
'resourcePath ' => self ::RESOURCE_PATH ,
499
- 'httpMethod ' => Request::HTTP_METHOD_POST
517
+ 'httpMethod ' => Request::HTTP_METHOD_POST ,
500
518
],
501
519
'soap ' => [
502
520
'service ' => self ::SERVICE_NAME ,
@@ -521,7 +539,7 @@ protected function deleteProductBySku($productSku)
521
539
$ serviceInfo = [
522
540
'rest ' => [
523
541
'resourcePath ' => $ resourcePath ,
524
- 'httpMethod ' => Request::HTTP_METHOD_DELETE
542
+ 'httpMethod ' => Request::HTTP_METHOD_DELETE ,
525
543
],
526
544
'soap ' => [
527
545
'service ' => self ::SERVICE_NAME ,
@@ -544,7 +562,7 @@ protected function saveProduct($product)
544
562
{
545
563
if (isset ($ product ['custom_attributes ' ])) {
546
564
$ count = count ($ product ['custom_attributes ' ]);
547
- for ($ i= 0 ; $ i < $ count ; $ i ++) {
565
+ for ($ i = 0 ; $ i < $ count ; $ i ++) {
548
566
if ($ product ['custom_attributes ' ][$ i ]['attribute_code ' ] == 'category_ids '
549
567
&& !is_array ($ product ['custom_attributes ' ][$ i ]['value ' ])
550
568
) {
@@ -556,7 +574,7 @@ protected function saveProduct($product)
556
574
$ serviceInfo = [
557
575
'rest ' => [
558
576
'resourcePath ' => $ resourcePath ,
559
- 'httpMethod ' => Request::HTTP_METHOD_PUT
577
+ 'httpMethod ' => Request::HTTP_METHOD_PUT ,
560
578
],
561
579
'soap ' => [
562
580
'service ' => self ::SERVICE_NAME ,
@@ -568,4 +586,43 @@ protected function saveProduct($product)
568
586
$ response = $ this ->_webApiCall ($ serviceInfo , $ requestData );
569
587
return $ response ;
570
588
}
589
+
590
+ /**
591
+ * Create configurable product with required attribute by web api.
592
+ *
593
+ * @return array
594
+ */
595
+ private function createConfigurableProductWithRequiredAttribute (): array
596
+ {
597
+ $ this ->configurableAttribute = $ this ->eavConfig ->getAttribute ('catalog_product ' , 'test_configurable ' );
598
+ $ options = $ this ->getConfigurableAttributeOptions ();
599
+ $ configurableProductOptions = [
600
+ [
601
+ "attribute_id " => $ this ->configurableAttribute ->getId (),
602
+ "label " => 'color ' ,
603
+ "position " => 0 ,
604
+ "values " => [
605
+ [
606
+ "value_index " => $ options [0 ]['option_id ' ],
607
+ ],
608
+ [
609
+ "value_index " => $ options [1 ]['option_id ' ],
610
+ ],
611
+ ],
612
+ ],
613
+ ];
614
+ $ product = [
615
+ "sku " => self ::CONFIGURABLE_PRODUCT_SKU ,
616
+ "name " => self ::CONFIGURABLE_PRODUCT_SKU ,
617
+ "type_id " => "configurable " ,
618
+ "price " => 50 ,
619
+ 'attribute_set_id ' => 4 ,
620
+ "extension_attributes " => [
621
+ "configurable_product_options " => $ configurableProductOptions ,
622
+ "configurable_product_links " => [10 , 20 ],
623
+ ],
624
+ ];
625
+
626
+ return $ this ->createProduct ($ product );
627
+ }
571
628
}
0 commit comments