diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php index eaa4ad64d9..828461c104 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php @@ -42,6 +42,7 @@ class ContentModerationStateTest extends KernelTestBase { 'content_moderation', 'user', 'system', + 'taxonomy', 'language', 'content_translation', 'text', @@ -68,6 +69,7 @@ protected function setUp() { $this->installEntitySchema('block_content'); $this->installEntitySchema('media'); $this->installEntitySchema('file'); + $this->installEntitySchema('taxonomy_term'); $this->installEntitySchema('content_moderation_state'); $this->installConfig('content_moderation'); $this->installSchema('file', 'file_usage'); @@ -166,6 +168,9 @@ public function basicModerationTestCases() { 'Media' => [ 'media', ], + 'Taxonomy term' => [ + 'taxonomy_term', + ], 'Test entity - revisions, data table, and published interface' => [ 'entity_test_mulrevpub', ], @@ -254,7 +259,7 @@ public function testContentModerationStateTranslationDataRemoval($entity_type_id ConfigurableLanguage::createFromLangcode($langcode) ->save(); $entity->save(); - $translation = $entity->addTranslation($langcode, ['title' => 'Titolo test']); + $translation = $entity->addTranslation($langcode, [$entity->getEntityType()->getKey('label') => 'Titolo test']); // Make sure we add values for all of the required fields. if ($entity_type_id == 'block_content') { $translation->info = $this->randomString(); diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 1d724c2535..2164848c7c 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -80,16 +80,6 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) { } } -/** - * Implements hook_entity_type_alter(). - */ -function taxonomy_entity_type_alter(array &$entity_types) { - // @todo Moderation is disabled for taxonomy terms until when we have an UI - // for them. - // @see https://www.drupal.org/project/drupal/issues/2899923 - $entity_types['taxonomy_term']->setHandlerClass('moderation', ''); -} - /** * Entity URI callback. */ diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyTermContentModerationTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTermContentModerationTest.php new file mode 100644 index 0000000000..d604704867 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTermContentModerationTest.php @@ -0,0 +1,201 @@ +createEditorialWorkflow(); + + $this->drupalLogin($this->drupalCreateUser([ + 'administer taxonomy', + 'use editorial transition create_new_draft', + 'use editorial transition publish', + 'view any unpublished content', + 'view latest version', + ])); + + $this->vocabulary = $this->createVocabulary(); + + // Set the vocabulary as moderated. + $workflow = Workflow::load('editorial'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('taxonomy_term', $this->vocabulary->id()); + $workflow->save(); + } + + /** + * Tests taxonomy term parents on a moderated vocabulary. + */ + public function testTaxonomyTermParents() { + // Create a simple hierarchy in the vocabulary, a root term and three parent + // terms. + $root = $this->createTerm($this->vocabulary, ['langcode' => 'en', 'moderation_state' => 'published']); + $parent_1 = $this->createTerm($this->vocabulary, ['langcode' => 'en', 'moderation_state' => 'published', 'parent' => $root->id()]); + $parent_2 = $this->createTerm($this->vocabulary, ['langcode' => 'en', 'moderation_state' => 'published', 'parent' => $root->id()]); + $parent_3 = $this->createTerm($this->vocabulary, ['langcode' => 'en', 'moderation_state' => 'published', 'parent' => $root->id()]); + + // Create a child term and assign one of the parents above. + $child = $this->createTerm($this->vocabulary, ['langcode' => 'en', 'moderation_state' => 'published', 'parent' => $parent_1->id()]); + + $taxonomy_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term'); + $validation_message = 'You can only change the hierarchy for the published version of this term.'; + + // Add a pending revision without changing the term parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, ['moderation_state[0][state]' => 'draft'], 'Save'); + + $this->assertSession()->pageTextNotContains($validation_message); + + // Add a pending revision and change the parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'parent[]' => [$parent_2->id()], + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + // Check that parents were not changed. + $this->assertSession()->pageTextContains($validation_message); + $taxonomy_storage->resetCache(); + $this->assertEquals([$parent_1->id()], array_keys($taxonomy_storage->loadParents($child->id()))); + + // Add a pending revision and add a new parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'parent[]' => [$parent_1->id(), $parent_3->id()], + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + // Check that parents were not changed. + $this->assertSession()->pageTextContains($validation_message); + $taxonomy_storage->resetCache(); + $this->assertEquals([$parent_1->id()], array_keys($taxonomy_storage->loadParents($child->id()))); + + // Add a pending revision and use the root term as a parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'parent[]' => [$root->id()], + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + // Check that parents were not changed. + $this->assertSession()->pageTextContains($validation_message); + $taxonomy_storage->resetCache(); + $this->assertEquals([$parent_1->id()], array_keys($taxonomy_storage->loadParents($child->id()))); + + // Add a pending revision and remove the parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'parent[]' => [], + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + // Check that parents were not changed. + $this->assertSession()->pageTextContains($validation_message); + $taxonomy_storage->resetCache(); + $this->assertEquals([$parent_1->id()], array_keys($taxonomy_storage->loadParents($child->id()))); + + // Add a published revision and change the parent. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'parent[]' => [$parent_2->id()], + 'moderation_state[0][state]' => 'published', + ], 'Save'); + + // Check that parents were changed. + //$this->assertSession()->pageTextNotContains($validation_message); + $taxonomy_storage->resetCache(); + $this->assertEquals([$parent_2->id()], array_keys($taxonomy_storage->loadParents($child->id()))); + + // Add a pending revision and change the weight. + $this->drupalGet('taxonomy/term/' . $child->id() . '/edit'); + $this->drupalPostForm(NULL, [ + 'weight' => 10, + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + // Check that weight was not changed. + $this->assertSession()->pageTextContains($validation_message); + + // Add a new term without any parent and publish it. + $edit = [ + 'name[0][value]' => $this->randomMachineName(), + 'moderation_state[0][state]' => 'published', + ]; + $this->drupalPostForm("admin/structure/taxonomy/manage/{$this->vocabulary->id()}/add", $edit, 'Save'); + // Add a pending revision without any changes. + $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']); + $term = reset($terms); + $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', ['moderation_state[0][state]' => 'draft'], 'Save'); + $this->assertSession()->pageTextNotContains($validation_message); + } + + /** + * Tests changing field values in pending revisions of taxonomy terms. + */ + public function testTaxonomyTermPendingRevisions() { + $default_term_name = 'term - default revision'; + $default_term_description = 'The default revision of a term.'; + $term = $this->createTerm($this->vocabulary, [ + 'name' => $default_term_name, + 'description' => $default_term_description, + 'langcode' => 'en', + 'moderation_state' => 'published', + ]); + + // Add a pending revision without changing the term parent. + $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); + $this->assertSession()->pageTextContains($default_term_name); + $this->assertSession()->pageTextContains($default_term_description); + + // Check the revision log message field does not appear on the term edit + // page. + $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); + $this->assertSession()->fieldNotExists('revision_log_message[0][value]'); + + $pending_term_name = 'term - pending revision'; + $pending_term_description = 'The pending revision of a term.'; + $this->drupalPostForm(NULL, [ + 'name[0][value]' => $pending_term_name, + 'description[0][value]' => $pending_term_description, + 'moderation_state[0][state]' => 'draft', + ], 'Save'); + + $this->assertSession()->pageTextContains($pending_term_name); + $this->assertSession()->pageTextContains($pending_term_description); + $this->assertSession()->pageTextNotContains($default_term_description); + + // Check that the default revision of the term contains the correct values. + $this->drupalGet('taxonomy/term/' . $term->id()); + $this->assertSession()->pageTextContains($default_term_name); + $this->assertSession()->pageTextContains($default_term_description); + } + +}