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,114 @@ 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+ $ store1 = $ this ->fixtures ->get ('store1 ' );
110+ $ store2 = $ this ->fixtures ->get ('store2 ' );
111+ $ attributeCode = $ this ->fixtures ->get ('multi_store_attr ' )->getAttributeCode ();
112+ $ attributeLabel = 'Multi Store Option ' ;
113+ $ store1Label = 'Store 1 Label ' ;
114+ $ store2Label = 'Store 2 Label ' ;
115+ $ store1LabelUpdated = 'Store 1 Label Updated ' ;
116+
117+ // First, create an option with multiple store labels
118+ $ initialOptionData = [
119+ AttributeOptionInterface::LABEL => $ attributeLabel ,
120+ AttributeOptionInterface::STORE_LABELS => [
121+ [
122+ AttributeOptionLabelInterface::LABEL => $ store1Label ,
123+ AttributeOptionLabelInterface::STORE_ID => $ store1 ->getId (),
124+ ],
125+ [
126+ AttributeOptionLabelInterface::LABEL => $ store2Label ,
127+ AttributeOptionLabelInterface::STORE_ID => $ store2 ->getId (),
128+ ],
129+ ],
130+ ];
131+
132+ // Add the option first
133+ $ newOptionId = $ this ->webApiCallAttributeOptions (
134+ $ attributeCode ,
135+ Request::HTTP_METHOD_POST ,
136+ 'add ' ,
137+ [
138+ 'attributeCode ' => $ attributeCode ,
139+ 'option ' => $ initialOptionData ,
140+ ]
141+ );
142+ $ this ->assertNotNull ($ newOptionId , 'Option should be created successfully ' );
143+
144+ // Now update only the first store label
145+ $ updateOptionData = [
146+ AttributeOptionInterface::LABEL => $ attributeLabel ,
147+ AttributeOptionInterface::VALUE => $ newOptionId ,
148+ AttributeOptionInterface::STORE_LABELS => [
149+ [
150+ AttributeOptionLabelInterface::LABEL => $ store1LabelUpdated ,
151+ AttributeOptionLabelInterface::STORE_ID => $ store1 ->getId (),
152+ ],
153+ ],
154+ ];
155+
156+ $ response = $ this ->webApiCallAttributeOptions (
157+ $ attributeCode ,
158+ Request::HTTP_METHOD_PUT ,
159+ 'update ' ,
160+ [
161+ 'attributeCode ' => $ attributeCode ,
162+ 'optionId ' => $ newOptionId ,
163+ 'option ' => $ updateOptionData ,
164+ ],
165+ $ newOptionId
166+ );
167+ $ this ->assertTrue ($ response , 'Update should be successful ' );
168+
169+ // Test store labels preservation by checking labels in different store contexts
170+ // This verifies that the fix for preserving store labels is working correctly
171+ $ store1Options = $ this ->getAttributeOptions ($ attributeCode , $ store1 ->getCode ());
172+ $ store2Options = $ this ->getAttributeOptions ($ attributeCode , $ store2 ->getCode ());
173+
174+ // Find the option in store1 context
175+ $ store1Option = null ;
176+ foreach ($ store1Options as $ option ) {
177+ if ($ option ['value ' ] === $ newOptionId ) {
178+ $ store1Option = $ option ;
179+ break ;
180+ }
181+ }
182+ // Find the option in store2 context
183+ $ store2Option = null ;
184+ foreach ($ store2Options as $ option ) {
185+ if ($ option ['value ' ] === $ newOptionId ) {
186+ $ store2Option = $ option ;
187+ break ;
188+ }
189+ }
190+
191+ // Verify that store1 label was updated
192+ $ this ->assertNotNull ($ store1Option , 'Option should exist in store1 context ' );
193+ $ this ->assertEquals (
194+ $ store1LabelUpdated ,
195+ $ store1Option ['label ' ],
196+ 'Store1 label should be updated '
197+ );
198+
199+ // Verify that store2 label was preserved
200+ $ this ->assertNotNull ($ store2Option , 'Option should exist in store2 context ' );
201+ $ this ->assertEquals (
202+ $ store2Label ,
203+ $ store2Option ['label ' ],
204+ 'Store2 label should be preserved '
205+ );
206+ }
207+
70208 /**
71209 * Test to update option with already exist exception
72210 *
0 commit comments