2121use Magento \Framework \App \ObjectManager \ConfigLoader ;
2222use Magento \Framework \App \State as AppState ;
2323use Magento \Framework \ObjectManagerInterface ;
24+ use Magento \GraphQl \Model \Query \ContextFactory ;
2425use Magento \GraphQlResolverCache \Model \Resolver \Result \CacheKey \Calculator \ProviderInterface ;
2526use Magento \GraphQlResolverCache \Model \Resolver \Result \Type as GraphQlResolverCache ;
2627use Magento \Integration \Api \IntegrationServiceInterface ;
2728use Magento \Integration \Model \Integration ;
29+ use Magento \Store \Api \Data \StoreInterface ;
30+ use Magento \Store \Model \StoreManagerInterface ;
31+ use Magento \Store \Test \Fixture \Store as StoreFixture ;
2832use Magento \TestFramework \Fixture \DataFixture ;
2933use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
3034use Magento \TestFramework \Helper \Bootstrap ;
@@ -56,6 +60,11 @@ class MediaGalleryTest extends ResolverCacheAbstract
5660 */
5761 private $ integration ;
5862
63+ /**
64+ * @var StoreManagerInterface
65+ */
66+ private $ storeManager ;
67+
5968 /**
6069 * @var DataFixtureStorageManager
6170 */
@@ -66,11 +75,19 @@ protected function setUp(): void
6675 $ this ->objectManager = Bootstrap::getObjectManager ();
6776 $ this ->graphQlResolverCache = $ this ->objectManager ->get (GraphQlResolverCache::class);
6877 $ this ->productRepository = $ this ->objectManager ->get (ProductRepositoryInterface::class);
78+ $ this ->storeManager = $ this ->objectManager ->get (StoreManagerInterface::class);
6979 $ this ->fixtures = DataFixtureStorageManager::getStorage ();
7080
7181 parent ::setUp ();
7282 }
7383
84+ protected function tearDown (): void
85+ {
86+ $ this ->storeManager ->setCurrentStore ('default ' );
87+
88+ parent ::tearDown ();
89+ }
90+
7491 #[
7592 DataFixture(ProductFixture::class, ['media_gallery_entries ' => [[]]], as: 'product ' ),
7693 ]
@@ -163,6 +180,86 @@ public function testSavingProductInAdminWithoutChangesDoesNotInvalidateResolverC
163180 $ this ->assertMediaGalleryResolverCacheRecordExists ($ product );
164181 }
165182
183+ #[
184+ DataFixture(StoreFixture::class, as: 'store2 ' ),
185+ DataFixture(
186+ ProductFixture::class,
187+ [
188+ 'media_gallery_entries ' => [[]]
189+ ],
190+ as: 'product '
191+ ),
192+ ]
193+ public function testResolverCacheRecordIsCreatedForEachStoreView ()
194+ {
195+ /** @var ProductInterface $product */
196+ $ product = $ this ->fixtures ->get ('product ' );
197+
198+ /** @var StoreInterface $store2 */
199+ $ store2 = $ this ->fixtures ->get ('store2 ' );
200+
201+ // Assert Media Gallery Resolver cache record does not exist before querying the product's media gallery
202+ $ this ->assertMediaGalleryResolverCacheRecordDoesNotExist ($ product );
203+
204+ $ query = $ this ->getProductWithMediaGalleryQuery ($ product );
205+
206+ // send 1 request for each store view
207+ $ responseInDefaultStoreView = $ this ->graphQlQuery ($ query );
208+ $ responseInSecondStoreView = $ this ->graphQlQuery ($ query , [], '' , ['Store ' => $ store2 ->getCode ()]);
209+
210+ $ this ->assertNotEmpty ($ responseInDefaultStoreView ['products ' ]['items ' ][0 ]['media_gallery ' ]);
211+ $ this ->assertNotEmpty ($ responseInSecondStoreView ['products ' ]['items ' ][0 ]['media_gallery ' ]);
212+
213+ // Assert Media Gallery Resolver cache record exists in default store
214+ $ cacheKeyInDefaultStoreView = $ this ->getCacheKeyForMediaGalleryResolver ($ product );
215+ $ this ->assertMediaGalleryResolverCacheRecordExists ($ product );
216+
217+ // Switch to second store view
218+ $ this ->storeManager ->setCurrentStore ($ store2 ->getCode ());
219+
220+ // reset query context so that new store id is taken into account
221+ $ contextFactory = $ this ->objectManager ->get (ContextFactory::class);
222+ $ contextFactory ->create ();
223+
224+ // Assert Media Gallery Resolver cache record exists in second store
225+ // Not using assertMediaGalleryResolverCacheRecordExists because label is not set in second store view
226+ $ cacheKeyInSecondStoreView = $ this ->getCacheKeyForMediaGalleryResolver ($ product );
227+ $ cacheEntryInSecondStoreView = $ this ->graphQlResolverCache ->load ($ cacheKeyInSecondStoreView );
228+
229+ $ this ->assertNotFalse (
230+ $ cacheEntryInSecondStoreView ,
231+ sprintf (
232+ 'Media gallery cache entry for product with sku "%s" in second store view does not exist ' ,
233+ $ product ->getSku ()
234+ )
235+ );
236+
237+ // Assert cache keys are different
238+ $ this ->assertNotEquals (
239+ $ cacheKeyInDefaultStoreView ,
240+ $ cacheKeyInSecondStoreView
241+ );
242+
243+ // change media gallery label and assert both cache entries are invalidated
244+ $ this ->actionMechanismProvider ()['update media label ' ][0 ]($ product );
245+
246+ $ this ->assertFalse (
247+ $ this ->graphQlResolverCache ->test ($ cacheKeyInDefaultStoreView ),
248+ sprintf (
249+ 'Media gallery cache entry for product with sku "%s" in default store view was not invalidated ' ,
250+ $ product ->getSku ()
251+ )
252+ );
253+
254+ $ this ->assertFalse (
255+ $ this ->graphQlResolverCache ->test ($ cacheKeyInSecondStoreView ),
256+ sprintf (
257+ 'Media gallery cache entry for product with sku "%s" in second store view was not invalidated ' ,
258+ $ product ->getSku ()
259+ )
260+ );
261+ }
262+
166263 /**
167264 * - product_simple_with_media_gallery_entries.php creates product with "simple" sku containing
168265 * link to 1 external YouTube video using an image placeholder in gallery
@@ -228,6 +325,10 @@ public function testMediaGalleryForProductVideos(callable $actionMechanismCallab
228325 }
229326 }
230327
328+ /**
329+ * @return array[]
330+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
331+ */
231332 public function actionMechanismProvider (): array
232333 {
233334 // provider is invoked before setUp() is called so need to init here
0 commit comments