diff --git a/core/modules/forum/config/optional/taxonomy.vocabulary.forums.yml b/core/modules/forum/config/optional/taxonomy.vocabulary.forums.yml index f9d41d3966..9999eb23f1 100644 --- a/core/modules/forum/config/optional/taxonomy.vocabulary.forums.yml +++ b/core/modules/forum/config/optional/taxonomy.vocabulary.forums.yml @@ -8,3 +8,4 @@ name: Forums vid: forums description: 'Forum navigation vocabulary' weight: -10 +new_revision: false diff --git a/core/modules/jsonapi/tests/src/Functional/VocabularyTest.php b/core/modules/jsonapi/tests/src/Functional/VocabularyTest.php index 6c177d90b5..1ee5dc65b0 100644 --- a/core/modules/jsonapi/tests/src/Functional/VocabularyTest.php +++ b/core/modules/jsonapi/tests/src/Functional/VocabularyTest.php @@ -88,6 +88,7 @@ protected function getExpectedDocument() { 'status' => TRUE, 'dependencies' => [], 'name' => 'Llama', + 'new_revision' => FALSE, 'description' => NULL, 'weight' => 0, 'drupal_internal__vid' => 'llama', diff --git a/core/modules/migrate/tests/modules/migrate_track_changes_test/config/install/taxonomy.vocabulary.track_changes_import_term.yml b/core/modules/migrate/tests/modules/migrate_track_changes_test/config/install/taxonomy.vocabulary.track_changes_import_term.yml index 8bbc5d7f04..78b8928087 100644 --- a/core/modules/migrate/tests/modules/migrate_track_changes_test/config/install/taxonomy.vocabulary.track_changes_import_term.yml +++ b/core/modules/migrate/tests/modules/migrate_track_changes_test/config/install/taxonomy.vocabulary.track_changes_import_term.yml @@ -5,3 +5,4 @@ name: Track changes import term vid: track_changes_import_term description: '' weight: 0 +new_revision: false diff --git a/core/modules/system/tests/modules/olivero_test/config/install/taxonomy.vocabulary.tags.yml b/core/modules/system/tests/modules/olivero_test/config/install/taxonomy.vocabulary.tags.yml index 4c754e86c7..0d0313cf6e 100644 --- a/core/modules/system/tests/modules/olivero_test/config/install/taxonomy.vocabulary.tags.yml +++ b/core/modules/system/tests/modules/olivero_test/config/install/taxonomy.vocabulary.tags.yml @@ -5,3 +5,4 @@ name: Tags vid: tags description: 'Use tags to group articles on similar topics into categories.' weight: 0 +new_revision: false diff --git a/core/modules/taxonomy/config/schema/taxonomy.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.schema.yml index 6b043b1778..47aeaa671e 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.schema.yml @@ -35,6 +35,9 @@ taxonomy.vocabulary.*: weight: type: integer label: 'Weight' + new_revision: + type: boolean + label: 'Whether a new revision should be created by default' field.formatter.settings.entity_reference_rss_category: type: mapping diff --git a/core/modules/taxonomy/src/Entity/Handler/TaxonomyModerationHandler.php b/core/modules/taxonomy/src/Entity/Handler/TaxonomyModerationHandler.php new file mode 100644 index 0000000000..872cd87f60 --- /dev/null +++ b/core/modules/taxonomy/src/Entity/Handler/TaxonomyModerationHandler.php @@ -0,0 +1,22 @@ +t('Revisions are required.'); + } + +} diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 234543aa68..faaad71ff3 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -32,7 +32,12 @@ * "views_data" = "Drupal\taxonomy\TermViewsData", * "form" = { * "default" = "Drupal\taxonomy\TermForm", - * "delete" = "Drupal\taxonomy\Form\TermDeleteForm" + * "delete" = "Drupal\taxonomy\Form\TermDeleteForm", + * "revision-delete" = \Drupal\Core\Entity\Form\RevisionDeleteForm::class, + * "revision-revert" = \Drupal\Core\Entity\Form\RevisionRevertForm::class, + * }, + * "route_provider" = { + * "revision" = \Drupal\Core\Entity\Routing\RevisionHtmlRouteProvider::class, * }, * "translation" = "Drupal\taxonomy\TermTranslationHandler" * }, @@ -40,6 +45,7 @@ * data_table = "taxonomy_term_field_data", * revision_table = "taxonomy_term_revision", * revision_data_table = "taxonomy_term_field_revision", + * show_revision_ui = TRUE, * translatable = TRUE, * entity_keys = { * "id" = "tid", @@ -63,6 +69,10 @@ * "delete-form" = "/taxonomy/term/{taxonomy_term}/delete", * "edit-form" = "/taxonomy/term/{taxonomy_term}/edit", * "create" = "/taxonomy/term", + * "revision" = "/taxonomy/term/{taxonomy_term}/revision/{taxonomy_term_revision}/view", + * "revision-delete-form" = "/taxonomy/term/{taxonomy_term}/revision/{taxonomy_term_revision}/delete", + * "revision-revert-form" = "/taxonomy/term/{taxonomy_term}/revision/{taxonomy_term_revision}/revert", + * "version-history" = "/taxonomy/term/{taxonomy_term}/revisions", * }, * permission_granularity = "bundle", * collection_permission = "access taxonomy overview", diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index aec8c8f0e3..5bd8208057 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -32,7 +32,8 @@ * "route_provider" = { * "html" = "Drupal\taxonomy\Entity\Routing\VocabularyRouteProvider", * "permissions" = "Drupal\user\Entity\EntityPermissionsRouteProvider", - * } + * }, + * "moderation" = "Drupal\taxonomy\Entity\Handler\TaxonomyModerationHandler" * }, * admin_permission = "administer taxonomy", * collection_permission = "access taxonomy overview", @@ -57,6 +58,7 @@ * "vid", * "description", * "weight", + * "new_revision", * } * ) */ @@ -104,6 +106,13 @@ public function getDescription() { return $this->description; } + /** + * The default revision setting for a vocabulary. + * + * @var bool + */ + protected $new_revision = FALSE; + /** * {@inheritdoc} */ @@ -161,4 +170,18 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti } } + /** + * {@inheritdoc} + */ + public function setNewRevision($new_revision) { + $this->new_revision = $new_revision; + } + + /** + * {@inheritdoc} + */ + public function shouldCreateNewRevision() { + return $this->new_revision; + } + } diff --git a/core/modules/taxonomy/src/TaxonomyPermissions.php b/core/modules/taxonomy/src/TaxonomyPermissions.php index 054b638a7a..06e3e6fa31 100644 --- a/core/modules/taxonomy/src/TaxonomyPermissions.php +++ b/core/modules/taxonomy/src/TaxonomyPermissions.php @@ -69,6 +69,15 @@ protected function buildPermissions(VocabularyInterface $vocabulary) { "create terms in $id" => ['title' => $this->t('%vocabulary: Create terms', $args)], "delete terms in $id" => ['title' => $this->t('%vocabulary: Delete terms', $args)], "edit terms in $id" => ['title' => $this->t('%vocabulary: Edit terms', $args)], + "view term revisions in $id" => ['title' => $this->t('%vocabulary: View term revisions', $args)], + "revert term revisions in $id" => [ + 'title' => $this->t('%vocabulary: Revert term revisions', $args), + 'description' => $this->t('To revert a revision you also need permission to edit the taxonomy term.'), + ], + "delete term revisions in $id" => [ + 'title' => $this->t('%vocabulary: Delete term revisions', $args), + 'description' => $this->t('To delete a revision you also need permission to delete the taxonomy term.'), + ], ]; } diff --git a/core/modules/taxonomy/src/TermAccessControlHandler.php b/core/modules/taxonomy/src/TermAccessControlHandler.php index b25dca4627..e774eab6cd 100644 --- a/core/modules/taxonomy/src/TermAccessControlHandler.php +++ b/core/modules/taxonomy/src/TermAccessControlHandler.php @@ -46,6 +46,25 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter return AccessResult::neutral()->setReason("The following permissions are required: 'delete terms in {$entity->bundle()}' OR 'administer taxonomy'."); + case 'view revision': + case 'view all revisions': + if ($account->hasPermission("view term revisions in {$entity->bundle()}") || $account->hasPermission("view all taxonomy revisions")) { + return AccessResult::allowed()->cachePerPermissions(); + } + return AccessResult::neutral()->setReason("The following permissions are required: 'view revisions in {$entity->bundle()}' OR 'view all taxonomy revisions'."); + + case 'revert': + if (($account->hasPermission("revert term revisions in {$entity->bundle()}") && $account->hasPermission("edit terms in {$entity->bundle()}")) || $account->hasPermission("revert all taxonomy revisions")) { + return AccessResult::allowed()->cachePerPermissions(); + } + return AccessResult::neutral()->setReason("The following permissions are required: 'revert term revisions in {$entity->bundle()}' OR 'revert all taxonomy revisions'."); + + case 'delete revision': + if (($account->hasPermission("delete term revisions in {$entity->bundle()}") && $account->hasPermission("delete terms in {$entity->bundle()}")) || $account->hasPermission("delete all taxonomy revisions")) { + return AccessResult::allowed()->cachePerPermissions(); + } + return AccessResult::neutral()->setReason("The following permissions are required: 'delete term revisions in {$entity->bundle()}' OR 'delete all taxonomy revisions'."); + default: // No opinion. return AccessResult::neutral()->cachePerPermissions(); diff --git a/core/modules/taxonomy/src/VocabularyForm.php b/core/modules/taxonomy/src/VocabularyForm.php index a9e13b8b93..c91bf953c8 100644 --- a/core/modules/taxonomy/src/VocabularyForm.php +++ b/core/modules/taxonomy/src/VocabularyForm.php @@ -76,6 +76,13 @@ public function form(array $form, FormStateInterface $form_state) { '#default_value' => $vocabulary->getDescription(), ]; + $form['revision'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Create new revision'), + '#default_value' => $vocabulary->shouldCreateNewRevision(), + '#description' => $this->t('Create a new revision by default for this vocabulary.'), + ]; + // $form['langcode'] is not wrapped in an // if ($this->moduleHandler->moduleExists('language')) check because the // language_select form element works also without the language module being @@ -117,6 +124,7 @@ public function form(array $form, FormStateInterface $form_state) { */ public function save(array $form, FormStateInterface $form_state) { $vocabulary = $this->entity; + $vocabulary->setNewRevision($form_state->getValue(['revision'])); // Prevent leading and trailing spaces in vocabulary names. $vocabulary->set('name', trim($vocabulary->label())); diff --git a/core/modules/taxonomy/src/VocabularyInterface.php b/core/modules/taxonomy/src/VocabularyInterface.php index ce64ef7da2..62fc3acc95 100644 --- a/core/modules/taxonomy/src/VocabularyInterface.php +++ b/core/modules/taxonomy/src/VocabularyInterface.php @@ -3,11 +3,12 @@ namespace Drupal\taxonomy; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\RevisionableEntityBundleInterface; /** * Provides an interface defining a taxonomy vocabulary entity. */ -interface VocabularyInterface extends ConfigEntityInterface { +interface VocabularyInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface { /** * Denotes that no term in the vocabulary has a parent. diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install index b03fda2ac4..3912169c3e 100644 --- a/core/modules/taxonomy/taxonomy.install +++ b/core/modules/taxonomy/taxonomy.install @@ -5,9 +5,33 @@ * Install, update and uninstall functions for the taxonomy module. */ +use Drupal\Core\Entity\Form\RevisionDeleteForm; +use Drupal\Core\Entity\Form\RevisionRevertForm; +use Drupal\Core\Entity\Routing\RevisionHtmlRouteProvider; +use Drupal\Core\StringTranslation\TranslatableMarkup; + /** * Implements hook_update_last_removed(). */ function taxonomy_update_last_removed() { return 8702; } + +/** + * Update entity definition to handle revision routes. + */ +function taxonomy_update_10100(&$sandbox = NULL): TranslatableMarkup { + $entityDefinitionUpdateManager = \Drupal::entityDefinitionUpdateManager(); + $definition = $entityDefinitionUpdateManager->getEntityType('taxonomy_term'); + $routeProviders = $definition->get('route_provider'); + $routeProviders['revision'] = RevisionHtmlRouteProvider::class; + $definition + ->setFormClass('revision-delete', RevisionDeleteForm::class) + ->setFormClass('revision-revert', RevisionRevertForm::class) + ->set('route_provider', $routeProviders) + ->setLinkTemplate('revision-delete-form', '/taxonomy/term/{taxonomy_term}/revision/{taxonomy_term}/delete') + ->setLinkTemplate('revision-revert-form', '/taxonomy/term/{taxonomy_term}/revision/{taxonomy_term}/revert') + ->setLinkTemplate('version-history', '/taxonomy/term/{taxonomy_term}/revisions'); + $entityDefinitionUpdateManager->updateEntityType($definition); + return \t('Added revision routes to Taxonomy Term entity type.'); +} diff --git a/core/modules/taxonomy/taxonomy.permissions.yml b/core/modules/taxonomy/taxonomy.permissions.yml index bb71e93c12..8ec7ab626c 100644 --- a/core/modules/taxonomy/taxonomy.permissions.yml +++ b/core/modules/taxonomy/taxonomy.permissions.yml @@ -5,5 +5,14 @@ access taxonomy overview: title: 'Access the taxonomy vocabulary overview page' description: 'Get an overview of all taxonomy vocabularies.' +revert all taxonomy revisions: + title: 'Revert all term revisions' + +delete all taxonomy revisions: + title: 'Delete all term revisions' + +view all taxonomy revisions: + title: 'View all term revisions' + permission_callbacks: - Drupal\taxonomy\TaxonomyPermissions::permissions diff --git a/core/modules/taxonomy/taxonomy.post_update.php b/core/modules/taxonomy/taxonomy.post_update.php index 6b5fefe6d0..0a8cc89090 100644 --- a/core/modules/taxonomy/taxonomy.post_update.php +++ b/core/modules/taxonomy/taxonomy.post_update.php @@ -5,6 +5,8 @@ * Post update functions for Taxonomy. */ +use Drupal\Core\Config\Entity\ConfigEntityUpdater; + /** * Implements hook_removed_post_updates(). */ @@ -19,3 +21,13 @@ function taxonomy_removed_post_updates() { 'taxonomy_post_update_clear_views_argument_validator_plugins_cache' => '10.0.0', ]; } + +/** + * Re-save Taxonomy configurations with new_revision config. + */ +function taxonomy_post_update_set_new_revision(&$sandbox = NULL) { + \Drupal::classResolver(ConfigEntityUpdater::class) + ->update($sandbox, 'taxonomy_vocabulary', function () { + return TRUE; + }); +} diff --git a/core/modules/taxonomy/tests/src/Functional/Rest/VocabularyResourceTestBase.php b/core/modules/taxonomy/tests/src/Functional/Rest/VocabularyResourceTestBase.php index de8e7a5804..ebd4bba71d 100644 --- a/core/modules/taxonomy/tests/src/Functional/Rest/VocabularyResourceTestBase.php +++ b/core/modules/taxonomy/tests/src/Functional/Rest/VocabularyResourceTestBase.php @@ -55,6 +55,7 @@ protected function getExpectedNormalizedEntity() { 'name' => 'Llama', 'description' => NULL, 'weight' => 0, + 'new_revision' => FALSE, ]; } diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionDeleteTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionDeleteTest.php new file mode 100644 index 0000000000..9eb7ab9571 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionDeleteTest.php @@ -0,0 +1,112 @@ +vocabulary = $this->createVocabulary(['vid' => 'test', 'name' => 'Test']); + } + + /** + * Tests revision delete. + */ + public function testDeleteForm(): void { + $termName = $this->randomMachineName(); + $entity = Term::create([ + 'vid' => $this->vocabulary->id(), + 'name' => $termName, + ]); + + $entity->setRevisionCreationTime((new \DateTimeImmutable('11 January 2009 4pm'))->getTimestamp()) + ->setRevisionTranslationAffected(TRUE); + $entity->setNewRevision(); + $entity->save(); + $revisionId = $entity->getRevisionId(); + + $this->drupalLogin($this->drupalCreateUser($this->permissions)); + + // Cannot delete latest revision. + $this->drupalGet($entity->toUrl('revision-delete-form')); + $this->assertSession()->statusCodeEquals(403); + + // Create a new latest revision. + $entity + ->setRevisionCreationTime((new \DateTimeImmutable('11 January 2009 5pm'))->getTimestamp()) + ->setRevisionTranslationAffected(TRUE) + ->setNewRevision(); + $entity->save(); + + // Reload the entity. + $revision = \Drupal::entityTypeManager()->getStorage('taxonomy_term') + ->loadRevision($revisionId); + $this->drupalGet($revision->toUrl('revision-delete-form')); + $this->assertSession()->pageTextContains('Are you sure you want to delete the revision from Sun, 01/11/2009 - 16:00?'); + $this->assertSession()->buttonExists('Delete'); + $this->assertSession()->linkExists('Cancel'); + + $countRevisions = static function (): int { + return (int) \Drupal::entityTypeManager()->getStorage('taxonomy_term') + ->getQuery() + ->accessCheck(FALSE) + ->allRevisions() + ->count() + ->execute(); + }; + + $count = $countRevisions(); + $this->submitForm([], 'Delete'); + $this->assertEquals($count - 1, $countRevisions()); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->addressEquals(sprintf('taxonomy/term/%s/revisions', $entity->id())); + $this->assertSession()->pageTextContains(sprintf('Revision from Sun, 01/11/2009 - 16:00 of Test %s has been deleted.', $termName)); + $this->assertSession()->elementsCount('css', 'table tbody tr', 1); + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionRevertTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionRevertTest.php new file mode 100644 index 0000000000..32a2d4041f --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionRevertTest.php @@ -0,0 +1,112 @@ +vocabulary = $this->createVocabulary(['vid' => 'test', 'name' => 'Test']); + } + + /** + * Tests revision revert. + */ + public function testRevertForm(): void { + $termName = $this->randomMachineName(); + $entity = Term::create([ + 'vid' => $this->vocabulary->id(), + 'name' => $termName, + ]); + + $entity->setRevisionCreationTime((new \DateTimeImmutable('11 January 2009 4pm'))->getTimestamp()) + ->setRevisionTranslationAffected(TRUE); + $entity->setNewRevision(); + $entity->save(); + $revisionId = $entity->getRevisionId(); + + $this->drupalLogin($this->drupalCreateUser($this->permissions)); + + // Cannot revert latest revision. + $this->drupalGet($entity->toUrl('revision-revert-form')); + $this->assertSession()->statusCodeEquals(403); + + // Create a new latest revision. + $entity + ->setRevisionCreationTime((new \DateTimeImmutable('11 January 2009 5pm'))->getTimestamp()) + ->setRevisionTranslationAffected(TRUE) + ->setNewRevision(); + $entity->save(); + + // Reload the entity. + $revision = \Drupal::entityTypeManager()->getStorage('taxonomy_term') + ->loadRevision($revisionId); + $this->drupalGet($revision->toUrl('revision-revert-form')); + $this->assertSession()->pageTextContains('Are you sure you want to revert to the revision from Sun, 01/11/2009 - 16:00?'); + $this->assertSession()->buttonExists('Revert'); + $this->assertSession()->linkExists('Cancel'); + + $countRevisions = static function (): int { + return (int) \Drupal::entityTypeManager()->getStorage('taxonomy_term') + ->getQuery() + ->accessCheck(FALSE) + ->allRevisions() + ->count() + ->execute(); + }; + + $count = $countRevisions(); + $this->submitForm([], 'Revert'); + $this->assertEquals($count + 1, $countRevisions()); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->addressEquals(sprintf('taxonomy/term/%s/revisions', $entity->id())); + $this->assertSession()->pageTextContains(sprintf('Test %s has been reverted to the revision from Sun, 01/11/2009 - 16:00.', $termName)); + $this->assertSession()->elementsCount('css', 'table tbody tr', 3); + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionTest.php new file mode 100644 index 0000000000..44e17c71e0 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionTest.php @@ -0,0 +1,58 @@ +assertSession(); + $vocabulary1 = $this->createVocabulary(['new_revision' => TRUE]); + $vocabulary2 = $this->createVocabulary(['new_revision' => FALSE]); + $user = $this->createUser([ + 'administer taxonomy', + ]); + $term1 = $this->createTerm($vocabulary1); + $term2 = $this->createTerm($vocabulary2); + + // Create some revisions so revision checkbox is visible. + $term1 = $this->createTaxonomyTermRevision($term1); + $term2 = $this->createTaxonomyTermRevision($term2); + $this->drupalLogin($user); + $this->drupalGet($term1->toUrl('edit-form')); + $assert->statusCodeEquals(200); + $assert->checkboxChecked('Create new revision'); + $this->drupalGet($term2->toUrl('edit-form')); + $assert->statusCodeEquals(200); + $assert->checkboxNotChecked('Create new revision'); + + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionVersionHistoryTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionVersionHistoryTest.php new file mode 100644 index 0000000000..c9e1c3f8f6 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyRevisionVersionHistoryTest.php @@ -0,0 +1,119 @@ +vocabulary = $this->createVocabulary(['vid' => 'test', 'name' => 'Test']); + } + + /** + * Tests version history page. + */ + public function testVersionHistory(): void { + $entity = Term::create([ + 'vid' => $this->vocabulary->id(), + 'name' => 'Test taxonomy term', + ]); + + $entity + ->setDescription('Description 1') + ->setRevisionCreationTime((new \DateTimeImmutable('1st June 2020 7am'))->getTimestamp()) + ->setRevisionLogMessage('first revision log') + ->setRevisionUser($this->drupalCreateUser(name: 'first author')) + ->setNewRevision(); + $entity->save(); + + $entity + ->setDescription('Description 2') + ->setRevisionCreationTime((new \DateTimeImmutable('2nd June 2020 8am'))->getTimestamp()) + ->setRevisionLogMessage('second revision log') + ->setRevisionUser($this->drupalCreateUser(name: 'second author')) + ->setNewRevision(); + $entity->save(); + + $entity + ->setDescription('Description 3') + ->setRevisionCreationTime((new \DateTimeImmutable('3rd June 2020 9am'))->getTimestamp()) + ->setRevisionLogMessage('third revision log') + ->setRevisionUser($this->drupalCreateUser(name: 'third author')) + ->setNewRevision(); + $entity->save(); + + $this->drupalLogin($this->drupalCreateUser($this->permissions)); + $this->drupalGet($entity->toUrl('version-history')); + $this->assertSession()->elementsCount('css', 'table tbody tr', 3); + + // Order is newest to oldest revision by creation order. + $row1 = $this->assertSession()->elementExists('css', 'table tbody tr:nth-child(1)'); + // Latest revision does not have revert or delete revision operation. + $this->assertSession()->elementNotExists('named', ['link', 'Revert'], $row1); + $this->assertSession()->elementNotExists('named', ['link', 'Delete'], $row1); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(1)', 'Current revision'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(1)', 'third revision log'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(1)', '06/03/2020 - 09:00 by third author'); + + $row2 = $this->assertSession()->elementExists('css', 'table tbody tr:nth-child(2)'); + $this->assertSession()->elementExists('named', ['link', 'Revert'], $row2); + $this->assertSession()->elementExists('named', ['link', 'Delete'], $row2); + $this->assertSession()->elementTextNotContains('css', 'table tbody tr:nth-child(2)', 'Current revision'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(2)', 'second revision log'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(2)', '06/02/2020 - 08:00 by second author'); + + $row3 = $this->assertSession()->elementExists('css', 'table tbody tr:nth-child(3)'); + $this->assertSession()->elementExists('named', ['link', 'Revert'], $row3); + $this->assertSession()->elementExists('named', ['link', 'Delete'], $row3); + $this->assertSession()->elementTextNotContains('css', 'table tbody tr:nth-child(2)', 'Current revision'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(3)', 'first revision log'); + $this->assertSession()->elementTextContains('css', 'table tbody tr:nth-child(3)', '06/01/2020 - 07:00 by first author'); + } + +} diff --git a/core/modules/taxonomy/tests/src/Traits/TaxonomyTestTrait.php b/core/modules/taxonomy/tests/src/Traits/TaxonomyTestTrait.php index 4df0f1a293..99d0f764e4 100644 --- a/core/modules/taxonomy/tests/src/Traits/TaxonomyTestTrait.php +++ b/core/modules/taxonomy/tests/src/Traits/TaxonomyTestTrait.php @@ -5,6 +5,7 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\taxonomy\Entity\Term; +use Drupal\taxonomy\TermInterface; use Drupal\taxonomy\VocabularyInterface; /** @@ -61,4 +62,20 @@ public function createTerm(VocabularyInterface $vocabulary, $values = []) { return $term; } + /** + * Creates a new revision for a given taxonomy term. + * + * @param \Drupal\taxonomy\TermInterface $term + * A micro-content object. + * + * @return \Drupal\taxonomy\TermInterface + * The new taxonomy term object. + */ + protected function createTaxonomyTermRevision(TermInterface $term) { + $term->set('name', $this->randomMachineName()); + $term->setNewRevision(); + $term->save(); + return $term; + } + } diff --git a/core/profiles/demo_umami/config/install/taxonomy.vocabulary.recipe_category.yml b/core/profiles/demo_umami/config/install/taxonomy.vocabulary.recipe_category.yml index b24b94a7f0..2927b77573 100644 --- a/core/profiles/demo_umami/config/install/taxonomy.vocabulary.recipe_category.yml +++ b/core/profiles/demo_umami/config/install/taxonomy.vocabulary.recipe_category.yml @@ -5,3 +5,4 @@ name: 'Recipe category' vid: recipe_category description: 'Use this taxonomy to group recipes of the same type together.' weight: 0 +new_revision: false diff --git a/core/profiles/demo_umami/config/install/taxonomy.vocabulary.tags.yml b/core/profiles/demo_umami/config/install/taxonomy.vocabulary.tags.yml index 4c754e86c7..0d0313cf6e 100644 --- a/core/profiles/demo_umami/config/install/taxonomy.vocabulary.tags.yml +++ b/core/profiles/demo_umami/config/install/taxonomy.vocabulary.tags.yml @@ -5,3 +5,4 @@ name: Tags vid: tags description: 'Use tags to group articles on similar topics into categories.' weight: 0 +new_revision: false diff --git a/core/profiles/nightwatch_a11y_testing/config/install/taxonomy.vocabulary.tags.yml b/core/profiles/nightwatch_a11y_testing/config/install/taxonomy.vocabulary.tags.yml index 4c754e86c7..0d0313cf6e 100644 --- a/core/profiles/nightwatch_a11y_testing/config/install/taxonomy.vocabulary.tags.yml +++ b/core/profiles/nightwatch_a11y_testing/config/install/taxonomy.vocabulary.tags.yml @@ -5,3 +5,4 @@ name: Tags vid: tags description: 'Use tags to group articles on similar topics into categories.' weight: 0 +new_revision: false diff --git a/core/profiles/standard/config/install/taxonomy.vocabulary.tags.yml b/core/profiles/standard/config/install/taxonomy.vocabulary.tags.yml index 4c754e86c7..0d0313cf6e 100644 --- a/core/profiles/standard/config/install/taxonomy.vocabulary.tags.yml +++ b/core/profiles/standard/config/install/taxonomy.vocabulary.tags.yml @@ -5,3 +5,4 @@ name: Tags vid: tags description: 'Use tags to group articles on similar topics into categories.' weight: 0 +new_revision: false