From 68c1000f77094b6b20d5f693f11ad1e0313538e9 Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Thu, 15 Jun 2023 17:06:38 +0100 Subject: [PATCH] Issue #3052115 by huzooka, HitchShock, floydm, ranjith_kumar_k_u, Sam152, edysmp, codebymikey, herved, Wim Leers, quietone, hchonov, Berdir, DamienMcKenna, rclemings, donquixote, benjifisher, fengtan, jwilson3: Mark an entity as 'syncing' during a migration update --- .../src/Plugin/migrate/destination/Entity.php | 4 + .../migrate/destination/EntityContentBase.php | 2 + .../migrate/destination/EntityRevision.php | 1 + .../destination/EntityContentBaseTest.php | 4 + .../Unit/destination/EntityRevisionTest.php | 4 + .../MigrateUpgradeExecuteTestBase.php | 33 +++++++++ .../tests/src/Functional/d6/Upgrade6Test.php | 2 +- .../d6/Upgrade6TestWithContentModeration.php | 73 +++++++++++++++++++ .../tests/src/Functional/d7/Upgrade7Test.php | 2 +- .../d7/Upgrade7TestWithContentModeration.php | 65 +++++++++++++++++ 10 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6TestWithContentModeration.php create mode 100644 core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7TestWithContentModeration.php diff --git a/core/modules/migrate/src/Plugin/migrate/destination/Entity.php b/core/modules/migrate/src/Plugin/migrate/destination/Entity.php index 3a2f93be4daa..b7faaae49101 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/Entity.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/Entity.php @@ -3,6 +3,7 @@ namespace Drupal\migrate\Plugin\migrate\destination; use Drupal\Component\Plugin\DependentPluginInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\DependencyTrait; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; @@ -215,6 +216,9 @@ public function rollback(array $destination_identifier) { // Delete the specified entity from Drupal if it exists. $entity = $this->storage->load(reset($destination_identifier)); if ($entity) { + if ($entity instanceof ContentEntityInterface) { + $entity->setSyncing(TRUE); + } $entity->delete(); } } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php index 2b439cd2cb31..cd1c24c2916e 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php @@ -233,6 +233,7 @@ public function validateEntity(FieldableEntityInterface $entity) { * An array containing the entity ID. */ protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { + $entity->setSyncing(TRUE); $entity->save(); return [$entity->id()]; } @@ -380,6 +381,7 @@ public function rollback(array $destination_identifier) { $translation = $entity->getTranslation($langcode); if (!$translation->isDefaultTranslation()) { $entity->removeTranslation($langcode); + $entity->setSyncing(TRUE); $entity->save(); } } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php index b387815724b3..16d986999ced 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php @@ -164,6 +164,7 @@ protected function getEntity(Row $row, array $old_destination_id_values) { * {@inheritdoc} */ protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { + $entity->setSyncing(TRUE); $entity->save(); return [$entity->getRevisionId()]; } diff --git a/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php index 3319b71a19d2..0f1f38f1019d 100644 --- a/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php +++ b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php @@ -14,6 +14,7 @@ use Drupal\migrate\Plugin\migrate\destination\EntityContentBase; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Row; +use Prophecy\Argument; /** * Tests base entity migration destination functionality. @@ -44,6 +45,9 @@ public function testImport() { // Assert that save is called. $entity->save() ->shouldBeCalledTimes(1); + // Syncing should be set once. + $entity->setSyncing(Argument::exact(TRUE)) + ->shouldBeCalledTimes(1); // Set an id for the entity $entity->id() ->willReturn(5); diff --git a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php index 374db8a94613..096f9a231ae4 100644 --- a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php @@ -15,6 +15,7 @@ use Drupal\migrate\Plugin\migrate\destination\EntityRevision as RealEntityRevision; use Drupal\migrate\Row; use Drupal\Tests\UnitTestCase; +use Prophecy\Argument; /** * Tests entity revision destination. @@ -178,6 +179,9 @@ public function testSave() { $entity = $this->prophesize('\Drupal\Core\Entity\ContentEntityInterface'); $entity->save() ->shouldBeCalled(); + // Syncing should be set once. + $entity->setSyncing(Argument::exact(TRUE)) + ->shouldBeCalledTimes(1); $entity->getRevisionId() ->shouldBeCalled() ->willReturn(1234); diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php index f28f6b4dc4a2..10288106c3ff 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional; +use Drupal\Core\Entity\ContentEntityStorageInterface; use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait; /** @@ -69,4 +70,36 @@ public function useTestMailCollector() { $this->writeSettings($settings); } + /** + * Checks the number of the specified entity's revisions. + * + * Revision translations are excluded. + * + * @param string $content_entity_type_id + * The entity type ID of the content entity, e.g. 'node', 'media', + * 'block_content'. + * @param int $expected_revision_count + * The expected number of the revisions. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function assertEntityRevisionsCount(string $content_entity_type_id, int $expected_revision_count) { + $entity_storage = \Drupal::entityTypeManager()->getStorage($content_entity_type_id); + assert($entity_storage instanceof ContentEntityStorageInterface); + $revision_ids = $entity_storage + ->getQuery() + ->allRevisions() + ->accessCheck(FALSE) + ->execute(); + $this->assertCount( + $expected_revision_count, + $revision_ids, + sprintf( + "The number of %s revisions is different than expected", + $content_entity_type_id + ) + ); + } + } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php index 1e6249c2e27f..c7eed2b2d901 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php @@ -200,7 +200,7 @@ public function testUpgradeAndIncremental() { $this->assertUserLogIn(2, 'john.doe_pass'); $this->assertFollowUpMigrationResults(); - + $this->assertEntityRevisionsCount('node', 26); $this->assertEmailsSent(); } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6TestWithContentModeration.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6TestWithContentModeration.php new file mode 100644 index 000000000000..4a46e7f36319 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6TestWithContentModeration.php @@ -0,0 +1,73 @@ +<?php + +namespace Drupal\Tests\migrate_drupal_ui\Functional\d6; + +use Drupal\workflows\Entity\Workflow; +use Drupal\workflows\WorkflowInterface; + +/** + * Tests Drupal 6 upgrade using the migrate UI with Content Moderation. + * + * @group migrate_drupal_ui + */ +class Upgrade6TestWithContentModeration extends Upgrade6Test { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'content_moderation', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + // Set up a moderation flow. + $types = [ + 'story', + 'test_planet', + 'company', + 'employee', + ]; + foreach ($types as $type) { + $this->drupalCreateContentType(['type' => $type]); + } + $editorial = Workflow::load('editorial'); + assert($editorial instanceof WorkflowInterface); + $type_settings = $editorial->getTypePlugin()->getConfiguration(); + $type_settings['default_moderation_state'] = 'published'; + $type_settings['entity_types']['node'] = array_merge( + ['page', 'forum'], + $types + ); + $type_plugin = $editorial->getTypePlugin(); + $type_plugin->setConfiguration($type_settings); + $editorial->trustData()->save(); + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + $entity_counts = parent::getEntityCounts() + [ + 'content_moderation_state' => 18, + 'workflow' => 1, + ]; + $entity_counts['field_config'] = $entity_counts['field_config'] + 1; + $entity_counts['view'] = $entity_counts['view'] + 1; + return $entity_counts; + } + + /** + * {@inheritdoc} + */ + protected function getEntityCountsIncremental() { + $entity_counts_incremental = parent::getEntityCountsIncremental(); + $entity_counts_incremental['content_moderation_state'] = $entity_counts_incremental['content_moderation_state'] + 1; + return $entity_counts_incremental; + } + +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php index 05baccd79858..960fffae0a49 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php @@ -227,7 +227,7 @@ public function testUpgradeAndIncremental() { $this->assertUserLogIn(2, 'a password'); $this->assertFollowUpMigrationResults(); - + $this->assertEntityRevisionsCount('node', 19); $this->assertEmailsSent(); } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7TestWithContentModeration.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7TestWithContentModeration.php new file mode 100644 index 000000000000..5d4ec2dc6d9e --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7TestWithContentModeration.php @@ -0,0 +1,65 @@ +<?php + +namespace Drupal\Tests\migrate_drupal_ui\Functional\d7; + +use Drupal\workflows\Entity\Workflow; +use Drupal\workflows\WorkflowInterface; + +/** + * Tests Drupal 7 upgrade using the migrate UI with Content Moderation. + * + * @group migrate_drupal_ui + */ +class Upgrade7TestWithContentModeration extends Upgrade7Test { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'content_moderation', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + // Set up a moderation flow. + $types = [ + 'blog', + 'et', + 'test_content_type', + ]; + foreach ($types as $type) { + $this->drupalCreateContentType(['type' => $type]); + } + + $editorial = Workflow::load('editorial'); + assert($editorial instanceof WorkflowInterface); + $type_settings = $editorial->getTypePlugin()->getConfiguration(); + $type_settings['default_moderation_state'] = 'published'; + $type_settings['entity_types']['node'] = array_merge( + ['article', 'forum'], + $types + ); + $type_plugin = $editorial->getTypePlugin(); + $type_plugin->setConfiguration($type_settings); + $editorial->trustData()->save(); + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + $entity_counts = parent::getEntityCounts() + [ + 'content_moderation_state' => 7, + 'workflow' => 1, + ]; + $entity_counts['entity_view_display'] = $entity_counts['entity_view_display'] + 1; + $entity_counts['field_config'] = $entity_counts['field_config'] + 2; + $entity_counts['view'] = $entity_counts['view'] + 1; + return $entity_counts; + } + +} -- GitLab