From 842449e2afc92f3f88828eb8d0f377f11c465d61 Mon Sep 17 00:00:00 2001 From: Dimitris Spachos Date: Wed, 12 Jun 2024 13:05:23 +0300 Subject: [PATCH] SLB-281 path aliases 404 issues (#1532) - path alias update now triggers a build --- .gitignore | 2 + .../src/Plugin/Gatsby/Feed/EntityFeed.php | 46 +++++++++++++---- .../src/Kernel/GatsbyBuildTriggerTest.php | 39 ++++++++++++--- .../src/Kernel/GatsbyUpdateHandlerTest.php | 42 ++++++++++++++++ .../src/Kernel/GatsbyUpdateTrackerTest.php | 48 +++++++++++++----- .../src/Kernel/GatsbyUpdateTriggerTest.php | 49 ++++++++++++++----- 6 files changed, 187 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 803b89e2d..8543b98fc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ node_modules # Local Netlify folder .netlify + +deno.lock diff --git a/packages/composer/amazeelabs/silverback_gatsby/src/Plugin/Gatsby/Feed/EntityFeed.php b/packages/composer/amazeelabs/silverback_gatsby/src/Plugin/Gatsby/Feed/EntityFeed.php index c9e84aae2..85e9b1e34 100644 --- a/packages/composer/amazeelabs/silverback_gatsby/src/Plugin/Gatsby/Feed/EntityFeed.php +++ b/packages/composer/amazeelabs/silverback_gatsby/src/Plugin/Gatsby/Feed/EntityFeed.php @@ -11,6 +11,9 @@ use Drupal\graphql\GraphQL\Resolver\ResolverInterface; use Drupal\graphql\GraphQL\ResolverBuilder; use Drupal\graphql\GraphQL\ResolverRegistryInterface; +use Drupal\node\Entity\Node; +use Drupal\path_alias\AliasManagerInterface; +use Drupal\path_alias\Entity\PathAlias; use Drupal\silverback_gatsby\Plugin\FeedBase; use Drupal\silverback_gatsby\Plugin\GraphQL\DataProducer\GatsbyBuildId; use GraphQL\Language\AST\DocumentNode; @@ -53,6 +56,12 @@ class EntityFeed extends FeedBase implements ContainerFactoryPluginInterface { */ protected ?ContentTranslationManagerInterface $contentTranslationManager; + /** + * The path alias manager. + * + * @var \Drupal\path_alias\AliasManagerInterface + */ + protected $pathAliasManager; /** * {@inheritDoc} @@ -67,9 +76,8 @@ public static function create( $configuration, $plugin_id, $plugin_definition, - $container->has('content_translation.manager') - ? $container->get('content_translation.manager') - : NULL + $container->has('content_translation.manager') ? $container->get('content_translation.manager') : NULL, + $container->get('path_alias.manager') ); } @@ -77,12 +85,14 @@ public function __construct( $config, $plugin_id, $plugin_definition, - ?ContentTranslationManagerInterface $contentTranslationManager + ?ContentTranslationManagerInterface $contentTranslationManager, + AliasManagerInterface $path_alias_manager ) { $this->type = $config['type']; $this->bundle = $config['bundle'] ?? NULL; - $this->access = $config['access'] ?? true; + $this->access = $config['access'] ?? TRUE; $this->contentTranslationManager = $contentTranslationManager; + $this->pathAliasManager = $path_alias_manager; parent::__construct( $config, @@ -103,6 +113,19 @@ public function isTranslatable(): bool { * {@inheritDoc} */ public function getUpdateIds($context, ?AccountInterface $account) : array { + + // Special case for path alias. + if ($context instanceof PathAlias) { + $path = $this->pathAliasManager->getPathByAlias($context->alias->value); + if (preg_match('/node\/(\d+)/', $path, $matches)) { + $node = isset($matches[1]) ? Node::load($matches[1]) : NULL; + if ($node) { + // See SLB-281 for details. + $context = $node; + } + } + } + if ( $context instanceof EntityInterface && $context->getEntityTypeId() === $this->type @@ -123,7 +146,7 @@ public function getUpdateIds($context, ?AccountInterface $account) : array { /** * {@inheritDoc} */ - public function resolveItem(ResolverInterface $id, ?ResolverInterface $langcode = null): ResolverInterface { + public function resolveItem(ResolverInterface $id, ?ResolverInterface $langcode = NULL): ResolverInterface { $resolver = $this->builder->produce('fetch_entity') ->map('type', $this->builder->fromValue($this->type)) ->map('bundles', $this->builder->fromValue($this->bundle === NULL ? NULL : [$this->bundle])) @@ -194,11 +217,17 @@ public function resolveTranslations(): ResolverInterface { ); } + /** + * + */ public function getExtensionDefinition(DocumentNode $parentAst): string { $type = $this->typeName; return "\nextend type Query { _load{$type}Revision(id: String!, revision: String!) : $type @deprecated }"; } + /** + * + */ public function addExtensionResolvers( ResolverRegistryInterface $registry, ResolverBuilder $builder @@ -209,15 +238,14 @@ public function addExtensionResolvers( : $builder->fromArgument('id'); $langResolver = $this->isTranslatable() ? $builder->produce('gatsby_extract_langcode')->map('id', $builder->fromArgument('id')) - : $builder->fromValue(null); + : $builder->fromValue(NULL); $resolver = $this->builder->produce('fetch_entity') ->map('type', $this->builder->fromValue($this->type)) ->map('bundles', $this->builder->fromValue($this->bundle === NULL ? NULL : [$this->bundle])) ->map('access', $this->builder->fromValue($this->access)) ->map('id', $idResolver) ->map('language', $langResolver) - ->map('revision_id', $builder->fromArgument('revision')) - ; + ->map('revision_id', $builder->fromArgument('revision')); $registry->addFieldResolver("Query", "_load{$type}Revision", $resolver); } diff --git a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyBuildTriggerTest.php b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyBuildTriggerTest.php index ad14edf93..e63cdaebc 100644 --- a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyBuildTriggerTest.php +++ b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyBuildTriggerTest.php @@ -10,6 +10,9 @@ use GuzzleHttp\Psr7\Request; use Prophecy\Argument; +/** + * + */ class GatsbyBuildTriggerTest extends KernelTestBase { use NotificationCheckTrait; @@ -28,6 +31,7 @@ class GatsbyBuildTriggerTest extends KernelTestBase { 'silverback_gatsby', 'silverback_gatsby_example', 'menu_link_content', + 'path_alias', ]; /** @@ -40,6 +44,9 @@ class GatsbyBuildTriggerTest extends KernelTestBase { */ protected $trigger; + /** + * {@inheritdoc} + */ protected function setUp() : void { parent::setUp(); $this->setupClientProphecy(); @@ -58,12 +65,12 @@ protected function setUp() : void { 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', - 'build_webhook' => 'http://localhost:8000/__refresh' - ] - ] + 'build_webhook' => 'http://localhost:8000/__refresh', + ], + ], ])->save(); Server::create([ @@ -73,22 +80,28 @@ protected function setUp() : void { 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', - 'build_webhook' => 'http://localhost:9000/__refresh' - ] - ] + 'build_webhook' => 'http://localhost:9000/__refresh', + ], + ], ])->save(); } + /** + * + */ public function testBeforeShutdown() { $this->trigger->trigger('foo', 1); // If _drupal_shutdown_function() is not called, no notifications go out. $this->checkTotalNotifications(0); } + /** + * + */ public function testRequestException() { $this->clientProphecy->post(Argument::any(), Argument::any()) ->willThrow(new RequestException('Invalid!', new Request('post', 'http://localhost:8000/__refresh'))); @@ -99,6 +112,9 @@ public function testRequestException() { $this->messengerProphecy->addError('Could not send build notification to server "http://localhost:8000/__refresh".')->shouldHaveBeenCalledTimes(1); } + /** + * + */ public function testSingleTrigger() { $this->trigger->trigger('foo', 1); _drupal_shutdown_function(); @@ -106,6 +122,9 @@ public function testSingleTrigger() { $this->checkBuildNotification('http://localhost:8000/__refresh', 1); } + /** + * + */ public function testMultipleTriggers() { $this->trigger->trigger('foo', 1); $this->trigger->trigger('foo', 2); @@ -114,6 +133,9 @@ public function testMultipleTriggers() { $this->checkBuildNotification('http://localhost:8000/__refresh', 2); } + /** + * + */ public function testMultipleServers() { $this->trigger->trigger('foo', 1); $this->trigger->trigger('bar', 2); @@ -122,4 +144,5 @@ public function testMultipleServers() { $this->checkBuildNotification('http://localhost:8000/__refresh', 1); $this->checkBuildNotification('http://localhost:9000/__refresh', 2); } + } diff --git a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateHandlerTest.php b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateHandlerTest.php index 35d796ba4..3d01b55d1 100644 --- a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateHandlerTest.php +++ b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateHandlerTest.php @@ -6,9 +6,16 @@ use Drupal\node\Entity\Node; use Drupal\silverback_gatsby\GatsbyUpdate; use Drupal\silverback_gatsby\GatsbyUpdateTrigger; +use Drupal\Tests\Traits\Core\PathAliasTestTrait; +/** + * + */ class GatsbyUpdateHandlerTest extends EntityFeedTestBase { + use PathAliasTestTrait; + public static $modules = ['path_alias']; + /** * @var \Drupal\silverback_gatsby\GatsbyUpdateTracker|object|null */ @@ -19,17 +26,27 @@ class GatsbyUpdateHandlerTest extends EntityFeedTestBase { */ protected $triggerProphecy; + /** + * + */ public function register(ContainerBuilder $container) { parent::register($container); $this->triggerProphecy = $this->prophesize(GatsbyUpdateTrigger::class); $container->set('silverback_gatsby.update_trigger', $this->triggerProphecy->reveal()); } + /** + * {@inheritdoc} + */ protected function setUp() : void { parent::setUp(); + $this->installEntitySchema('path_alias'); $this->tracker = $this->container->get('silverback_gatsby.update_tracker'); } + /** + * + */ public function testLogRelevantChanges() { $node = Node::create([ 'type' => 'page', @@ -54,6 +71,9 @@ public function testLogRelevantChanges() { ], $diff); } + /** + * + */ public function testIgnoreIrrelevantChanges() { $node = Node::create([ 'type' => 'article', @@ -68,6 +88,9 @@ public function testIgnoreIrrelevantChanges() { $this->assertEmpty($diff); } + /** + * + */ public function testTriggerUpdates() { $page = Node::create([ 'type' => 'page', @@ -86,4 +109,23 @@ public function testTriggerUpdates() { $this->triggerProphecy ->trigger($this->server->id(), new GatsbyUpdate('Page', $page->uuid() . ':en'))->shouldHaveBeenCalledTimes(1); } + + /** + * Test case for testing the behavior when path alias triggers updates. + */ + public function testPathAliasTriggerUpdates() { + $node = Node::create([ + 'type' => 'page', + 'title' => 'Test', + ]); + $node->save(); + $this->tracker->clear(); + $this->createPathAlias('/node/1', '/test', 'en'); + $this->tracker->clear(); + // We expect two calls for the same page, as the path alias + // should also trigger a page build. + $this->triggerProphecy + ->trigger($this->server->id(), new GatsbyUpdate('Page', $node->uuid() . ':en'))->shouldHaveBeenCalledTimes(2); + } + } diff --git a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTrackerTest.php b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTrackerTest.php index 1042a6037..5b364d5da 100644 --- a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTrackerTest.php +++ b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTrackerTest.php @@ -7,6 +7,9 @@ use Drupal\silverback_gatsby\GatsbyUpdate; use Drupal\Tests\silverback_gatsby\Traits\NotificationCheckTrait; +/** + * + */ class GatsbyUpdateTrackerTest extends KernelTestBase { use NotificationCheckTrait; @@ -25,6 +28,7 @@ class GatsbyUpdateTrackerTest extends KernelTestBase { 'silverback_gatsby', 'silverback_gatsby_example', 'menu_link_content', + 'path_alias', ]; /** @@ -32,7 +36,10 @@ class GatsbyUpdateTrackerTest extends KernelTestBase { */ protected $tracker; - protected function setUp() : void{ + /** + * {@inheritdoc} + */ + protected function setUp() : void { parent::setUp(); $this->setupClientProphecy(); $this->installConfig('graphql'); @@ -44,12 +51,12 @@ protected function setUp() : void{ 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', - 'build_webhook' => 'http://localhost:8000/__refresh' - ] - ] + 'build_webhook' => 'http://localhost:8000/__refresh', + ], + ], ])->save(); Server::create([ 'schema' => 'directable', @@ -58,16 +65,19 @@ protected function setUp() : void{ 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', - 'build_webhook' => 'http://localhost:8000/__refresh' - ] - ] + 'build_webhook' => 'http://localhost:8000/__refresh', + ], + ], ])->save(); $this->tracker = $this->container->get('silverback_gatsby.update_tracker'); } + /** + * + */ public function testNoBuilds() { $this->assertEquals(-1, $this->tracker->latestBuild('foo')); $this->assertEmpty($this->tracker->diff(1, 2, 'foo')); @@ -75,6 +85,9 @@ public function testNoBuilds() { $this->checkTotalNotifications(0); } + /** + * + */ public function testSingleBuild() { $this->tracker->track('foo', 'Page', '1'); $this->assertEquals(1, $this->tracker->latestBuild('foo')); @@ -82,6 +95,9 @@ public function testSingleBuild() { $this->checkTotalNotifications(1); } + /** + * + */ public function testMultipleBuilds() { $this->tracker->track('foo', 'Page', '1'); $this->tracker->track('foo', 'Page', '2'); @@ -91,6 +107,9 @@ public function testMultipleBuilds() { ); } + /** + * + */ public function testDeferredBuild() { $this->tracker->track('foo', 'Page', '1', FALSE); $this->assertEquals(1, $this->tracker->latestBuild('foo')); @@ -98,6 +117,9 @@ public function testDeferredBuild() { $this->checkTotalNotifications(0); } + /** + * + */ public function testInvalidDiff() { $this->tracker->track('foo', 'Page', '1'); $this->tracker->track('foo', 'Page', '2'); @@ -122,6 +144,9 @@ public function testInvalidDiff() { ); } + /** + * + */ public function testMultipleServers() { $this->tracker->track('foo', 'Page', '1'); $this->tracker->track('foo', 'Page', '2'); @@ -132,13 +157,14 @@ public function testMultipleServers() { $this->assertEquals(4, $this->tracker->latestBuild('bar')); $this->assertEquals([ - new GatsbyUpdate('Page', '2') + new GatsbyUpdate('Page', '2'), ], $this->tracker->diff(1, 2, 'foo')); $this->assertEquals([], $this->tracker->diff(1, 2, 'bar')); $this->assertEquals([ - new GatsbyUpdate('Page', '3') + new GatsbyUpdate('Page', '3'), ], $this->tracker->diff(3, 4, 'bar')); } + } diff --git a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTriggerTest.php b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTriggerTest.php index 1eb8ffddd..f3a18c25b 100644 --- a/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTriggerTest.php +++ b/packages/composer/amazeelabs/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTriggerTest.php @@ -11,6 +11,9 @@ use GuzzleHttp\Psr7\Request; use Prophecy\Argument; +/** + * + */ class GatsbyUpdateTriggerTest extends KernelTestBase { use NotificationCheckTrait; @@ -29,6 +32,7 @@ class GatsbyUpdateTriggerTest extends KernelTestBase { 'silverback_gatsby', 'silverback_gatsby_example', 'menu_link_content', + 'path_alias', ]; /** @@ -41,6 +45,9 @@ class GatsbyUpdateTriggerTest extends KernelTestBase { */ protected $trigger; + /** + * {@inheritdoc} + */ protected function setUp() : void { parent::setUp(); $this->setupClientProphecy(); @@ -59,13 +66,13 @@ protected function setUp() : void { 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', 'build_webhook' => 'http://localhost:8000/__refresh', - 'update_webhook' => 'http://localhost:8000/__update' - ] - ] + 'update_webhook' => 'http://localhost:8000/__update', + ], + ], ])->save(); Server::create([ @@ -75,23 +82,29 @@ protected function setUp() : void { 'schema_configuration' => [ 'directable' => [ 'extensions' => [ - 'silverback_gatsby' => 'silverback_gatsby' + 'silverback_gatsby' => 'silverback_gatsby', ], 'schema_definition' => __DIR__ . '/../../../modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls', 'build_webhook' => 'http://localhost:9000/__refresh', 'update_webhook' => 'http://localhost:9000/__update', - ] - ] + ], + ], ])->save(); } + /** + * + */ public function testBeforeShutdown() { $this->trigger->trigger('foo', new GatsbyUpdate('Page', '1')); // If _drupal_shutdown_function() is not called, no notifications go out. $this->checkTotalNotifications(0); } + /** + * + */ public function testRequestException() { $this->clientProphecy->post(Argument::any(), Argument::any()) ->willThrow(new RequestException('Invalid!', new Request('post', 'http://localhost:8000/__update'))); @@ -102,6 +115,9 @@ public function testRequestException() { $this->messengerProphecy->addError('Could not send build notification to server "http://localhost:8000/__update".')->shouldHaveBeenCalledTimes(1); } + /** + * + */ public function testSingleTrigger() { $this->trigger->trigger('foo', new GatsbyUpdate("Page", "1")); _drupal_shutdown_function(); @@ -109,9 +125,13 @@ public function testSingleTrigger() { $this->checkUpdateNotification('http://localhost:8000/__update', [[ 'type' => 'Page', 'id' => '1', - ]]); + ], + ]); } + /** + * + */ public function testMultipleTriggers() { $this->trigger->trigger('foo', new GatsbyUpdate("Page", "1")); $this->trigger->trigger('foo', new GatsbyUpdate("Page", "2")); @@ -123,9 +143,13 @@ public function testMultipleTriggers() { ], [ 'type' => 'Page', 'id' => '2', - ]]); + ], + ]); } + /** + * + */ public function testMultipleServers() { $this->trigger->trigger('foo', new GatsbyUpdate("Page", "1")); $this->trigger->trigger('bar', new GatsbyUpdate("Page", "2")); @@ -134,10 +158,13 @@ public function testMultipleServers() { $this->checkUpdateNotification('http://localhost:8000/__update', [[ 'type' => 'Page', 'id' => '1', - ]]); + ], + ]); $this->checkUpdateNotification('http://localhost:9000/__update', [[ 'type' => 'Page', 'id' => '2', - ]]); + ], + ]); } + }