MediaEntityMetadataApiTest.php

Same filename and directory in other branches
  1. 9 core/modules/ckeditor5/tests/src/Functional/MediaEntityMetadataApiTest.php
  2. 11.x core/modules/ckeditor5/tests/src/Functional/MediaEntityMetadataApiTest.php

Namespace

Drupal\Tests\ckeditor5\Functional

File

core/modules/ckeditor5/tests/src/Functional/MediaEntityMetadataApiTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\ckeditor5\Functional;

use Drupal\ckeditor5\Plugin\Editor\CKEditor5;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\editor\Entity\Editor;
use Drupal\field\Entity\FieldConfig;
use Drupal\file\Entity\File;
use Drupal\filter\Entity\FilterFormat;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Entity\ContentLanguageSettings;
use Drupal\media\Entity\Media;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\ckeditor5\Traits\SynchronizeCsrfTokenSeedTrait;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
use Drupal\Tests\TestFileCreationTrait;
use Drupal\user\RoleInterface;
use Drupal\user\Entity\User;
use Symfony\Component\Validator\ConstraintViolation;

/**
 * Tests the media entity metadata API.
 *
 * @group ckeditor5
 * @internal
 */
class MediaEntityMetadataApiTest extends BrowserTestBase {
  use TestFileCreationTrait;
  use MediaTypeCreationTrait;
  use SynchronizeCsrfTokenSeedTrait;
  
  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'user',
    'filter',
    'editor',
    'ckeditor5',
    'media',
  ];
  
  /**
   * The sample image media entity to use for testing.
   *
   * @var \Drupal\media\MediaInterface
   */
  protected $mediaImage;
  
  /**
   * The sample file media entity to use for testing.
   *
   * @var \Drupal\media\MediaInterface
   */
  protected $mediaFile;
  
  /**
   * The editor instance to use for testing.
   *
   * @var \Drupal\editor\Entity\Editor
   */
  protected $editor;
  
  /**
   * The admin user.
   *
   * @var \Drupal\user\Entity\User
   */
  protected User $adminUser;
  
  /**
   * @var \Drupal\Component\Uuid\UuidInterface
   */
  protected $uuidService;
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->uuidService = $this->container
      ->get('uuid');
    EntityViewMode::create([
      'id' => 'media.view_mode_1',
      'targetEntityType' => 'media',
      'status' => TRUE,
      'enabled' => TRUE,
      'label' => 'View Mode 1',
    ])->save();
    EntityViewMode::create([
      'id' => 'media.view_mode_2',
      'targetEntityType' => 'media',
      'status' => TRUE,
      'enabled' => TRUE,
      'label' => 'View Mode 2',
    ])->save();
    $filtered_html_format = FilterFormat::create([
      'format' => 'filtered_html',
      'name' => 'Filtered HTML',
      'weight' => 0,
      'filters' => [
        'filter_html' => [
          'id' => 'filter_html',
          'status' => TRUE,
          'weight' => -10,
          'settings' => [
            'allowed_html' => "<p> <br> <drupal-media data-entity-type data-entity-uuid data-view-mode alt>",
            'filter_html_help' => TRUE,
            'filter_html_nofollow' => TRUE,
          ],
        ],
        'media_embed' => [
          'id' => 'media_embed',
          'status' => TRUE,
          'settings' => [
            'default_view_mode' => 'view_mode_1',
            'allowed_view_modes' => [
              'view_mode_1' => 'view_mode_1',
              'view_mode_2' => 'view_mode_2',
            ],
            'allowed_media_types' => [],
          ],
        ],
      ],
      'roles' => [
        RoleInterface::AUTHENTICATED_ID,
      ],
    ]);
    $filtered_html_format->save();
    $this->editor = Editor::create([
      'format' => 'filtered_html',
      'editor' => 'ckeditor5',
      'settings' => [
        'toolbar' => [
          'items' => [],
        ],
        'plugins' => [
          'media_media' => [
            'allow_view_mode_override' => TRUE,
          ],
        ],
      ],
    ]);
    $this->editor
      ->save();
    $filtered_html_format->setFilterConfig('media_embed', [
      'status' => TRUE,
      'settings' => [
        'default_view_mode' => 'view_mode_1',
        'allowed_media_types' => [],
        'allowed_view_modes' => [
          'view_mode_1' => 'view_mode_1',
          'view_mode_2' => 'view_mode_2',
        ],
      ],
    ])
      ->save();
    $this->assertSame([], array_map(function (ConstraintViolation $v) {
      return (string) $v->getMessage();
    }, iterator_to_array(CKEditor5::validatePair($this->editor, $filtered_html_format))));
    // Create a sample media entity to be embedded.
    $this->createMediaType('image', [
      'id' => 'image',
    ]);
    File::create([
      'uri' => $this->getTestFiles('image')[0]->uri,
    ])
      ->save();
    $this->mediaImage = Media::create([
      'bundle' => 'image',
      'name' => 'Screaming hairy armadillo',
      'field_media_image' => [
        [
          'target_id' => 1,
          'alt' => 'default alt',
          'title' => 'default title',
        ],
      ],
    ]);
    $this->mediaImage
      ->save();
    $this->createMediaType('file', [
      'id' => 'file',
    ]);
    File::create([
      'uri' => $this->getTestFiles('text')[0]->uri,
    ])
      ->save();
    $this->mediaFile = Media::create([
      'bundle' => 'file',
      'name' => 'Information about screaming hairy armadillo',
      'field_media_file' => [
        [
          'target_id' => 2,
        ],
      ],
    ]);
    $this->mediaFile
      ->save();
    $this->adminUser = $this->drupalCreateUser([
      'use text format filtered_html',
    ]);
    $this->drupalLogin($this->adminUser);
  }
  
  /**
   * Tests the media entity metadata API.
   */
  public function testApi() : void {
    $path = '/ckeditor5/filtered_html/media-entity-metadata';
    $token = $this->container
      ->get('csrf_token')
      ->get(ltrim($path, '/'));
    $uuid = $this->mediaImage
      ->uuid();
    $this->drupalGet($path, [
      'query' => [
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(400);
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    $this->assertSame(json_encode([
      "type" => "image",
      'imageSourceMetadata' => [
        'alt' => 'default alt',
      ],
    ]), $this->getSession()
      ->getPage()
      ->getContent());
    $this->mediaImage
      ->set('field_media_image', [
      'target_id' => 1,
      'alt' => '',
      'title' => 'default title',
    ])
      ->save();
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    $this->assertSame(json_encode([
      'type' => 'image',
      'imageSourceMetadata' => [
        'alt' => '',
      ],
    ]), $this->getSession()
      ->getPage()
      ->getContent());
    // Test that setting the media image field to not display alt field also
    // omits it from the API (which will in turn instruct the CKE5 plugin to not
    // show it).
    FieldConfig::loadByName('media', 'image', 'field_media_image')->setSetting('alt_field', FALSE)
      ->save();
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    $this->assertSame(json_encode([
      'type' => 'image',
    ]), $this->getSession()
      ->getPage()
      ->getContent());
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $this->mediaFile
          ->uuid(),
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    $this->assertSame(json_encode([
      'type' => 'file',
    ]), $this->getSession()
      ->getPage()
      ->getContent());
    // Ensure that unpublished media returns 403.
    $this->mediaImage
      ->setUnpublished()
      ->save();
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(403);
    // Ensure that valid, but non-existing UUID returns 404.
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $this->uuidService
          ->generate(),
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(404);
    // Ensure that invalid UUID returns 400.
    $this->drupalGet($path, [
      'query' => [
        'uuid' => '🦙',
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(400);
    // Ensure that users that don't have access to the filter format receive
    // either 404 or 403.
    $this->drupalLogout();
    $token = $this->container
      ->get('csrf_token')
      ->get(ltrim($path, '/'));
    $this->drupalGet($path, [
      'token' => $token,
    ]);
    $this->assertSession()
      ->statusCodeEquals(400);
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(403);
    $this->mediaImage
      ->setPublished()
      ->save();
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(403);
  }
  
  /**
   * Tests the media entity metadata API with translations.
   */
  public function testApiTranslation() : void {
    $this->container
      ->get('module_installer')
      ->install([
      'language',
      'content_translation',
    ]);
    $this->resetAll();
    ConfigurableLanguage::createFromLangcode('fi')->save();
    $this->container
      ->get('config.factory')
      ->getEditable('language.negotiation')
      ->set('url.source', 'path_prefix')
      ->set('url.prefixes.fi', 'fi')
      ->save();
    $this->rebuildContainer();
    ContentLanguageSettings::loadByEntityTypeBundle('media', 'image')->setDefaultLangcode('en')
      ->setLanguageAlterable(TRUE)
      ->save();
    $media_fi = Media::load($this->mediaImage
      ->id())
      ->addTranslation('fi');
    $media_fi->field_media_image
      ->setValue([
      [
        'target_id' => '1',
        // cSpell:disable-next-line
'alt' => 'oletus alt-teksti kuvalle',
      ],
    ]);
    $media_fi->save();
    $uuid = $this->mediaImage
      ->uuid();
    $path = '/ckeditor5/filtered_html/media-entity-metadata';
    $token = $this->container
      ->get('csrf_token')
      ->get(ltrim($path, '/'));
    // Ensure that translation is returned when language is specified.
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
      'language' => $media_fi->language(),
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    // cSpell:disable-next-line
    $this->assertSame(json_encode([
      'type' => 'image',
      'imageSourceMetadata' => [
        'alt' => 'oletus alt-teksti kuvalle',
      ],
    ]), $this->getSession()
      ->getPage()
      ->getContent());
    // Ensure that default translation is returned when no language is
    // specified.
    $this->drupalGet($path, [
      'query' => [
        'uuid' => $uuid,
        'token' => $token,
      ],
    ]);
    $this->assertSession()
      ->statusCodeEquals(200);
    $this->assertSame(json_encode([
      'type' => 'image',
      'imageSourceMetadata' => [
        'alt' => 'default alt',
      ],
    ]), $this->getSession()
      ->getPage()
      ->getContent());
  }

}

Classes

Title Deprecated Summary
MediaEntityMetadataApiTest Tests the media entity metadata API.

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