ContentModerationTest.php

Same filename and directory in other branches
  1. 9 core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php
  2. 8.9.x core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php
  3. 11.x core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php

Namespace

Drupal\Tests\media_library\FunctionalJavascript

File

core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\media_library\FunctionalJavascript;

use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\file\Entity\File;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\media\Entity\Media;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
use Drupal\Tests\TestFileCreationTrait;
// cspell:ignore hoglet

/**
 * Tests media library integration with content moderation.
 *
 * @group media_library
 */
class ContentModerationTest extends WebDriverTestBase {
  use ContentModerationTestTrait;
  use EntityReferenceFieldCreationTrait;
  use MediaTypeCreationTrait;
  use TestFileCreationTrait;
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'content_moderation',
    'field',
    'media',
    'media_library',
    'node',
    'views',
  ];
  
  /**
   * {@inheritdoc}
   *
   * @todo Remove and fix test to not rely on super user.
   * @see https://www.drupal.org/project/drupal/issues/3437620
   */
  protected bool $usesSuperUserAccessPolicy = TRUE;
  
  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';
  
  /**
   * User with the 'administer media' permission.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $userAdmin;
  
  /**
   * User with the 'view media' permission.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $userViewer;
  
  /**
   * User with the 'view media' and 'view own unpublished media' permissions.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $userViewOwnUnpublished;
  
  /**
   * User with the 'view media' and 'view any unpublished content' permissions.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $userViewAnyUnpublished;
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    // Create an image media type and article node type.
    $this->createMediaType('image', [
      'id' => 'image',
    ]);
    $this->drupalCreateContentType([
      'type' => 'article',
      'name' => 'Article',
    ]);
    // Create a media reference field on articles.
    $this->createEntityReferenceField('node', 'article', 'field_media', 'Media', 'media', 'default', [
      'target_bundles' => [
        'image',
      ],
    ], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
    // Add the media field to the form display.
    $form_display = \Drupal::service('entity_display.repository')->getFormDisplay('node', 'article', 'default');
    $form_display->setComponent('field_media', [
      'type' => 'media_library_widget',
    ])
      ->save();
    // Configure the "Editorial" workflow to apply to image media.
    $workflow = $this->createEditorialWorkflow();
    $workflow->getTypePlugin()
      ->addEntityTypeAndBundle('media', 'image');
    $workflow->save();
    $image = File::create([
      'uri' => $this->getTestFiles('image')[0]->uri,
    ]);
    $image->setPermanent();
    $image->save();
    // Create a draft, published and archived media item.
    $draft_media = Media::create([
      'name' => 'Hoglet',
      'bundle' => 'image',
      'field_media_image' => $image,
      'moderation_state' => 'draft',
    ]);
    $draft_media->save();
    $published_media = Media::create([
      'name' => 'Panda',
      'bundle' => 'image',
      'field_media_image' => $image,
      'moderation_state' => 'published',
    ]);
    $published_media->save();
    $archived_media = Media::create([
      'name' => 'Mammoth',
      'bundle' => 'image',
      'field_media_image' => $image,
      'moderation_state' => 'archived',
    ]);
    $archived_media->save();
    // Create some users for our tests. We want to check with user 1, a media
    // administrator with 'administer media' permissions, a user that has the
    // 'view media' permissions, a user that can 'view media' and 'view own
    // unpublished media', and a user that has 'view media' and 'view any
    // unpublished content' permissions.
    $this->userAdmin = $this->drupalCreateUser([
      'access administration pages',
      'access content',
      'access media overview',
      'edit own article content',
      'create article content',
      'administer media',
    ]);
    $this->userViewer = $this->drupalCreateUser([
      'access administration pages',
      'access content',
      'access media overview',
      'edit own article content',
      'create article content',
      'view media',
      'create media',
    ]);
    $this->userViewOwnUnpublished = $this->drupalCreateUser([
      'access administration pages',
      'access content',
      'access media overview',
      'edit own article content',
      'create article content',
      'view media',
      'view own unpublished media',
      'create media',
    ]);
    $this->userViewAnyUnpublished = $this->drupalCreateUser([
      'access administration pages',
      'access content',
      'access media overview',
      'edit own article content',
      'create article content',
      'view media',
      'create media',
      'view any unpublished content',
    ]);
  }
  
  /**
   * Tests the media library widget only shows published media.
   */
  public function testAdministrationPage() : void {
    // User 1 should be able to see all media items.
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // The media admin user should be able to see all media items.
    $this->drupalLogin($this->userAdmin);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // The media viewer user should be able to see only published media items.
    $this->drupalLogin($this->userViewer);
    $this->drupalGet('admin/content/media');
    $this->assertOnlyPublishedMedia();
    // The media viewer user that can also view its own unpublished media should
    // also be able to see only published media items since it is not the owner
    // of the created media items.
    $this->drupalLogin($this->userViewOwnUnpublished);
    $this->drupalGet('admin/content/media');
    $this->assertOnlyPublishedMedia();
    // When content moderation is enabled, a media viewer that can view any
    // unpublished content should be able to see all media.
    // @see content_moderation_entity_access()
    $this->drupalLogin($this->userViewAnyUnpublished);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // Assign all media to the user with the 'view own unpublished media'
    // permission.
    foreach (Media::loadMultiple() as $media) {
      $media->setOwner($this->userViewOwnUnpublished);
      $media->save();
    }
    // User 1 should still be able to see all media items.
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // The media admin user should still be able to see all media items.
    $this->drupalLogin($this->userAdmin);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // The media viewer user should still be able to see only published media
    // items.
    $this->drupalLogin($this->userViewer);
    $this->drupalGet('admin/content/media');
    $this->assertOnlyPublishedMedia();
    // The media viewer user that can also view its own unpublished media
    // should now be able to see all media items since it is the owner of the
    // created media items.
    $this->drupalLogin($this->userViewOwnUnpublished);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
    // The media viewer that can view any unpublished content should still be
    // able to see all media.
    $this->drupalLogin($this->userViewAnyUnpublished);
    $this->drupalGet('admin/content/media');
    $this->assertAllMedia();
  }
  
  /**
   * Tests the media library widget only shows published media.
   */
  public function testWidget() : void {
    $assert_session = $this->assertSession();
    // All users should only be able to see published media items.
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userAdmin);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewer);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewOwnUnpublished);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewAnyUnpublished);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    // After we change the owner to the user with 'view own unpublished media'
    // permission, all users should still only be able to see published media.
    foreach (Media::loadMultiple() as $media) {
      $media->setOwner($this->userViewOwnUnpublished);
      $media->save();
    }
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userAdmin);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewer);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewOwnUnpublished);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
    $this->drupalLogin($this->userViewAnyUnpublished);
    $this->drupalGet('node/add/article');
    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertOnlyPublishedMedia();
  }
  
  /**
   * Asserts all media items are visible.
   *
   * @internal
   */
  protected function assertAllMedia() : void {
    $assert_session = $this->assertSession();
    $assert_session->pageTextContains('Hoglet');
    $assert_session->pageTextContains('Panda');
    $assert_session->pageTextContains('Mammoth');
  }
  
  /**
   * Asserts only published media items are visible.
   *
   * @internal
   */
  protected function assertOnlyPublishedMedia() : void {
    $assert_session = $this->assertSession();
    $assert_session->pageTextNotContains('Hoglet');
    $assert_session->pageTextContains('Panda');
    $assert_session->pageTextNotContains('Mammoth');
  }

}

Classes

Title Deprecated Summary
ContentModerationTest Tests media library integration with content moderation.

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