@@ -254,6 +254,130 @@ public function testCachePurgedWithStoreScopeConfigChange(): void
254254 $ this ->assertEquals ($ newLocale , $ secondStoreResponseHitResult ['locale ' ]);
255255 }
256256
257+ /**
258+ * Website scope config change triggers purging only the cache of the stores associated with the changed website.
259+ *
260+ * Test stores set up:
261+ * STORE - WEBSITE - STORE GROUP
262+ * default - base - main_website_store
263+ * second_store_view - second - second_store
264+ * third_store_view - second - third_store
265+ *
266+ * @magentoConfigFixture default/system/full_page_cache/caching_application 2
267+ * @magentoApiDataFixture Magento/Store/_files/multiple_websites_with_store_groups_stores.php
268+ * @throws NoSuchEntityException
269+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
270+ */
271+ public function testCachePurgedWithWebsiteScopeConfigChange (): void
272+ {
273+ $ this ->changeToTwoWebsitesThreeStoreGroupsThreeStores ();
274+ $ defaultLocale = $ this ->defaultStoreConfig ->getLocale ();
275+ $ query = $ this ->getQuery ();
276+
277+ // Query default store config
278+ $ responseDefaultStore = $ this ->graphQlQueryWithResponseHeaders ($ query );
279+ $ defaultStoreCacheId = $ responseDefaultStore ['headers ' ][CacheIdCalculator::CACHE_ID_HEADER ];
280+ // Verify we obtain a cache MISS at the 1st time
281+ $ this ->assertCacheMissAndReturnResponse (
282+ $ query ,
283+ [CacheIdCalculator::CACHE_ID_HEADER => $ defaultStoreCacheId ]
284+ );
285+
286+ // Query second store config
287+ $ secondStoreCode = 'second_store_view ' ;
288+ $ responseThirdStore = $ this ->graphQlQueryWithResponseHeaders (
289+ $ query ,
290+ [],
291+ '' ,
292+ ['Store ' => $ secondStoreCode ]
293+ );
294+ $ secondStoreCacheId = $ responseThirdStore ['headers ' ][CacheIdCalculator::CACHE_ID_HEADER ];
295+ // Verify we obtain a cache MISS at the 1st time
296+ $ secondStoreResponse = $ this ->assertCacheMissAndReturnResponse (
297+ $ query ,
298+ [
299+ CacheIdCalculator::CACHE_ID_HEADER => $ secondStoreCacheId ,
300+ 'Store ' => $ secondStoreCode
301+ ]
302+ );
303+ $ this ->assertEquals ($ defaultLocale , $ secondStoreResponse ['body ' ]['storeConfig ' ]['locale ' ]);
304+
305+ // Query third store config
306+ $ thirdStoreCode = 'third_store_view ' ;
307+ $ responseThirdStore = $ this ->graphQlQueryWithResponseHeaders (
308+ $ query ,
309+ [],
310+ '' ,
311+ ['Store ' => $ thirdStoreCode ]
312+ );
313+ $ thirdStoreCacheId = $ responseThirdStore ['headers ' ][CacheIdCalculator::CACHE_ID_HEADER ];
314+ // Verify we obtain a cache MISS at the 1st time
315+ $ thirdStoreResponse = $ this ->assertCacheMissAndReturnResponse (
316+ $ query ,
317+ [
318+ CacheIdCalculator::CACHE_ID_HEADER => $ thirdStoreCacheId ,
319+ 'Store ' => $ thirdStoreCode
320+ ]
321+ );
322+ $ this ->assertEquals ($ defaultLocale , $ thirdStoreResponse ['body ' ]['storeConfig ' ]['locale ' ]);
323+
324+ // Change second website locale
325+ $ localeConfigPath = 'general/locale/code ' ;
326+ $ newLocale = 'de_DE ' ;
327+ $ this ->setConfig ($ localeConfigPath , $ newLocale , ScopeInterface::SCOPE_WEBSITES , 'second ' );
328+
329+ // Query default store config after second store group is changed
330+ // Verify we obtain a cache HIT at the 2nd time, the cache is not purged
331+ $ this ->assertCacheHitAndReturnResponse (
332+ $ query ,
333+ [CacheIdCalculator::CACHE_ID_HEADER => $ defaultStoreCacheId ]
334+ );
335+
336+ // Query second store config after the config of its associated second website is changed
337+ // Verify we obtain a cache MISS at the 2nd time, the cache is purged
338+ $ secondStoreResponseMiss = $ this ->assertCacheMissAndReturnResponse (
339+ $ query ,
340+ [
341+ CacheIdCalculator::CACHE_ID_HEADER => $ secondStoreCacheId ,
342+ 'Store ' => $ secondStoreCode
343+ ]
344+ );
345+ $ this ->assertEquals (
346+ $ newLocale ,
347+ $ secondStoreResponseMiss ['body ' ]['storeConfig ' ]['locale ' ]
348+ );
349+ // Verify we obtain a cache HIT at the 3rd time
350+ $ this ->assertCacheHitAndReturnResponse (
351+ $ query ,
352+ [
353+ CacheIdCalculator::CACHE_ID_HEADER => $ secondStoreCacheId ,
354+ 'Store ' => $ secondStoreCode
355+ ]
356+ );
357+
358+ // Query third store config after the config of its associated second website is changed
359+ // Verify we obtain a cache MISS at the 2nd time, the cache is purged
360+ $ thirdStoreResponseMiss = $ this ->assertCacheMissAndReturnResponse (
361+ $ query ,
362+ [
363+ CacheIdCalculator::CACHE_ID_HEADER => $ thirdStoreCacheId ,
364+ 'Store ' => $ thirdStoreCode
365+ ]
366+ );
367+ $ this ->assertEquals (
368+ $ newLocale ,
369+ $ thirdStoreResponseMiss ['body ' ]['storeConfig ' ]['locale ' ]
370+ );
371+ // Verify we obtain a cache HIT at the 3rd time
372+ $ this ->assertCacheHitAndReturnResponse (
373+ $ query ,
374+ [
375+ CacheIdCalculator::CACHE_ID_HEADER => $ thirdStoreCacheId ,
376+ 'Store ' => $ thirdStoreCode
377+ ]
378+ );
379+ }
380+
257381 /**
258382 * Store change triggers purging only the cache of the changed store.
259383 *
@@ -617,6 +741,23 @@ private function changeToOneWebsiteTwoStoreGroupsThreeStores()
617741 $ store3 ->setGroupId ($ store2GroupId )->setWebsiteId (1 )->save ();
618742 }
619743
744+ private function changeToTwoWebsitesThreeStoreGroupsThreeStores ()
745+ {
746+ /** @var $website2 \Magento\Store\Model\Website */
747+ $ website2 = $ this ->objectManager ->create (Website::class);
748+ $ website2Id = $ website2 ->load ('second ' , 'code ' )->getId ();
749+
750+ // Change third store to the same website of second store
751+ /** @var Store $store3 */
752+ $ store3 = $ this ->objectManager ->create (Store::class);
753+ $ store3 ->load ('third_store_view ' , 'code ' );
754+ $ store3GroupId = $ store3 ->getStoreGroupId ();
755+ /** @var Group $store3Group */
756+ $ store3Group = $ this ->objectManager ->create (Group::class);
757+ $ store3Group ->load ($ store3GroupId )->setWebsiteId ($ website2Id )->save ();
758+ $ store3 ->setWebsiteId ($ website2Id )->save ();
759+ }
760+
620761 /**
621762 * Get query
622763 *
0 commit comments