11<?php
22/**
3- * Copyright © Magento, Inc. All rights reserved.
4- * See COPYING.txt for license details .
3+ * Copyright 2020 Adobe
4+ * All Rights Reserved .
55 */
6+
67namespace Magento \Catalog \Api ;
78
9+ use Magento \Catalog \Test \Fixture \SelectAttribute as SelectAttributeFixture ;
810use Magento \Eav \Api \Data \AttributeOptionInterface ;
911use Magento \Eav \Api \Data \AttributeOptionLabelInterface ;
1012use Magento \Framework \Webapi \Rest \Request ;
13+ use Magento \Store \Test \Fixture \Group as StoreGroupFixture ;
14+ use Magento \Store \Test \Fixture \Store as StoreFixture ;
15+ use Magento \Store \Test \Fixture \Website as WebsiteFixture ;
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 \ObjectManager ;
1121use Magento \TestFramework \TestCase \WebapiAbstract ;
1222
1323/**
@@ -20,6 +30,26 @@ class ProductAttributeOptionUpdateInterfaceTest extends WebapiAbstract
2030 private const SERVICE_VERSION = 'V1 ' ;
2131 private const RESOURCE_PATH = '/V1/products/attributes ' ;
2232
33+ /**
34+ * @var ObjectManager
35+ */
36+ private $ objectManager ;
37+
38+ /**
39+ * @var DataFixtureStorage
40+ */
41+ private $ fixtures ;
42+
43+ /**
44+ * @inheritdoc
45+ */
46+ protected function setUp (): void
47+ {
48+ parent ::setUp ();
49+ $ this ->objectManager = Bootstrap::getObjectManager ();
50+ $ this ->fixtures = $ this ->objectManager ->get (DataFixtureStorageManager::class)->getStorage ();
51+ }
52+
2353 /**
2454 * Test to update attribute option
2555 *
@@ -67,6 +97,110 @@ public function testUpdate()
6797 }
6898 }
6999
100+ #[
101+ DataFixture(WebsiteFixture::class, as: 'website ' ),
102+ DataFixture(StoreGroupFixture::class, ['website_id ' => '$website.id$ ' ], 'store_group ' ),
103+ DataFixture(StoreFixture::class, ['store_group_id ' => '$store_group.id$ ' ], 'store1 ' ),
104+ DataFixture(StoreFixture::class, ['store_group_id ' => '$store_group.id$ ' ], 'store2 ' ),
105+ DataFixture(SelectAttributeFixture::class, ['default_frontend_label ' => 'CustomAttr ' ], 'multi_store_attr ' ),
106+ ]
107+ public function testUpdateMultistorePreservingOtherStoreLabel ()
108+ {
109+ $ this ->_markTestAsRestOnly ('Fix inconsistencies in WSDL and Data interfaces ' );
110+ $ store1 = $ this ->fixtures ->get ('store1 ' );
111+ $ store2 = $ this ->fixtures ->get ('store2 ' );
112+ $ attributeCode = $ this ->fixtures ->get ('multi_store_attr ' )->getAttributeCode ();
113+ $ attributeLabel = 'Multi Store Option ' ;
114+ $ store1Label = 'Store 1 Label ' ;
115+ $ store2Label = 'Store 2 Label ' ;
116+ $ store1LabelUpdated = 'Store 1 Label Updated ' ;
117+
118+ // First, create an option with multiple store labels and add the option
119+ $ initialOptionData = [
120+ AttributeOptionInterface::LABEL => $ attributeLabel ,
121+ AttributeOptionInterface::STORE_LABELS => [
122+ [
123+ AttributeOptionLabelInterface::LABEL => $ store1Label ,
124+ AttributeOptionLabelInterface::STORE_ID => $ store1 ->getId (),
125+ ],
126+ [
127+ AttributeOptionLabelInterface::LABEL => $ store2Label ,
128+ AttributeOptionLabelInterface::STORE_ID => $ store2 ->getId (),
129+ ],
130+ ],
131+ ];
132+ $ newOptionId = $ this ->webApiCallAttributeOptions (
133+ $ attributeCode ,
134+ Request::HTTP_METHOD_POST ,
135+ 'add ' ,
136+ [
137+ 'attributeCode ' => $ attributeCode ,
138+ 'option ' => $ initialOptionData ,
139+ ]
140+ );
141+ $ this ->assertNotNull ($ newOptionId , 'Option should be created successfully ' );
142+
143+ // Now update only the first store label
144+ $ updateOptionData = [
145+ AttributeOptionInterface::LABEL => $ attributeLabel ,
146+ AttributeOptionInterface::VALUE => $ newOptionId ,
147+ AttributeOptionInterface::STORE_LABELS => [
148+ [
149+ AttributeOptionLabelInterface::LABEL => $ store1LabelUpdated ,
150+ AttributeOptionLabelInterface::STORE_ID => $ store1 ->getId (),
151+ ],
152+ ],
153+ ];
154+ $ response = $ this ->webApiCallAttributeOptions (
155+ $ attributeCode ,
156+ Request::HTTP_METHOD_PUT ,
157+ 'update ' ,
158+ [
159+ 'attributeCode ' => $ attributeCode ,
160+ 'optionId ' => $ newOptionId ,
161+ 'option ' => $ updateOptionData ,
162+ ],
163+ $ newOptionId
164+ );
165+ $ this ->assertTrue ($ response , 'Update should be successful ' );
166+
167+ $ store1Options = $ this ->getAttributeOptions ($ attributeCode , $ store1 ->getCode ());
168+ $ store2Options = $ this ->getAttributeOptions ($ attributeCode , $ store2 ->getCode ());
169+
170+ // Find the option in store1 context
171+ $ store1Option = null ;
172+ foreach ($ store1Options as $ option ) {
173+ if ($ option ['value ' ] === $ newOptionId ) {
174+ $ store1Option = $ option ;
175+ break ;
176+ }
177+ }
178+ // Find the option in store2 context
179+ $ store2Option = null ;
180+ foreach ($ store2Options as $ option ) {
181+ if ($ option ['value ' ] === $ newOptionId ) {
182+ $ store2Option = $ option ;
183+ break ;
184+ }
185+ }
186+
187+ // Verify that store1 label was updated
188+ $ this ->assertNotNull ($ store1Option , 'Option should exist in store1 context ' );
189+ $ this ->assertEquals (
190+ $ store1LabelUpdated ,
191+ $ store1Option ['label ' ],
192+ 'Store1 label should be updated '
193+ );
194+
195+ // Verify that store2 label was preserved
196+ $ this ->assertNotNull ($ store2Option , 'Option should exist in store2 context ' );
197+ $ this ->assertEquals (
198+ $ store2Label ,
199+ $ store2Option ['label ' ],
200+ 'Store2 label should be preserved '
201+ );
202+ }
203+
70204 /**
71205 * Test to update option with already exist exception
72206 *
0 commit comments