PathContentModerationTest.php

Same filename and directory in other branches
  1. 8.9.x core/modules/path/tests/src/Functional/PathContentModerationTest.php
  2. 10 core/modules/path/tests/src/Functional/PathContentModerationTest.php
  3. 11.x core/modules/path/tests/src/Functional/PathContentModerationTest.php

Namespace

Drupal\Tests\path\Functional

File

core/modules/path/tests/src/Functional/PathContentModerationTest.php

View source
<?php

namespace Drupal\Tests\path\Functional;

use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;

/**
 * Tests path aliases with Content Moderation.
 *
 * @group content_moderation
 * @group path
 */
class PathContentModerationTest extends BrowserTestBase {
    use ContentModerationTestTrait;
    
    /**
     * Modules to install.
     *
     * @var array
     */
    protected static $modules = [
        'node',
        'path',
        'content_moderation',
        'content_translation',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'stark';
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        ConfigurableLanguage::createFromLangcode('fr')->save();
        $this->rebuildContainer();
        // Created a content type.
        $this->drupalCreateContentType([
            'name' => 'moderated',
            'type' => 'moderated',
        ]);
        // Set the content type as moderated.
        $workflow = $this->createEditorialWorkflow();
        $workflow->getTypePlugin()
            ->addEntityTypeAndBundle('node', 'moderated');
        $workflow->save();
        $this->drupalLogin($this->rootUser);
        // Enable URL language detection and selection.
        $edit = [
            'language_interface[enabled][language-url]' => 1,
        ];
        $this->drupalGet('admin/config/regional/language/detection');
        $this->submitForm($edit, 'Save settings');
        // Enable translation for moderated node.
        $edit = [
            'entity_types[node]' => 1,
            'settings[node][moderated][translatable]' => 1,
            'settings[node][moderated][fields][path]' => 1,
            'settings[node][moderated][fields][body]' => 1,
            'settings[node][moderated][settings][language][language_alterable]' => 1,
        ];
        $this->drupalGet('admin/config/regional/content-language');
        $this->submitForm($edit, 'Save configuration');
        \Drupal::entityTypeManager()->clearCachedDefinitions();
    }
    
