Chris@0: drupalCreateUser( Chris@0: [ Chris@0: 'view page revisions', Chris@0: 'revert page revisions', Chris@0: 'delete page revisions', Chris@0: 'edit any page content', Chris@17: 'delete any page content', Chris@0: ] Chris@0: ); Chris@0: $this->drupalLogin($web_user); Chris@0: Chris@0: // Create an initial node. Chris@0: $node = $this->drupalCreateNode(); Chris@0: Chris@16: // Create a user for revision authoring. Chris@16: // This must be different from user performing revert. Chris@16: $this->revisionUser = $this->drupalCreateUser(); Chris@16: Chris@0: $settings = get_object_vars($node); Chris@0: $settings['revision'] = 1; Chris@0: Chris@0: $nodes = []; Chris@0: $logs = []; Chris@0: Chris@0: // Get the original node. Chris@0: $nodes[] = clone $node; Chris@0: Chris@0: // Create three revisions. Chris@0: $revision_count = 3; Chris@0: for ($i = 0; $i < $revision_count; $i++) { Chris@0: $logs[] = $node->revision_log = $this->randomMachineName(32); Chris@0: Chris@0: $node = $this->createNodeRevision($node); Chris@0: $nodes[] = clone $node; Chris@0: } Chris@0: Chris@0: $this->nodes = $nodes; Chris@0: $this->revisionLogs = $logs; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates a new revision for a given node. Chris@0: * Chris@0: * @param \Drupal\node\NodeInterface $node Chris@0: * A node object. Chris@0: * Chris@0: * @return \Drupal\node\NodeInterface Chris@0: * A node object with up to date revision information. Chris@0: */ Chris@0: protected function createNodeRevision(NodeInterface $node) { Chris@0: // Create revision with a random title and body and update variables. Chris@0: $node->title = $this->randomMachineName(); Chris@0: $node->body = [ Chris@0: 'value' => $this->randomMachineName(32), Chris@0: 'format' => filter_default_format(), Chris@0: ]; Chris@0: $node->setNewRevision(); Chris@16: // Ensure the revision author is a different user. Chris@16: $node->setRevisionUserId($this->revisionUser->id()); Chris@0: $node->save(); Chris@0: Chris@0: return $node; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Checks node revision operations. Chris@0: */ Chris@0: public function testRevisions() { Chris@0: $node_storage = $this->container->get('entity.manager')->getStorage('node'); Chris@0: $nodes = $this->nodes; Chris@0: $logs = $this->revisionLogs; Chris@0: Chris@0: // Get last node for simple checks. Chris@0: $node = $nodes[3]; Chris@0: Chris@0: // Create and log in user. Chris@0: $content_admin = $this->drupalCreateUser( Chris@0: [ Chris@0: 'view all revisions', Chris@0: 'revert all revisions', Chris@0: 'delete all revisions', Chris@0: 'edit any page content', Chris@17: 'delete any page content', Chris@0: ] Chris@0: ); Chris@0: $this->drupalLogin($content_admin); Chris@0: Chris@0: // Confirm the correct revision text appears on "view revisions" page. Chris@0: $this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view"); Chris@0: $this->assertText($node->body->value, 'Correct text displays for version.'); Chris@0: Chris@0: // Confirm the correct revision log message appears on the "revisions Chris@0: // overview" page. Chris@0: $this->drupalGet("node/" . $node->id() . "/revisions"); Chris@0: foreach ($logs as $revision_log) { Chris@0: $this->assertText($revision_log, 'Revision log message found.'); Chris@0: } Chris@0: Chris@0: // Confirm that this is the current revision. Chris@0: $this->assertTrue($node->isDefaultRevision(), 'Third node revision is the current one.'); Chris@0: Chris@0: // Confirm that revisions revert properly. Chris@0: $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/revert", [], t('Revert')); Chris@0: $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', Chris@0: [ Chris@0: '@type' => 'Basic page', Chris@0: '%title' => $nodes[1]->getTitle(), Chris@18: '%revision-date' => $this->container->get('date.formatter')->format($nodes[1]->getRevisionCreationTime()), Chris@0: ]), Chris@0: 'Revision reverted.'); Chris@0: $node_storage->resetCache([$node->id()]); Chris@0: $reverted_node = $node_storage->load($node->id()); Chris@0: $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.'); Chris@0: Chris@16: // Confirm the revision author is the user performing the revert. Chris@16: $this->assertTrue($reverted_node->getRevisionUserId() == $this->loggedInUser->id(), 'Node revision author is user performing revert.'); Chris@16: // And that its not the revision author. Chris@16: $this->assertTrue($reverted_node->getRevisionUserId() != $this->revisionUser->id(), 'Node revision author is not original revision author.'); Chris@16: Chris@0: // Confirm that this is not the current version. Chris@0: $node = node_revision_load($node->getRevisionId()); Chris@0: $this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the current one.'); Chris@0: Chris@0: // Confirm that the node can still be updated. Chris@0: $this->drupalPostForm("node/" . $reverted_node->id() . "/edit", ['body[0][value]' => 'We are Drupal.'], t('Save')); Chris@0: $this->assertText(t('Basic page @title has been updated.', ['@title' => $reverted_node->getTitle()]), 'Node was successfully saved after reverting a revision.'); Chris@0: $this->assertText('We are Drupal.', 'Node was correctly updated after reverting a revision.'); Chris@0: Chris@0: // Confirm revisions delete properly. Chris@0: $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete')); Chris@0: $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', Chris@0: [ Chris@18: '%revision-date' => $this->container->get('date.formatter')->format($nodes[1]->getRevisionCreationTime()), Chris@0: '@type' => 'Basic page', Chris@0: '%title' => $nodes[1]->getTitle(), Chris@0: ]), Chris@0: 'Revision deleted.'); Chris@18: $connection = Database::getConnection(); Chris@0: $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', Chris@0: [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, Chris@0: 'Revision not found.'); Chris@0: Chris@0: // Set the revision timestamp to an older date to make sure that the Chris@0: // confirmation message correctly displays the stored revision date. Chris@0: $old_revision_date = REQUEST_TIME - 86400; Chris@18: $connection->update('node_revision') Chris@0: ->condition('vid', $nodes[2]->getRevisionId()) Chris@0: ->fields([ Chris@0: 'revision_timestamp' => $old_revision_date, Chris@0: ]) Chris@0: ->execute(); Chris@0: $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", [], t('Revert')); Chris@0: $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [ Chris@0: '@type' => 'Basic page', Chris@0: '%title' => $nodes[2]->getTitle(), Chris@18: '%revision-date' => $this->container->get('date.formatter')->format($old_revision_date), Chris@0: ])); Chris@0: Chris@0: // Create 50 more revisions in order to trigger paging on the revisions Chris@0: // overview screen. Chris@0: $node = $nodes[0]; Chris@0: for ($i = 0; $i < 50; $i++) { Chris@0: $logs[] = $node->revision_log = $this->randomMachineName(32); Chris@0: Chris@0: $node = $this->createNodeRevision($node); Chris@0: $nodes[] = clone $node; Chris@0: } Chris@0: Chris@0: $this->drupalGet('node/' . $node->id() . '/revisions'); Chris@0: Chris@0: // Check that the pager exists. Chris@0: $this->assertRaw('page=1'); Chris@0: Chris@0: // Check that the last revision is displayed on the first page. Chris@0: $this->assertText(end($logs)); Chris@0: Chris@0: // Go to the second page and check that one of the initial three revisions Chris@0: // is displayed. Chris@0: $this->clickLink(t('Page 2')); Chris@0: $this->assertText($logs[2]); Chris@0: } Chris@0: Chris@0: }