diff --git a/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php b/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php
new file mode 100644
index 0000000000000..751fa3fdfad84
--- /dev/null
+++ b/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php
@@ -0,0 +1,60 @@
+cacheConfig = $cacheConfig;
+ $this->pageCache = $pageCache;
+ }
+
+ /**
+ * Clean the category page cache if built in cache page cache is used.
+ *
+ * The built in cache requires cleaning all pages that contain the top category navigation menu when a
+ * category is moved. This is because the built in cache does not support ESI blocks.
+ *
+ * @param Event $event
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function execute(Event $event)
+ {
+ if ($this->cacheConfig->getType() == CacheConfig::BUILT_IN && $this->cacheConfig->isEnabled()) {
+ $this->pageCache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, [Category::CACHE_TAG]);
+ }
+ }
+}
diff --git a/app/code/Magento/Catalog/etc/adminhtml/events.xml b/app/code/Magento/Catalog/etc/adminhtml/events.xml
index ad83f5898237a..ab1a8348d2904 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/events.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/events.xml
@@ -12,4 +12,7 @@
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php
new file mode 100644
index 0000000000000..3324da008a84a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php
@@ -0,0 +1,55 @@
+get(ObjectManagerConfig::class);
+ $argumentConfig = $diConfig->getArguments(\Magento\Framework\App\Cache\Frontend\Pool::class);
+
+ $pageCacheDir = $argumentConfig['frontendSettings']['page_cache']['backend_options']['cache_dir'] ?? null;
+ $defaultCacheDir = $argumentConfig['frontendSettings']['default']['backend_options']['cache_dir'] ?? null;
+
+ $noPageCacheMessage = "No default page_cache directory set in di.xml: \n" . var_export($argumentConfig, true);
+ $this->assertNotEmpty($pageCacheDir, $noPageCacheMessage);
+
+ $sameCacheDirMessage = 'The page_cache and default cache storages share the same cache directory';
+ $this->assertNotSame($pageCacheDir, $defaultCacheDir, $sameCacheDirMessage);
+ }
+
+ /**
+ * @covers \Magento\Framework\App\Cache\Frontend\Pool::_getCacheSettings
+ * @depends testPageCacheNotSameAsDefaultCacheDirectory
+ */
+ public function testCleaningDefaultCachePreservesPageCache()
+ {
+ $testData = 'test data';
+ $testKey = 'test-key';
+
+ /** @var \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool */
+ $cacheFrontendPool = ObjectManager::getInstance()->get(\Magento\Framework\App\Cache\Frontend\Pool::class);
+
+ $pageCache = $cacheFrontendPool->get('page_cache');
+ $pageCache->save($testData, $testKey);
+
+ $defaultCache = $cacheFrontendPool->get('default');
+ $defaultCache->clean();
+
+ $this->assertSame($testData, $pageCache->load($testKey));
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php
index f25144c308c68..862a924f65793 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php
@@ -7,9 +7,15 @@
namespace Magento\GraphQlCache\Controller;
-use PHPUnit\Framework\TestCase;
-use Magento\TestFramework\ObjectManager;
+use Magento\Framework\App\Request\Http as HttpRequest;
+use Magento\Framework\App\Response\HttpInterface as HttpResponse;
+use Magento\Framework\Registry;
+use Magento\GraphQl\Controller\GraphQl as GraphQlController;
+use Magento\GraphQlCache\Model\CacheableQuery;
+use Magento\PageCache\Model\Cache\Type as PageCache;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\ObjectManager;
+use PHPUnit\Framework\TestCase;
/**
* Abstract test class for Graphql cache tests
@@ -21,40 +27,114 @@ abstract class AbstractGraphqlCacheTest extends TestCase
*/
protected $objectManager;
- /**
- * @inheritdoc
- */
protected function setUp(): void
{
$this->objectManager = Bootstrap::getObjectManager();
+ $this->enablePageCachePlugin();
+ $this->enableCachebleQueryTestProxy();
+ }
+
+ protected function tearDown(): void
+ {
+ $this->disableCacheableQueryTestProxy();
+ $this->disablePageCachePlugin();
+ $this->flushPageCache();
+ }
+
+ protected function enablePageCachePlugin(): void
+ {
+ /** @var $registry Registry */
+ $registry = $this->objectManager->get(Registry::class);
+ $registry->register('use_page_cache_plugin', true, true);
+ }
+
+ protected function disablePageCachePlugin(): void
+ {
+ /** @var $registry Registry */
+ $registry = $this->objectManager->get(Registry::class);
+ $registry->unregister('use_page_cache_plugin');
+ }
+
+ protected function flushPageCache(): void
+ {
+ /** @var PageCache $fullPageCache */
+ $fullPageCache = $this->objectManager->get(PageCache::class);
+ $fullPageCache->clean();
}
/**
- * Prepare a query and return a request to be used in the same test end to end
+ * Regarding the SuppressWarnings annotation below: the nested class below triggers a false rule match.
*
- * @param string $query
- * @return \Magento\Framework\App\Request\Http
+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
- protected function prepareRequest(string $query) : \Magento\Framework\App\Request\Http
- {
- $cacheableQuery = $this->objectManager->get(\Magento\GraphQlCache\Model\CacheableQuery::class);
- $cacheableQueryReflection = new \ReflectionProperty(
- $cacheableQuery,
- 'cacheTags'
- );
- $cacheableQueryReflection->setAccessible(true);
- $cacheableQueryReflection->setValue($cacheableQuery, []);
-
- /** @var \Magento\Framework\UrlInterface $urlInterface */
- $urlInterface = $this->objectManager->create(\Magento\Framework\UrlInterface::class);
- //set unique URL
- $urlInterface->setQueryParam('query', $query);
-
- $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class);
- $request->setUri($urlInterface->getUrl('graphql'));
+ private function enableCachebleQueryTestProxy(): void
+ {
+ $cacheableQueryProxy = new class($this->objectManager) extends CacheableQuery {
+ /** @var CacheableQuery */
+ private $delegate;
+
+ public function __construct(ObjectManager $objectManager)
+ {
+ $this->reset($objectManager);
+ }
+
+ public function reset(ObjectManager $objectManager): void
+ {
+ $this->delegate = $objectManager->create(CacheableQuery::class);
+ }
+
+ public function getCacheTags(): array
+ {
+ return $this->delegate->getCacheTags();
+ }
+
+ public function addCacheTags(array $cacheTags): void
+ {
+ $this->delegate->addCacheTags($cacheTags);
+ }
+
+ public function isCacheable(): bool
+ {
+ return $this->delegate->isCacheable();
+ }
+
+ public function setCacheValidity(bool $cacheable): void
+ {
+ $this->delegate->setCacheValidity($cacheable);
+ }
+
+ public function shouldPopulateCacheHeadersWithTags(): bool
+ {
+ return $this->delegate->shouldPopulateCacheHeadersWithTags();
+ }
+ };
+ $this->objectManager->addSharedInstance($cacheableQueryProxy, CacheableQuery::class);
+ }
+
+ private function disableCacheableQueryTestProxy(): void
+ {
+ $this->resetQueryCacheTags();
+ $this->objectManager->removeSharedInstance(CacheableQuery::class);
+ }
+
+ protected function resetQueryCacheTags(): void
+ {
+ $this->objectManager->get(CacheableQuery::class)->reset($this->objectManager);
+ }
+
+ protected function dispatchGraphQlGETRequest(array $queryParams): HttpResponse
+ {
+ $this->resetQueryCacheTags();
+
+ /** @var HttpRequest $request */
+ $request = $this->objectManager->get(HttpRequest::class);
+ $request->setPathInfo('/graphql');
$request->setMethod('GET');
- //set the actual GET query
- $request->setQueryValue('query', $query);
- return $request;
+ $request->setParams($queryParams);
+
+ // required for \Magento\Framework\App\PageCache\Identifier to generate the correct cache key
+ $request->setUri(implode('?', [$request->getPathInfo(), http_build_query($queryParams)]));
+
+ return $this->objectManager->create(GraphQlController::class)->dispatch($request);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php
index fd97399992c1c..287353bbd2b80 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php
@@ -9,8 +9,6 @@
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
-use Magento\Framework\App\Request\Http;
-use Magento\GraphQl\Controller\GraphQl;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
@@ -22,31 +20,12 @@
*/
class CategoriesWithProductsCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
-
- /**
- * @var Http
- */
- private $request;
-
- /**
- * @inheritdoc
- */
- protected function setUp(): void
- {
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
- $this->request = $this->objectManager->create(Http::class);
- }
/**
* Test cache tags and debug header for category with products querying for products and category
*
* @magentoDataFixture Magento/Catalog/_files/category_product.php
*/
- public function testToCheckRequestCacheTagsForCategoryWithProducts(): void
+ public function testRequestCacheTagsForCategoryWithProducts(): void
{
/** @var ProductRepositoryInterface $productRepository */
$productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
@@ -91,17 +70,7 @@ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void
'operationName' => 'GetCategoryWithProducts'
];
- /** @var \Magento\Framework\UrlInterface $urlInterface */
- $urlInterface = $this->objectManager->create(\Magento\Framework\UrlInterface::class);
- //set unique URL
- $urlInterface->setQueryParam('query', $queryParams['query']);
- $urlInterface->setQueryParam('variables', $queryParams['variables']);
- $urlInterface->setQueryParam('operationName', $queryParams['operationName']);
- $this->request->setUri($urlInterface->getUrl('graphql'));
- $this->request->setPathInfo('/graphql');
- $this->request->setMethod('GET');
- $this->request->setParams($queryParams);
- $response = $this->graphqlController->dispatch($this->request);
+ $response = $this->dispatchGraphQlGETRequest($queryParams);
$this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
$expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC'];
$actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php
index be920fb200ff3..90bdc4f75825a 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php
@@ -7,8 +7,6 @@
namespace Magento\GraphQlCache\Controller\Catalog;
-use Magento\Framework\App\Request\Http;
-use Magento\GraphQl\Controller\GraphQl;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
@@ -20,25 +18,12 @@
*/
class CategoryCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
-
- /**
- * @inheritdoc
- */
- protected function setUp(): void
- {
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
- }
/**
* Test cache tags and debug header for category and querying only for category
*
* @magentoDataFixture Magento/Catalog/_files/category_product.php
*/
- public function testToCheckRequestCacheTagsForForCategory(): void
+ public function testRequestCacheTagsForCategory(): void
{
$categoryId ='333';
$query
@@ -53,11 +38,10 @@ public function testToCheckRequestCacheTagsForForCategory(): void
}
}
QUERY;
- $request = $this->prepareRequest($query);
- $response = $this->graphqlController->dispatch($request);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $query]);
$this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
$actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC'];
+ $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC'];
$this->assertEquals($expectedCacheTags, $actualCacheTags);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php
index 746b37a88770a..6228feae37c15 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php
@@ -9,7 +9,6 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\CategoryRepositoryInterface;
-use Magento\Framework\App\Request\Http;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
@@ -20,24 +19,11 @@
*/
class DeepNestedCategoriesAndProductsTest extends AbstractGraphqlCacheTest
{
- /** @var \Magento\GraphQl\Controller\GraphQl */
- private $graphql;
-
- /**
- * @inheritdoc
- */
- protected function setUp(): void
- {
- parent::setUp();
- $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
- }
-
/**
* Test cache tags and debug header for deep nested queries involving category and products
*
* @magentoCache all enabled
* @magentoDataFixture Magento/Catalog/_files/product_in_multiple_categories.php
- *
*/
public function testDispatchForCacheHeadersOnDeepNestedQueries(): void
{
@@ -83,15 +69,18 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void
$productIdsFromCategory = $category->getProductCollection()->getAllIds();
foreach ($productIdsFromCategory as $productId) {
+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
$resolvedCategoryIds = array_merge(
$resolvedCategoryIds,
$productRepository->getById($productId)->getCategoryIds()
);
}
+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
$resolvedCategoryIds = array_merge($resolvedCategoryIds, [$baseCategoryId]);
foreach ($resolvedCategoryIds as $categoryId) {
$category = $categoryRepository->get($categoryId);
+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
$productIdsFromCategory= array_merge(
$productIdsFromCategory,
$category->getProductCollection()->getAllIds()
@@ -102,14 +91,15 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void
$uniqueCategoryIds = array_unique($resolvedCategoryIds);
$expectedCacheTags = ['cat_c', 'cat_p', 'FPC'];
foreach ($uniqueProductIds as $uniqueProductId) {
- $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$uniqueProductId]);
+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
+ $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_' . $uniqueProductId]);
}
foreach ($uniqueCategoryIds as $uniqueCategoryId) {
- $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$uniqueCategoryId]);
+ // phpcs:ignore Magento2.Performance.ForeachArrayMerge
+ $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_' . $uniqueCategoryId]);
}
- $request = $this->prepareRequest($query);
- $response = $this->graphql->dispatch($request);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $query]);
$this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
$actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
$this->assertEmpty(
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php
index 335067f8408df..038a8c7255815 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php
@@ -8,7 +8,6 @@
namespace Magento\GraphQlCache\Controller\Catalog;
use Magento\Catalog\Api\ProductRepositoryInterface;
-use Magento\GraphQl\Controller\GraphQl;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
@@ -20,26 +19,12 @@
*/
class ProductsCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
-
- /**
- * @inheritdoc
- */
- protected function setUp(): void
- {
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
- }
-
/**
* Test request is dispatched and response is checked for debug headers and cache tags
*
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php
*/
- public function testToCheckRequestCacheTagsForProducts(): void
+ public function testRequestCacheTagsForProducts(): void
{
/** @var ProductRepositoryInterface $productRepository */
$productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
@@ -63,8 +48,7 @@ public function testToCheckRequestCacheTagsForProducts(): void
}
QUERY;
- $request = $this->prepareRequest($query);
- $response = $this->graphqlController->dispatch($request);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $query]);
$this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
$actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
$expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC'];
@@ -74,7 +58,7 @@ public function testToCheckRequestCacheTagsForProducts(): void
/**
* Test request is checked for debug headers and no cache tags for not existing product
*/
- public function testToCheckRequestNoTagsForProducts(): void
+ public function testRequestNoTagsForNonExistingProducts(): void
{
$query
= <<prepareRequest($query);
- $response = $this->graphqlController->dispatch($request);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $query]);
$this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
$actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
$expectedCacheTags = ['FPC'];
$this->assertEquals($expectedCacheTags, $actualCacheTags);
}
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php
+ */
+ public function testConsecutiveRequestsAreServedFromThePageCache(): void
+ {
+ $query
+ = <<dispatchGraphQlGETRequest(['query' => $query]);
+ $response2 = $this->dispatchGraphQlGETRequest(['query' => $query]);
+
+ $this->assertEquals('MISS', $response1->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $this->assertEquals('HIT', $response2->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ }
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php
+ */
+ public function testDifferentProductsRequestsUseDifferentPageCacheRecords(): void
+ {
+ $queryTemplate
+ = <<dispatchGraphQlGETRequest(['query' => sprintf($queryTemplate, 'simple1')]);
+ $responseProduct2 = $this->dispatchGraphQlGETRequest(['query' => sprintf($queryTemplate, 'simple2')]);
+
+ $this->assertEquals('MISS', $responseProduct1->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $this->assertEquals('MISS', $responseProduct2->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php
index c9dca2a5a8372..bcc7c623eb18a 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php
@@ -7,8 +7,9 @@
namespace Magento\GraphQlCache\Controller\Cms;
+use Magento\Cms\Api\Data\BlockInterface;
use Magento\Cms\Model\BlockRepository;
-use Magento\GraphQl\Controller\GraphQl;
+use Magento\Framework\App\Response\HttpInterface as HttpResponse;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
@@ -20,23 +21,27 @@
*/
class BlockCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
+ private function assertPageCacheMissWithTagsForCmsBlock(HttpResponse $response, BlockInterface $block): void
+ {
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $this->assertCmsBlockCacheTags($response, $block);
+ }
- /**
- * @inheritdoc
- */
- protected function setUp(): void
+ private function assertPageCacheHitWithTagsForCmsBlock(HttpResponse $response, BlockInterface $block): void
+ {
+ $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $this->assertCmsBlockCacheTags($response, $block);
+ }
+
+ private function assertCmsBlockCacheTags(HttpResponse $response, BlockInterface $block): void
{
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
+ $expectedCacheTags = ['cms_b', 'cms_b_' . $block->getId(), 'cms_b_' . $block->getIdentifier(), 'FPC'];
+ $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
+ $actualCacheTags = explode(',', $rawActualCacheTags);
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
}
/**
- * Test that the correct cache tags get added to request for cmsBlocks
- *
* @magentoDataFixture Magento/Cms/_files/block.php
* @magentoDataFixture Magento/Cms/_files/blocks.php
*/
@@ -46,9 +51,9 @@ public function testCmsBlocksRequestHasCorrectTags(): void
$blockRepository = $this->objectManager->get(BlockRepository::class);
$block1Identifier = 'fixture_block';
- $block1 = $blockRepository->getById($block1Identifier);
+ $block1 = $blockRepository->getById($block1Identifier);
$block2Identifier = 'enabled_block';
- $block2 = $blockRepository->getById($block2Identifier);
+ $block2 = $blockRepository->getById($block2Identifier);
$queryBlock1
= <<prepareRequest($queryBlock1);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]);
+ $this->assertPageCacheMissWithTagsForCmsBlock($response, $block1);
- // check to see that the second entity gets a miss when called the first time
- $request = $this->prepareRequest($queryBlock2);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block2->getId(), 'cms_b_' . $block2->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ // check to see that the second entity gets a MISS when called the first time
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock2]);
+ $this->assertPageCacheMissWithTagsForCmsBlock($response, $block2);
// check to see that the first entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryBlock1);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]);
+ $this->assertPageCacheHitWithTagsForCmsBlock($response, $block1);
// check to see that the second entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryBlock2);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block2->getId(), 'cms_b_' . $block2->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock2]);
+ $this->assertPageCacheHitWithTagsForCmsBlock($response, $block2);
$block1->setTitle('something else that causes invalidation');
$blockRepository->save($block1);
// check to see that the first entity gets a MISS and it was invalidated
- $request = $this->prepareRequest($queryBlock1);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]);
+ $this->assertPageCacheMissWithTagsForCmsBlock($response, $block1);
// check to see that the first entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryBlock1);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]);
+ $this->assertPageCacheHitWithTagsForCmsBlock($response, $block1);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php
index 0248f870a5f11..60d84947d87c8 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php
@@ -7,13 +7,14 @@
namespace Magento\GraphQlCache\Controller\Cms;
+use Magento\Cms\Api\Data\PageInterface;
use Magento\Cms\Model\GetPageByIdentifier;
use Magento\Cms\Model\PageRepository;
-use Magento\GraphQl\Controller\GraphQl;
+use Magento\Framework\App\Response\HttpInterface as HttpResponse;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
/**
- * Test caching works for CMS page
+ * Test caching works for CMS pages
*
* @magentoAppArea graphql
* @magentoCache full_page enabled
@@ -22,123 +23,34 @@
*/
class CmsPageCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
-
- /**
- * @inheritdoc
- */
- protected function setUp(): void
- {
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class);
- }
-
- /**
- * Test that the correct cache tags get added to request for cmsPage query
- *
- * @magentoDataFixture Magento/Cms/_files/pages.php
- */
- public function testToCheckCmsPageRequestCacheTags(): void
+ private function assertPageCacheMissWithTagsForCmsPage(string $pageId, string $name, HttpResponse $response): void
{
- $cmsPage100 = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0);
- $pageId100 = $cmsPage100->getId();
-
- $cmsPageBlank = $this->objectManager->get(GetPageByIdentifier::class)->execute('page_design_blank', 0);
- $pageIdBlank = $cmsPageBlank->getId();
-
- $queryCmsPage100 = $this->getQuery($pageId100);
- $queryCmsPageBlank = $this->getQuery($pageIdBlank);
-
- // check to see that the first entity gets a MISS when called the first time
- $request = $this->prepareRequest($queryCmsPage100);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals(
- 'MISS',
- $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected MISS on page page100 id {$queryCmsPage100}"
- );
- $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC'];
- $this->assertEquals($expectedCacheTags, $requestedCacheTags);
-
- // check to see that the second entity gets a miss when called the first time
- $request = $this->prepareRequest($queryCmsPageBlank);
- $response = $this->graphqlController->dispatch($request);
$this->assertEquals(
'MISS',
$response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected MISS on page pageBlank id {$pageIdBlank}"
- );
- $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageIdBlank , 'FPC'];
- $this->assertEquals($expectedCacheTags, $requestedCacheTags);
-
- // check to see that the first entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryCmsPage100);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals(
- 'HIT',
- $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected HIT on page page100 id {$queryCmsPage100}"
- );
- $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC'];
- $this->assertEquals($expectedCacheTags, $requestedCacheTags);
-
- // check to see that the second entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryCmsPageBlank);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals(
- 'HIT',
- $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected HIT on page pageBlank id {$pageIdBlank}"
+ "expected MISS on page {$name} id {$pageId}"
);
- $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageIdBlank , 'FPC'];
- $this->assertEquals($expectedCacheTags, $requestedCacheTags);
-
- /** @var PageRepository $pageRepository */
- $pageRepository = $this->objectManager->get(PageRepository::class);
-
- $page = $pageRepository->getById($pageId100);
- $page->setTitle('something else that causes invalidation');
- $pageRepository->save($page);
-
- // check to see that the first entity gets a MISS and it was invalidated
- $request = $this->prepareRequest($queryCmsPage100);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals(
- 'MISS',
- $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected MISS on page page100 id {$queryCmsPage100}"
- );
- $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC'];
- $this->assertEquals($expectedCacheTags, $requestedCacheTags);
+ $this->assertCmsPageCacheTags($pageId, $response);
+ }
- // check to see that the first entity gets a HIT when called the second time
- $request = $this->prepareRequest($queryCmsPage100);
- $response = $this->graphqlController->dispatch($request);
+ private function assertPageCacheHitWithTagsForCmsPage(string $pageId, string $name, HttpResponse $response): void
+ {
$this->assertEquals(
'HIT',
$response->getHeader('X-Magento-Cache-Debug')->getFieldValue(),
- "expected MISS on page page100 id {$queryCmsPage100}"
+ "expected HIT on page {$name} id {$pageId}"
);
+ $this->assertCmsPageCacheTags($pageId, $response);
+ }
+
+ private function assertCmsPageCacheTags(string $pageId, HttpResponse $response): void
+ {
$requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
- $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC'];
+ $expectedCacheTags = ['cms_p', 'cms_p_' . $pageId, 'FPC'];
$this->assertEquals($expectedCacheTags, $requestedCacheTags);
}
- /**
- * Get cms query
- *
- * @param string $id
- * @return string
- */
- private function getQuery(string $id) : string
+ private function buildQuery(string $id): string
{
$queryCmsPage = <<objectManager->get(PageRepository::class);
+ $page = $pageRepository->getById($pageId100);
+ $page->setTitle($newTitle);
+ $pageRepository->save($page);
+ }
+
+ /**
+ * @magentoDataFixture Magento/Cms/_files/pages.php
+ */
+ public function testCmsPageRequestCacheTags(): void
+ {
+ /** @var PageInterface $cmsPage100 */
+ $cmsPage100 = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0);
+ $pageId100 = (string) $cmsPage100->getId();
+
+ /** @var PageInterface $cmsPageBlank */
+ $cmsPageBlank = $this->objectManager->get(GetPageByIdentifier::class)->execute('page_design_blank', 0);
+ $pageIdBlank = (string) $cmsPageBlank->getId();
+
+ $queryCmsPage100 = $this->buildQuery($pageId100);
+ $queryCmsPageBlank = $this->buildQuery($pageIdBlank);
+
+ // check to see that the first entity gets a MISS when called the first time
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]);
+ $this->assertPageCacheMissWithTagsForCmsPage($pageId100, 'page100', $response);
+
+ // check to see that the second entity gets a MISS when called the first time
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]);
+ $this->assertPageCacheMissWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response);
+
+ // check to see that the first entity gets a HIT when called the second time
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]);
+ $this->assertPageCacheHitWithTagsForCmsPage($pageId100, 'page100', $response);
+
+ // check to see that the second entity gets a HIT when called the second time
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]);
+ $this->assertPageCacheHitWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response);
+
+ // invalidate first entity
+ $this->updateCmsPageTitle($pageId100, 'something else that causes invalidation');
+
+ // check to see that the second entity gets a HIT to confirm only the first was invalidated
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]);
+ $this->assertPageCacheHitWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response);
+
+ // check to see that the first entity gets a MISS because it was invalidated
+ $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]);
+ $this->assertPageCacheMissWithTagsForCmsPage($pageId100, 'page100', $response);
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php
index 7accb1d7d0b26..81a4988b81935 100644
--- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php
@@ -9,7 +9,7 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
-use Magento\GraphQl\Controller\GraphQl;
+use Magento\Framework\App\Response\HttpInterface as HttpResponse;
use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\Cms\Api\Data\PageInterface;
@@ -24,155 +24,153 @@
*/
class AllEntitiesUrlResolverCacheTest extends AbstractGraphqlCacheTest
{
- /**
- * @var GraphQl
- */
- private $graphqlController;
+ private function assertCacheMISSWithTagsForCategory(string $categoryId, HttpResponse $response): void
+ {
+ $this->assertCacheMISS($response);
+ $this->assertCacheTags($categoryId, 'cat_c', $response);
+ }
- /**
- * @inheritdoc
- */
- protected function setUp(): void
+ private function assertCacheMISSWithTagsForProduct(string $productId, HttpResponse $response): void
+ {
+ $this->assertCacheMISS($response);
+ $this->assertCacheTags($productId, 'cat_p', $response);
+ }
+
+ private function assertCacheMISSWithTagsForCmsPage(string $pageId, HttpResponse $response): void
+ {
+ $this->assertCacheMISS($response);
+ $this->assertCacheTags($pageId, 'cms_p', $response);
+ }
+
+ private function assertCacheHITWithTagsForCategory(string $categoryId, HttpResponse $response): void
{
- parent::setUp();
- $this->graphqlController = $this->objectManager->get(GraphQl::class);
+ $this->assertCacheHIT($response);
+ $this->assertCacheTags($categoryId, 'cat_c', $response);
+ }
+
+ private function assertCacheHITWithTagsForProduct(string $productId, HttpResponse $response): void
+ {
+ $this->assertCacheHIT($response);
+ $this->assertCacheTags($productId, 'cat_p', $response);
+ }
+
+ private function assertCacheHITWithTagsForCmsPage(string $pageId, HttpResponse $response): void
+ {
+ $this->assertCacheHIT($response);
+ $this->assertCacheTags($pageId, 'cms_p', $response);
+ }
+
+ private function assertCacheMISS(HttpResponse $response): void
+ {
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ }
+
+ private function assertCacheHIT(HttpResponse $response): void
+ {
+ $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ }
+
+ private function assertCacheTags(string $entityId, string $entityCacheTag, HttpResponse $response)
+ {
+ $expectedCacheTags = [$entityCacheTag, $entityCacheTag . '_' . $entityId, 'FPC'];
+ $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
+ $actualCacheTags = explode(',', $rawActualCacheTags);
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ }
+
+ private function buildQuery(string $requestPath): string
+ {
+ $resolverQuery = <<objectManager->get(ProductRepositoryInterface::class);
/** @var Product $product */
$product = $productRepository->get($productSku, false, null, true);
- $storeId = $product->getStoreId();
+ $storeId = (string) $product->getStoreId();
/** @var UrlFinderInterface $urlFinder */
- $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
- $actualUrls = $urlFinder->findOneByData(
+ $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
+ $actualUrls = $urlFinder->findOneByData(
[
'request_path' => $categoryUrlKey,
'store_id' => $storeId
]
);
- $categoryId = $actualUrls->getEntityId();
- $categoryQuery = $this->getQuery($categoryUrlKey);
+ $categoryId = (string) $actualUrls->getEntityId();
+ $categoryQuery = $this->buildQuery($categoryUrlKey);
- $productQuery = $this->getQuery($productUrlKey);
+ $productQuery = $this->buildQuery($productUrlKey);
/** @var GetPageByIdentifierInterface $page */
$page = $this->objectManager->get(GetPageByIdentifierInterface::class);
/** @var PageInterface $cmsPage */
- $cmsPage = $page->execute('page100', 0);
- $cmsPageId = $cmsPage->getId();
+ $cmsPage = $page->execute('page100', 0);
+ $cmsPageId = (string) $cmsPage->getId();
$requestPath = $cmsPage->getIdentifier();
- $pageQuery = $this->getQuery($requestPath);
+ $pageQuery = $this->buildQuery($requestPath);
// query category for MISS
- $request = $this->prepareRequest($categoryQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]);
+ $this->assertCacheMISSWithTagsForCategory($categoryId, $response);
// query product for MISS
- $request = $this->prepareRequest($productQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]);
+ $this->assertCacheMISSWithTagsForProduct((string) $product->getId(), $response);
// query page for MISS
- $request = $this->prepareRequest($pageQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_p','cms_p_' . $cmsPageId,'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $pageQuery]);
+ $this->assertCacheMISSWithTagsForCmsPage($cmsPageId, $response);
// query category for HIT
- $request = $this->prepareRequest($categoryQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]);
+ $this->assertCacheHITWithTagsForCategory($categoryId, $response);
// query product for HIT
- $request = $this->prepareRequest($productQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]);
+ $this->assertCacheHITWithTagsForProduct((string) $product->getId(), $response);
- // query product for HIT
- $request = $this->prepareRequest($pageQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cms_p','cms_p_' . $cmsPageId,'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ // query page for HIT
+ $response = $this->dispatchGraphQlGETRequest(['query' => $pageQuery]);
+ $this->assertCacheHITWithTagsForCmsPage($cmsPageId, $response);
$product->setUrlKey('something-else-that-invalidates-the-cache');
$productRepository->save($product);
- $productQuery = $this->getQuery('something-else-that-invalidates-the-cache.html');
+ $productQuery = $this->buildQuery('something-else-that-invalidates-the-cache.html');
// query category for MISS
- $request = $this->prepareRequest($categoryQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]);
+ $this->assertCacheMISSWithTagsForCategory($categoryId, $response);
- // query product for HIT
- $request = $this->prepareRequest($productQuery);
- $response = $this->graphqlController->dispatch($request);
- $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
- $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC'];
- $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue();
- $actualCacheTags = explode(',', $rawActualCacheTags);
- $this->assertEquals($expectedCacheTags, $actualCacheTags);
- }
+ // query product for MISS
+ $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]);
+ $this->assertCacheMISSWithTagsForProduct((string) $product->getId(), $response);
- /**
- * Get urlResolver query
- *
- * @param string $id
- * @return string
- */
- private function getQuery(string $requestPath) : string
- {
- $resolverQuery = <<dispatchGraphQlGETRequest(['query' => $pageQuery]);
+ $this->assertCacheHITWithTagsForCmsPage($cmsPageId, $response);
}
}
diff --git a/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php b/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php
index 30cb4a67b9edd..a4c9fb4380651 100644
--- a/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php
+++ b/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Framework\App\Cache\Frontend;
use Magento\Framework\App\Cache\Type\FrontendPool;
@@ -55,6 +56,7 @@ public function __construct(
/**
* Create instances of every cache frontend known to the system.
+ *
* Method is to be used for delayed initialization of the iterator.
*
* @return void
@@ -77,18 +79,21 @@ protected function _initialize()
protected function _getCacheSettings()
{
/*
- * Merging is intentionally implemented through array_merge() instead of array_replace_recursive()
- * to avoid "inheritance" of the default settings that become irrelevant as soon as cache storage type changes
+ * Merging is intentionally implemented through array_replace_recursive() instead of array_merge(), because even
+ * though some settings may become irrelevant when the cache storage type is changed, they don't do any harm
+ * and can be overwritten when needed.
+ * Also array_merge leads to unexpected behavior, for for example by dropping the
+ * default cache_dir setting from di.xml when a cache id_prefix is configured in app/etc/env.php.
*/
$cacheInfo = $this->deploymentConfig->getConfigData(FrontendPool::KEY_CACHE);
if (null !== $cacheInfo) {
- return array_merge($this->_frontendSettings, $cacheInfo[FrontendPool::KEY_FRONTEND_CACHE]);
+ return array_replace_recursive($this->_frontendSettings, $cacheInfo[FrontendPool::KEY_FRONTEND_CACHE]);
}
return $this->_frontendSettings;
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*
* @return \Magento\Framework\Cache\FrontendInterface
*/
@@ -99,7 +104,7 @@ public function current()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function key()
{
@@ -108,7 +113,7 @@ public function key()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function next()
{
@@ -117,7 +122,7 @@ public function next()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function rewind()
{
@@ -126,7 +131,7 @@ public function rewind()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function valid()
{
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php
index bfa37311884ba..5ec3dd658737b 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php
@@ -8,6 +8,9 @@
use Magento\Framework\App\Cache\Frontend\Pool;
use Magento\Framework\App\Cache\Type\FrontendPool;
+/**
+ * And another docblock to make the sniff shut up.
+ */
class PoolTest extends \PHPUnit\Framework\TestCase
{
/**
@@ -111,25 +114,38 @@ public function testInitializationParams(
public function initializationParamsDataProvider()
{
return [
- 'default frontend, default settings' => [
+ 'no deployment config, default settings' => [
['frontend' => []],
[Pool::DEFAULT_FRONTEND_ID => ['default_option' => 'default_value']],
['default_option' => 'default_value'],
],
- 'default frontend, overridden settings' => [
+ 'deployment config, default settings' => [
+ ['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]],
+ [Pool::DEFAULT_FRONTEND_ID => ['default_option' => 'default_value']],
+ ['configured_option' => 'configured_value', 'default_option' => 'default_value'],
+ ],
+ 'deployment config, overridden settings' => [
['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]],
- [Pool::DEFAULT_FRONTEND_ID => ['ignored_option' => 'ignored_value']],
+ [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'default_value']],
['configured_option' => 'configured_value'],
],
- 'custom frontend, default settings' => [
- ['frontend' => []],
+ 'deployment config, default settings, overridden settings' => [
+ ['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]],
+ [Pool::DEFAULT_FRONTEND_ID => [
+ 'configured_option' => 'default_value',
+ 'default_setting' => 'default_value'
+ ]],
+ ['configured_option' => 'configured_value', 'default_setting' => 'default_value'],
+ ],
+ 'custom deployent config, default settings' => [
+ ['frontend' => ['custom' => ['configured_option' => 'configured_value']]],
['custom' => ['default_option' => 'default_value']],
- ['default_option' => 'default_value'],
+ ['configured_option' => 'configured_value', 'default_option' => 'default_value'],
],
- 'custom frontend, overridden settings' => [
+ 'custom deployent config, default settings, overridden settings' => [
['frontend' => ['custom' => ['configured_option' => 'configured_value']]],
- ['custom' => ['ignored_option' => 'ignored_value']],
- ['configured_option' => 'configured_value'],
+ ['custom' => ['default_option' => 'default_value', 'configured_option' => 'default_value']],
+ ['configured_option' => 'configured_value', 'default_option' => 'default_value'],
]
];
}