From 348ff90c8ef0fb5c861090b8484b873c8badae29 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Tue, 16 May 2017 13:44:54 +0100
Subject: [PATCH] Issue #2848508 by timmillwood, dragos-dumi, Sam152, Pavan B
 S, pradeep22saini: Reverting a revision causes validation error on edit form
 submit

---
 .../ModerationRevisionRevertTest.php          | 90 +++++++++++++++++++
 .../node/src/Form/NodeRevisionRevertForm.php  | 18 +++-
 .../NodeRevisionRevertTranslationForm.php     | 10 ++-
 3 files changed, 113 insertions(+), 5 deletions(-)
 create mode 100644 core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php

diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php
new file mode 100644
index 000000000000..7dac15667fbd
--- /dev/null
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Drupal\Tests\content_moderation\Functional;
+
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\workflows\Entity\Workflow;
+
+/**
+ * Test revision revert.
+ *
+ * @group content_moderation
+ */
+class ModerationRevisionRevertTest extends BrowserTestBase {
+
+  use ContentTypeCreationTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'content_moderation',
+    'node',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $moderated_bundle = $this->createContentType(['type' => 'moderated_bundle']);
+    $moderated_bundle->save();
+
+    $workflow = Workflow::load('editorial');
+    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated_bundle');
+    $workflow->save();
+
+    $admin = $this->drupalCreateUser([
+      'access content overview',
+      'administer nodes',
+      'bypass node access',
+      'view all revisions',
+      'view content moderation',
+      'use editorial transition create_new_draft',
+      'use editorial transition publish',
+    ]);
+    $this->drupalLogin($admin);
+  }
+
+  /**
+   * Test that reverting a revision works.
+   */
+  public function testEditingAfterRevertRevision() {
+    // Create a draft.
+    $this->drupalPostForm('node/add/moderated_bundle', ['title[0][value]' => 'First draft node'], t('Save and Create New Draft'));
+
+    // Now make it published.
+    $this->drupalPostForm('node/1/edit', ['title[0][value]' => 'Published node'], t('Save and Publish'));
+
+    // Check the editing form that show the published title.
+    $this->drupalGet('node/1/edit');
+    $this->assertSession()
+      ->pageTextContains('Published node');
+
+    // Revert the first revision.
+    $revision_url = 'node/1/revisions/1/revert';
+    $this->drupalGet($revision_url);
+    $this->assertSession()->elementExists('css', '.form-submit');
+    $this->click('.form-submit');
+
+    // Check that it reverted.
+    $this->drupalGet('node/1/edit');
+    $this->assertSession()
+      ->pageTextContains('First draft node');
+    // Try to save the node.
+    $this->click('.moderation-state-draft > input');
+
+    // Check if the submission passed the EntityChangedConstraintValidator.
+    $this->assertSession()
+      ->pageTextNotContains('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+
+    // Check the node has been saved.
+    $this->assertSession()
+      ->pageTextContains('moderated_bundle First draft node has been updated');
+  }
+
+}
diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php
index 09aab6f543f3..8137c3f4fa1d 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Form;
 
+use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Form\ConfirmFormBase;
@@ -36,6 +37,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
    */
   protected $dateFormatter;
 
+  /**
+   * The time service.
+   *
+   * @var \Drupal\Component\Datetime\TimeInterface
+   */
+  protected $time;
+
   /**
    * Constructs a new NodeRevisionRevertForm.
    *
@@ -43,10 +51,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
    *   The node storage.
    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
    *   The date formatter service.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
    */
-  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter) {
+  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, TimeInterface $time) {
     $this->nodeStorage = $node_storage;
     $this->dateFormatter = $date_formatter;
+    $this->time = $time;
   }
 
   /**
@@ -55,7 +66,8 @@ public function __construct(EntityStorageInterface $node_storage, DateFormatterI
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager')->getStorage('node'),
-      $container->get('date.formatter')
+      $container->get('date.formatter'),
+      $container->get('datetime.time')
     );
   }
 
@@ -114,6 +126,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     $this->revision = $this->prepareRevertedRevision($this->revision, $form_state);
     $this->revision->revision_log = t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]);
+    $this->revision->setRevisionCreationTime($this->time->getRequestTime());
+    $this->revision->setChangedTime($this->time->getRequestTime());
     $this->revision->save();
 
     $this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
diff --git a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
index fd20dadce138..d5da697abeb8 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Form;
 
+use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -37,9 +38,11 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
    *   The date formatter service.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
    */
-  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager) {
-    parent::__construct($node_storage, $date_formatter);
+  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager, TimeInterface $time) {
+    parent::__construct($node_storage, $date_formatter, $time);
     $this->languageManager = $language_manager;
   }
 
@@ -50,7 +53,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager')->getStorage('node'),
       $container->get('date.formatter'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('datetime.time')
     );
   }
 
-- 
GitLab