diff --git a/core/modules/content_moderation/src/StateTransitionValidation.php b/core/modules/content_moderation/src/StateTransitionValidation.php index f5fc429edf..914410f798 100644 --- a/core/modules/content_moderation/src/StateTransitionValidation.php +++ b/core/modules/content_moderation/src/StateTransitionValidation.php @@ -42,7 +42,7 @@ public function __construct(ModerationInformationInterface $moderation_info) { */ public function getValidTransitions(ContentEntityInterface $entity, AccountInterface $user) { $workflow = $this->moderationInfo->getWorkflowForEntity($entity); - $current_state = !$entity->isNew() && $entity->moderation_state->value ? $workflow->getTypePlugin()->getState($entity->moderation_state->value) : $workflow->getTypePlugin()->getInitialState($entity); + $current_state = $entity->moderation_state->value ? $workflow->getTypePlugin()->getState($entity->moderation_state->value) : $workflow->getTypePlugin()->getInitialState($entity); return array_filter($current_state->getTransitions(), function (Transition $transition) use ($workflow, $user) { return $user->hasPermission('use ' . $workflow->id() . ' transition ' . $transition->id()); diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php index 74403fe9f9..3b129b0e9e 100644 --- a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php +++ b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php @@ -110,6 +110,15 @@ public function testModerationForm() { $this->drupalGet($edit_path); $this->assertFieldByName('moderation_state[0][state]', 'published', 'The moderation default value is set correctly.'); + // Preview the content while selecting the "draft" state and when the user + // returns to the edit form, ensure all of the available transitions are + // still those available from the "published" source state. + $this->submitForm(['moderation_state[0][state]' => 'draft'], 'Preview'); + $this->clickLink('Back to content editing'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'draft'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'published'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'archived'); + // The published view should not have a moderation form, because it is the // live revision. $this->drupalGet($canonical_path); @@ -306,6 +315,16 @@ public function testContentTranslationNodeForm() { $this->assertSession()->optionExists('moderation_state[0][state]', 'draft'); $this->assertSession()->optionExists('moderation_state[0][state]', 'published'); $this->assertSession()->optionExists('moderation_state[0][state]', 'archived'); + + // Preview the content while selecting the "draft" state and when the user + // returns to the edit form, ensure all of the available transitions are + // still those available from the "published" source state. + $this->submitForm(['moderation_state[0][state]' => 'draft'], 'Preview'); + $this->clickLink('Back to content editing'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'draft'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'published'); + $this->assertSession()->optionExists('moderation_state[0][state]', 'archived'); + $this->drupalPostForm(NULL, [ 'body[0][value]' => 'Third version of the content.', 'moderation_state[0][state]' => 'draft', @@ -520,135 +539,5 @@ public function testWorkflowInUse() { } } - /** - * Test current state and available transitions after preview. - */ - public function testModerationStateAfterPreview() { - // Create new moderated content in draft. - $this->drupalPostForm('node/add/moderated_content', [ - 'title[0][value]' => 'Some moderated content', - 'body[0][value]' => 'First version of the content.', - 'moderation_state[0][state]' => 'draft', - ], t('Save')); - - $node = $this->drupalGetNodeByTitle('Some moderated content'); - $edit_path = sprintf('node/%d/edit', $node->id()); - - // Publish the entity. - $edit = ['moderation_state[0][state]' => 'published']; - $this->drupalPostForm($edit_path, $edit, t('Save')); - - // Create pending draft revision. - $this->drupalPostForm($edit_path, [ - 'title[0][value]' => 'Second revision ', - 'moderation_state[0][state]' => 'draft', - ], t('Save')); - - // Change state to published and preview the change. - $edit = ['moderation_state[0][state]' => 'published']; - $this->drupalPostForm($edit_path, $edit, t('Preview')); - - // Go back to edit form. - $this->clickLink(t('Back to content editing')); - - // Confirm no new transitions exist. - $this->assertSession()->optionExists('moderation_state[0][state]', 'draft'); - $this->assertSession()->optionExists('moderation_state[0][state]', 'published'); - $this->assertSession()->optionNotExists('moderation_state[0][state]', 'archived'); - - // Confirm the current state is Draft and not Published. - $this->assertSession()->pageTextContains('Current state Draft'); - $selected_option = $this->xpath("//select[@name='moderation_state[0][state]']/option[@selected='selected']"); - $this->assertEquals('published', $selected_option[0]->getValue()); - - // Publish the entity. - $edit = ['moderation_state[0][state]' => 'published']; - $this->drupalPostForm($edit_path, $edit, t('Save')); - - // Confirm the current state is Published and not Draft. - $this->drupalGet($edit_path); - $this->assertSession()->pageTextContains('Current state Published'); - - // Create pending draft revision. - $this->drupalPostForm($edit_path, [ - 'title[0][value]' => 'Third revision ', - 'moderation_state[0][state]' => 'draft', - ], t('Save')); - - // Confirm the current state is Draft and not Published. - $this->drupalGet($edit_path); - $this->assertSession()->pageTextContains('Current state Draft'); - } - - /** - * Tests translated and moderated nodes. - */ - public function testTranslatedStateAfterPreview() { - $this->drupalLogin($this->rootUser); - - // Add French language. - $edit = ['predefined_langcode' => 'fr']; - $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); - - // Enable content translation on articles. - $this->drupalGet('admin/config/regional/content-language'); - $edit = [ - 'entity_types[node]' => TRUE, - 'settings[node][moderated_content][translatable]' => TRUE, - 'settings[node][moderated_content][settings][language][language_alterable]' => TRUE, - ]; - $this->drupalPostForm(NULL, $edit, t('Save configuration')); - - // Adding languages requires a container rebuild in the test running - // environment so that multilingual services are used. - $this->rebuildContainer(); - - // Create new moderated content in draft (revision 1). - $this->drupalPostForm('node/add/moderated_content', [ - 'title[0][value]' => 'Some moderated content', - 'body[0][value]' => 'First version of the content.', - 'moderation_state[0][state]' => 'draft', - ], t('Save')); - $this->assertTrue($this->xpath('//ul[@class="entity-moderation-form"]')); - - $node = $this->drupalGetNodeByTitle('Some moderated content'); - $this->assertTrue($node->language(), 'en'); - $fr_edit_path = sprintf('fr/node/%d/edit', $node->id()); - $translate_path = sprintf('node/%d/translations/add/en/fr', $node->id()); - - // Add french translation (revision 2). - $this->drupalGet($translate_path); - $this->drupalPostForm(NULL, [ - 'body[0][value]' => 'Second version of the content.', - 'moderation_state[0][state]' => 'published', - ], t('Save (this translation)')); - - // Change state to draft and preview the change. - $edit = ['moderation_state[0][state]' => 'draft']; - $this->drupalPostForm($fr_edit_path, $edit, t('Preview')); - - // Go back to edit form. - $this->clickLink(t('Back to content editing')); - - // Confirm transitions are as expected. - $this->assertSession()->optionExists('moderation_state[0][state]', 'draft'); - $this->assertSession()->optionExists('moderation_state[0][state]', 'published'); - $this->assertSession()->optionExists('moderation_state[0][state]', 'archived'); - - // Confirm the current state is Published and not Draft. - $this->assertSession()->pageTextContains('Current state Published'); - $selected_option = $this->xpath("//select[@name='moderation_state[0][state]']/option[@selected='selected']"); - $this->assertEquals('draft', $selected_option[0]->getValue()); - - // Create pending draft revision. - $this->drupalPostForm($fr_edit_path, [ - 'body[0][value]' => 'Third version of the content.', - 'moderation_state[0][state]' => 'draft', - ], t('Save (this translation)')); - - // Confirm the current state is Draft and not Published. - $this->drupalGet($fr_edit_path); - $this->assertSession()->pageTextContains('Current state Draft'); - } } diff --git a/core/modules/content_moderation/tests/src/Kernel/ModerationInformationTest.php b/core/modules/content_moderation/tests/src/Kernel/ModerationInformationTest.php index bff2a972a5..c2d739a111 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ModerationInformationTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ModerationInformationTest.php @@ -154,4 +154,33 @@ public function testIsDefaultRevisionPublishedMultilingual() { $this->assertEquals(TRUE, $this->moderationInformation->isDefaultRevisionPublished($entity)); } + /** + * @covers ::getOriginalState + */ + public function testGetOriginalState() { + $entity = EntityTestMulRevPub::create([ + 'moderation_state' => 'published', + ]); + $entity->save(); + $entity->moderation_state = 'foo'; + $this->assertEquals('published', $this->moderationInformation->getOriginalState($entity)->id()); + } + + /** + * @covers ::getOriginalState + */ + public function testGetOriginalStateMultilingual() { + $entity = EntityTestMulRevPub::create([ + 'moderation_state' => 'draft', + ]); + $entity->save(); + + $translated = $entity->addTranslation('de', $entity->toArray()); + $translated->moderation_state = 'published'; + $translated->save(); + + $translated->moderation_state = 'foo'; + $this->assertEquals('published', $this->moderationInformation->getOriginalState($translated)->id()); + } + }