    /**
     * Tests node path aliases on a moderated content type.
     */
    public function testNodePathAlias() {
        // Create some moderated content with a path alias.
        $this->drupalGet('node/add/moderated');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '');
        $this->submitForm([
            'title[0][value]' => 'moderated content',
            'path[0][alias]' => '/moderated-content',
            'moderation_state[0][state]' => 'published',
        ], 'Save');
        $node = $this->getNodeByTitle('moderated content');
        // Add a pending revision with the same alias.
        $this->drupalGet('node/' . $node->id() . '/edit');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '/moderated-content');
        $this->submitForm([
            'title[0][value]' => 'pending revision',
            'path[0][alias]' => '/moderated-content',
            'moderation_state[0][state]' => 'draft',
        ], 'Save');
        $this->assertSession()
            ->statusMessageNotContains('You can only change the URL alias for the published version of this content.');
        // Create some moderated content with no path alias.
        $this->drupalGet('node/add/moderated');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '');
        $this->submitForm([
            'title[0][value]' => 'moderated content 2',
            'path[0][alias]' => '',
            'moderation_state[0][state]' => 'published',
        ], 'Save');
        $node = $this->getNodeByTitle('moderated content 2');
        // Add a pending revision with a new alias.
        $this->drupalGet('node/' . $node->id() . '/edit');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '');
        $this->submitForm([
            'title[0][value]' => 'pending revision',
            'path[0][alias]' => '/pending-revision',
            'moderation_state[0][state]' => 'draft',
        ], 'Save');
        $this->assertSession()
            ->statusMessageContains('You can only change the URL alias for the published version of this content.', 'error');
        // Create some moderated content with no path alias.
        $this->drupalGet('node/add/moderated');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '');
        $this->submitForm([
            'title[0][value]' => 'moderated content 3',
            'path[0][alias]' => '',
            'moderation_state[0][state]' => 'published',
        ], 'Save');
        $node = $this->getNodeByTitle('moderated content 3');
        // Add a pending revision with no path alias.
        $this->drupalGet('node/' . $node->id() . '/edit');
        $this->assertSession()
            ->fieldValueEquals('path[0][alias]', '');
        $this->submitForm([
            'title[0][value]' => 'pending revision',
            'path[0][alias]' => '',
            'moderation_state[0][state]' => 'draft',
        ], 'Save');
        $this->assertSession()
            ->statusMessageNotContains('You can only change the URL alias for the published version of this content.');
    }
    
    /**
     * Tests that translated and moderated node can get new draft revision.
     */
    public function testTranslatedModeratedNodeAlias() {
        // Create one node with a random alias.
        $default_node = $this->drupalCreateNode([
            'type' => 'moderated',
            'langcode' => 'en',
            'moderation_state' => 'published',
            'path' => '/' . $this->randomMachineName(),
        ]);
        // Add published translation with another alias.
        $this->drupalGet('node/' . $default_node->id());
        $this->drupalGet('node/' . $default_node->id() . '/translations');
        $this->clickLink('Add');
        $edit_translation = [
            'body[0][value]' => $this->randomMachineName(),
            'moderation_state[0][state]' => 'published',
            'path[0][alias]' => '/' . $this->randomMachineName(),
        ];
        $this->submitForm($edit_translation, 'Save (this translation)');
        // Confirm that the alias works.
        $this->drupalGet('fr' . $edit_translation['path[0][alias]']);
        $this->assertSession()
            ->pageTextContains($edit_translation['body[0][value]']);
        $default_path = $default_node->path->alias;
        $translation_path = 'fr' . $edit_translation['path[0][alias]'];
        $this->assertPathsAreAccessible([
            $default_path,
            $translation_path,
        ]);
        // Try to create new draft revision for translation with a new path alias.
        $edit_new_translation_draft_with_alias = [
            'moderation_state[0][state]' => 'draft',
            'path[0][alias]' => '/' . $this->randomMachineName(),
        ];
        $this->drupalGet('fr/node/' . $default_node->id() . '/edit');
        $this->submitForm($edit_new_translation_draft_with_alias, 'Save (this translation)');
        // Confirm the expected error.
        $this->assertSession()
            ->statusMessageContains('You can only change the URL alias for the published version of this content.', 'error');
        // Create new draft revision for translation without changing path alias.
        $edit_new_translation_draft = [
            'body[0][value]' => $this->randomMachineName(),
            'moderation_state[0][state]' => 'draft',
        ];
        $this->drupalGet('fr/node/' . $default_node->id() . '/edit');
        $this->submitForm($edit_new_translation_draft, 'Save (this translation)');
        // Confirm that the new draft revision was created.
        $this->assertSession()
            ->statusMessageNotContains('You can only change the URL alias for the published version of this content.');
        $this->assertSession()
            ->pageTextContains($edit_new_translation_draft['body[0][value]']);
        $this->assertPathsAreAccessible([
            $default_path,
            $translation_path,
        ]);
        // Try to create a new draft revision for translation with path alias from
        // the original language's default revision.
        $edit_new_translation_draft_with_defaults_alias = [
            'moderation_state[0][state]' => 'draft',
            'path[0][alias]' => $default_node->path->alias,
        ];
        $this->drupalGet('fr/node/' . $default_node->id() . '/edit');
        $this->submitForm($edit_new_translation_draft_with_defaults_alias, 'Save (this translation)');
        // Verify the expected error.
        $this->assertSession()
            ->statusMessageContains('You can only change the URL alias for the published version of this content.', 'error');
        // Try to create new draft revision for translation with deleted (empty)
        // path alias.
        $edit_new_translation_draft_empty_alias = [
            'body[0][value]' => $this->randomMachineName(),
            'moderation_state[0][state]' => 'draft',
            'path[0][alias]' => '',
        ];
        $this->drupalGet('fr/node/' . $default_node->id() . '/edit');
        $this->submitForm($edit_new_translation_draft_empty_alias, 'Save (this translation)');
        // Confirm the expected error.
        $this->assertSession()
            ->statusMessageContains('You can only change the URL alias for the published version of this content.', 'error');
        // Create new default (published) revision for translation with new path
        // alias.
        $edit_new_translation = [
            'body[0][value]' => $this->randomMachineName(),
            'moderation_state[0][state]' => 'published',
            'path[0][alias]' => '/' . $this->randomMachineName(),
        ];
        $this->drupalGet('fr/node/' . $default_node->id() . '/edit');
        $this->submitForm($edit_new_translation, 'Save (this translation)');
        // Confirm that the new published revision was created.
        $this->assertSession()
            ->statusMessageNotContains('You can only change the URL alias for the published version of this content.');
        $this->assertSession()
            ->pageTextContains($edit_new_translation['body[0][value]']);
        $this->assertSession()
            ->addressEquals('fr' . $edit_new_translation['path[0][alias]']);
        $this->assertPathsAreAccessible([
            $default_path,
        ]);
    }
    
    /**
     * Helper callback to verify paths are responding with status 200.
     *
     * @param string[] $paths
     *   An array of paths to check for.
     *
     * @internal
     */
    public function assertPathsAreAccessible(array $paths) : void {
        foreach ($paths as $path) {
            $this->drupalGet($path);
            $this->assertSession()
                ->statusCodeEquals(200);
        }
    }

}

Classes

Title Deprecated Summary
PathContentModerationTest Tests path aliases with Content Moderation.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.