--- /dev/null
+<?php
+
+namespace Drupal\Tests\content_moderation\Functional;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Test updating the ContentModerationState entity default revisions.
+ *
+ * @group Update
+ * @see content_moderation_post_update_update_cms_default_revisions
+ */
+class DefaultContentModerationStateRevisionUpdateTest extends UpdatePathTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setDatabaseDumpFiles() {
+ $this->databaseDumpFiles = [
+ __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz',
+ __DIR__ . '/../../fixtures/update/drupal-8.4.0-content_moderation_installed.php',
+ __DIR__ . '/../../fixtures/update/drupal-8.default-cms-entity-id-2941736.php',
+ ];
+ }
+
+ /**
+ * Test updating the default revision.
+ */
+ public function testUpdateDefaultRevision() {
+ $this->runUpdates();
+
+ foreach (['node', 'block_content'] as $entity_type_id) {
+ $draft_pending_revision = $this->getEntityByLabel($entity_type_id, 'draft pending revision');
+ $this->assertFalse($draft_pending_revision->isLatestRevision());
+ $this->assertCompositeEntityMatchesDefaultRevisionId($draft_pending_revision);
+
+ $published_default_revision = $this->getEntityByLabel($entity_type_id, 'published default revision');
+ $this->assertTrue($published_default_revision->isLatestRevision());
+ $this->assertCompositeEntityMatchesDefaultRevisionId($published_default_revision);
+
+ $archived_default_revision = $this->getEntityByLabel($entity_type_id, 'archived default revision');
+ $this->assertTrue($archived_default_revision->isLatestRevision());
+ $this->assertCompositeEntityMatchesDefaultRevisionId($archived_default_revision);
+ }
+ }
+
+ /**
+ * Assert for the given entity, the default revision ID matches.
+ *
+ * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+ * The entity to use for the assertion.
+ */
+ protected function assertCompositeEntityMatchesDefaultRevisionId(ContentEntityInterface $entity) {
+ $entity_type_manager = $this->container->get('entity_type.manager');
+ $entity_list = $entity_type_manager->getStorage('content_moderation_state')
+ ->loadByProperties([
+ 'content_entity_type_id' => $entity->getEntityTypeId(),
+ 'content_entity_id' => $entity->id(),
+ ]);
+ $content_moderation_state_entity = array_shift($entity_list);
+ $this->assertEquals($entity->getLoadedRevisionId(), $content_moderation_state_entity->content_entity_revision_id->value);
+
+ // Check that the data table records were updated correctly.
+ /** @var \Drupal\Core\Database\Connection $database */
+ $database = $this->container->get('database');
+ $query = 'SELECT * FROM {content_moderation_state_field_data} WHERE id = :id';
+ $records = $database->query($query, [':id' => $content_moderation_state_entity->id()])
+ ->fetchAllAssoc('langcode');
+ foreach ($records as $langcode => $record) {
+ /** @var \Drupal\Core\Entity\ContentEntityInterface $translation */
+ $translation = $content_moderation_state_entity->getTranslation($langcode);
+ foreach ((array) $record as $field_name => $value) {
+ if ($translation->hasField($field_name)) {
+ $items = $translation->get($field_name)->getValue();
+ $this->assertEquals(current($items[0]), $value);
+ }
+ }
+ }
+ }
+
+ /**
+ * Load an entity by label.
+ *
+ * @param string $entity_type_id
+ * The entity type ID.
+ * @param string $label
+ * The label of the entity to load.
+ *
+ * @return \Drupal\Core\Entity\ContentEntityInterface
+ * The loaded entity.
+ */
+ protected function getEntityByLabel($entity_type_id, $label) {
+ $entity_type_manager = $this->container->get('entity_type.manager');
+ $label_field = $entity_type_manager->getDefinition($entity_type_id)->getKey('label');
+ $entity_list = $entity_type_manager->getStorage($entity_type_id)
+ ->loadByProperties([$label_field => $label]);
+ return array_shift($entity_list);
+ }
+
+}