From 55acc7cba0af16c7e73f702f8486eb499a507b02 Mon Sep 17 00:00:00 2001 From: Carl Alexander Date: Mon, 7 Feb 2022 13:19:28 -0500 Subject: [PATCH] feat: add hooks to page caching subscriber --- ...ntDeliveryNetworkPageCachingSubscriber.php | 14 +- ...liveryNetworkPageCachingSubscriberTest.php | 186 +++++++++++++++++- 2 files changed, 188 insertions(+), 12 deletions(-) diff --git a/src/Subscriber/ContentDeliveryNetworkPageCachingSubscriber.php b/src/Subscriber/ContentDeliveryNetworkPageCachingSubscriber.php index 08ea8ee..d08ac38 100644 --- a/src/Subscriber/ContentDeliveryNetworkPageCachingSubscriber.php +++ b/src/Subscriber/ContentDeliveryNetworkPageCachingSubscriber.php @@ -13,14 +13,14 @@ namespace Ymir\Plugin\Subscriber; -use Ymir\Plugin\EventManagement\SubscriberInterface; +use Ymir\Plugin\EventManagement\AbstractEventManagerAwareSubscriber; use Ymir\Plugin\PageCache\ContentDeliveryNetworkPageCacheClientInterface; use Ymir\Plugin\Support\Collection; /** * Subscriber that handles interaction with the content delivery network handling page caching. */ -class ContentDeliveryNetworkPageCachingSubscriber implements SubscriberInterface +class ContentDeliveryNetworkPageCachingSubscriber extends AbstractEventManagerAwareSubscriber { /** * Client interacting with the content delivery network handling page caching. @@ -77,6 +77,8 @@ public static function getSubscribedEvents(): array */ public function clearCache() { + $this->eventManager->execute('ymir_page_caching_clear_all'); + $this->pageCacheClient->clearAll(); } @@ -187,6 +189,12 @@ public function clearPost($postId) $urlsToClear[] = get_post_type_archive_feed_link($post->post_type); } + $urlsToClear = $this->eventManager->filter('ymir_page_caching_urls_to_clear', $urlsToClear); + + if (!$urlsToClear instanceof Collection) { + return; + } + $urlsToClear->filter(function ($url) { return is_string($url) && !empty($url); })->each(function (string $url) { @@ -199,6 +207,8 @@ public function clearPost($postId) */ public function sendClearRequest() { + $this->eventManager->execute('ymir_page_caching_send_clear_request'); + $this->pageCacheClient->sendClearRequest(); } } diff --git a/tests/Unit/Subscriber/ContentDeliveryNetworkPageCachingSubscriberTest.php b/tests/Unit/Subscriber/ContentDeliveryNetworkPageCachingSubscriberTest.php index 8dbcb1c..96ad8e3 100644 --- a/tests/Unit/Subscriber/ContentDeliveryNetworkPageCachingSubscriberTest.php +++ b/tests/Unit/Subscriber/ContentDeliveryNetworkPageCachingSubscriberTest.php @@ -14,7 +14,9 @@ namespace Ymir\Plugin\Tests\Unit\Subscriber; use Ymir\Plugin\Subscriber\ContentDeliveryNetworkPageCachingSubscriber; +use Ymir\Plugin\Support\Collection; use Ymir\Plugin\Tests\Mock\ContentDeliveryNetworkPageCacheClientInterfaceMockTrait; +use Ymir\Plugin\Tests\Mock\EventManagerMockTrait; use Ymir\Plugin\Tests\Mock\FunctionMockTrait; use Ymir\Plugin\Tests\Mock\WPPostMockTrait; use Ymir\Plugin\Tests\Mock\WPPostTypeMockTrait; @@ -28,6 +30,7 @@ class ContentDeliveryNetworkPageCachingSubscriberTest extends TestCase { use ContentDeliveryNetworkPageCacheClientInterfaceMockTrait; + use EventManagerMockTrait; use FunctionMockTrait; use WPPostMockTrait; use WPPostTypeMockTrait; @@ -36,11 +39,20 @@ class ContentDeliveryNetworkPageCachingSubscriberTest extends TestCase public function testClearCache() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('execute') + ->with($this->identicalTo('ymir_page_caching_clear_all')); + $pageCacheClient = $this->getContentDeliveryNetworkPageCacheClientInterfaceMock(); $pageCacheClient->expects($this->once()) ->method('clearAll'); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearCache(); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearCache(); } public function testClearPostAddsCategoryUrls() @@ -48,6 +60,12 @@ public function testClearPostAddsCategoryUrls() $category = $this->getWPTermMock(); $category->term_id = 24; + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'page'; @@ -110,11 +128,21 @@ public function testClearPostAddsCategoryUrls() [$this->identicalTo('rest_url/wp/v2/categories/24/')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsCustomPostArchive() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'page'; @@ -176,11 +204,21 @@ public function testClearPostAddsCustomPostArchive() [$this->identicalTo('post_archive_permalink')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsCustomPostTypeArchiveAndFeed() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'custom_post_type'; @@ -248,11 +286,21 @@ public function testClearPostAddsCustomPostTypeArchiveAndFeed() [$this->identicalTo('custom_post_type_archive_feed_url')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsPostRelatedUrls() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_author = '24'; $post->post_status = 'publish'; @@ -344,11 +392,21 @@ public function testClearPostAddsPostRelatedUrls() [$this->identicalTo('post_commments_feed_url')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsPublicTaxonomyUrls() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'page'; @@ -429,11 +487,21 @@ public function testClearPostAddsPublicTaxonomyUrls() [$this->identicalTo('rest_url/wp/v2/taxonomy/slug/')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsRestApiEndpointIfWeHavePostTypeObject() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'page'; @@ -493,11 +561,21 @@ public function testClearPostAddsRestApiEndpointIfWeHavePostTypeObject() [$this->identicalTo('rest_url/wp/v2/pages/42/')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostAddsTagUrls() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'publish'; $post->post_type = 'page'; @@ -563,7 +641,76 @@ public function testClearPostAddsTagUrls() [$this->identicalTo('rest_url/wp/v2/tag/24/')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); + } + + public function testClearPostDoesNothingIfFilterDoesntReturnCollection() + { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn(null); + + $post = $this->getWPPostMock(); + $post->post_status = 'publish'; + $post->post_type = 'page'; + + $get_post = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_post'); + $get_post->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturn($post); + + $get_post_type_object = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_post_type_object'); + $get_post_type_object->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturn(false); + + $get_permalink = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_permalink'); + $get_permalink->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturnOnConsecutiveCalls('permalink'); + + $get_site_option = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_site_option'); + $get_site_option->expects($this->exactly(2)) + ->withConsecutive( + [$this->identicalTo('show_on_front')], + [$this->identicalTo('tag_base')] + ) + ->willReturnOnConsecutiveCalls(false, '/tag/'); + + $get_the_category = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_the_category'); + $get_the_category->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturn([]); + + $get_the_tags = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_the_tags'); + $get_the_tags->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturn([]); + + $get_post_taxonomies = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'get_post_taxonomies'); + $get_post_taxonomies->expects($this->once()) + ->with($this->identicalTo(42)) + ->willReturn([]); + + $home_url = $this->getFunctionMock($this->getNamespace(ContentDeliveryNetworkPageCachingSubscriber::class), 'home_url'); + $home_url->expects($this->once()) + ->willReturn('home_url'); + + $pageCacheClient = $this->getContentDeliveryNetworkPageCacheClientInterfaceMock(); + $pageCacheClient->expects($this->never()) + ->method('clearUrl'); + + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostDoesNothingIfPageCachingDisabled() @@ -583,6 +730,12 @@ public function testClearPostDoesNothingIfPageCachingDisabled() public function testClearPostFixesTrashedPostPermalinkUrl() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('filter') + ->with($this->identicalTo('ymir_page_caching_urls_to_clear'), $this->isInstanceOf(Collection::class)) + ->willReturn($this->returnArgument(1)); + $post = $this->getWPPostMock(); $post->post_status = 'trash'; $post->post_type = 'page'; @@ -638,7 +791,11 @@ public function testClearPostFixesTrashedPostPermalinkUrl() [$this->identicalTo('home_url/')] ); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->clearPost(42); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->clearPost(42); } public function testClearPostWhenGetPermalinkDoesntReturnAString() @@ -773,10 +930,19 @@ public function testGetSubscribedEvents() public function testSendClearRequest() { + $eventManager = $this->getEventManagerMock(); + $eventManager->expects($this->once()) + ->method('execute') + ->with($this->identicalTo('ymir_page_caching_send_clear_request')); + $pageCacheClient = $this->getContentDeliveryNetworkPageCacheClientInterfaceMock(); $pageCacheClient->expects($this->once()) ->method('sendClearRequest'); - (new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'))->sendClearRequest(); + $subscriber = new ContentDeliveryNetworkPageCachingSubscriber($pageCacheClient, 'rest_url'); + + $subscriber->setEventManager($eventManager); + + $subscriber->sendClearRequest(); } }