twig_tweak-8.x-2.8/tests/src/Kernel/ImageViewBuilderTest.php

tests/src/Kernel/ImageViewBuilderTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\twig_tweak\Kernel;

use Drupal\Core\Cache\Cache;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\File\FileExists;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\PrivateStream;
use Drupal\file\FileInterface;
use PHPUnit\Framework\Attributes\DataProvider;

/**
 * A test class for testing the image view builder.
 *
 * @group twig_tweak
 */
final class ImageViewBuilderTest extends AbstractTestCase {

  private const string SOURCE_IMAGE = 'core/tests/fixtures/files/image-test.jpg';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'twig_tweak',
    'twig_tweak_test',
    'user',
    'system',
    'file',
    'image',
    'responsive_image',
    'breakpoint',
    'views',
    'filter',
  ];

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();

    $this->installEntitySchema('file');
    $this->installSchema('file', 'file_usage');

    $file_system = $this->container->get('file_system');
    $file_system->prepareDirectory($this->siteDirectory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
    $private_directory = $this->siteDirectory . '/private';
    $file_system->prepareDirectory($private_directory, FileSystemInterface::CREATE_DIRECTORY);
    $this->setSetting('file_private_path', $private_directory);

    $entity_type_manager = $this->container->get('entity_type.manager');
    $image_style_storage = $entity_type_manager->getStorage('image_style');
    $image_style = $image_style_storage->create([
      'name' => 'small',
      'label' => 'Small',
    ]);
    // Add a crop effect:
    $image_style->addImageEffect([
      'id' => 'image_resize',
      'data' => [
        'width' => 10,
        'height' => 10,
      ],
      'weight' => 0,
    ]);
    $image_style_storage->save($image_style);

    $responsive_image_style_storage = $entity_type_manager->getStorage('responsive_image_style');
    $responsive_image_style = $responsive_image_style_storage->create([
      'id' => 'wide',
      'label' => 'Wide',
      'breakpoint_group' => 'twig_tweak_image_view_builder',
      'fallback_image_style' => 'small',
    ]);
    $responsive_image_style_storage->save($responsive_image_style);
  }

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container): void {
    parent::register($container);
    $container->register('stream_wrapper.private', PrivateStream::class)
      ->addTag('stream_wrapper', ['scheme' => 'private']);
  }

  /**
   * {@selfdoc}
   */
  #[DataProvider('dataProvider')]
  public function testImageViewBuilder(string $uri, ?string $style, array $attributes, bool $responsive, bool $check_access, array $expected_build, string $expected_output): void {
    $view_builder = $this->container->get('twig_tweak.image_view_builder');
    $build = $view_builder->build($this->createFile($uri), $style, $attributes, $responsive, $check_access);
    self::assertRenderArray($expected_build, $build);
    self::assertSame($expected_output, $this->renderInIsolation($build));
  }

  /**
   * {@selfdoc}
   */
  public static function dataProvider(): \Generator {
    $build_data = static fn (
      string $uri,
      ?string $style,
      array $attributes,
      bool $responsive,
      bool $check_access,
      array $expected_build,
      string $expected_output,
    ): array => \func_get_args();

    yield 'Without style' => $build_data(
      uri: 'public://image-test.jpg',
      style: NULL,
      attributes: [],
      responsive: FALSE,
      check_access: TRUE,
      expected_build: [
        '#uri' => 'public://image-test.jpg',
        '#attributes' => [],
        '#theme' => 'image',
        '#cache' => [
          'contexts' => [
            'user',
            'user.permissions',
          ],
          'tags' => [
            'file:1',
            'tag_for_public://image-test.jpg',
          ],
          'max-age' => 70,
        ],
      ],
      expected_output: '<img src="/files/image-test.jpg" alt="" />',
    );

    yield 'With style' => $build_data(
      uri: 'public://image-test.jpg',
      style: 'small',
      attributes: ['alt' => 'Image with style'],
      responsive: FALSE,
      check_access: TRUE,
      expected_build: [
        '#uri' => 'public://image-test.jpg',
        '#attributes' => ['alt' => 'Image with style'],
        '#width' => 40,
        '#height' => 20,
        '#theme' => 'image_style',
        '#style_name' => 'small',
        '#cache' => [
          'contexts' => [
            'user',
            'user.permissions',
          ],
          'tags' => [
            'file:1',
            'tag_for_public://image-test.jpg',
          ],
          'max-age' => 70,
        ],
      ],
      expected_output: '<img alt="Image with style" src="/files/styles/small/public/image-test.jpg?itok=abc" width="10" height="10" loading="lazy" />',
    );

    yield 'With responsive style' => $build_data(
      uri: 'public://image-test.jpg',
      style: 'wide',
      attributes: ['alt' => 'Image with responsive style'],
      responsive: TRUE,
      check_access: TRUE,
      expected_build: [
        '#uri' => 'public://image-test.jpg',
        '#attributes' => ['alt' => 'Image with responsive style'],
        '#width' => 40,
        '#height' => 20,
        '#type' => 'responsive_image',
        '#responsive_image_style_id' => 'wide',
        '#cache' => [
          'contexts' => [
            'user',
            'user.permissions',
          ],
          'tags' => [
            'file:1',
            'tag_for_public://image-test.jpg',
          ],
          'max-age' => 70,
        ],
      ],
      expected_output: '<picture><img width="10" height="10" src="/files/styles/small/public/image-test.jpg?itok=abc" alt="Image with responsive style" loading="lazy" /></picture>',
    );

    yield 'Private image with access check' => $build_data(
      uri: 'private://image-test.jpg',
      style: NULL,
      attributes: [],
      responsive: FALSE,
      check_access: TRUE,
      expected_build: [
        '#cache' => [
          'contexts' => ['user'],
          'tags' => [
            'file:1',
            'tag_for_private://image-test.jpg',
          ],
          'max-age' => 70,
        ],
      ],
      expected_output: '',
    );

    yield 'Private image without access check' => $build_data(
      uri: 'private://image-test.jpg',
      style: NULL,
      attributes: [],
      responsive: FALSE,
      check_access: FALSE,
      expected_build: [
        '#uri' => 'private://image-test.jpg',
        '#attributes' => [],
        '#theme' => 'image',
        '#cache' => [
          'contexts' => [],
          'tags' => ['file:1'],
          'max-age' => Cache::PERMANENT,
        ],
      ],
      expected_output: '<img src="/files/image-test.jpg" alt="" />',
    );
  }

  /**
   * Renders a render array.
   */
  private function renderInIsolation(array $build): string {
    $renderer = $this->container->get('renderer');
    $html = (string) $renderer->renderInIsolation($build);
    $html = \preg_replace('#src=".+/files/#s', 'src="/files/', $html);
    $html = \preg_replace('#\?itok=.+?"#', '?itok=abc"', $html);
    $html = \preg_replace(['#\s{2,}#', '#\n#'], '', $html);
    return \rtrim($html);
  }

  /**
   * {@selfdoc}
   */
  private function createFile(string $uri): FileInterface {
    $file_system = $this->container->get('file_system');

    // Create a copy of a test image file. Original size is 40×20 px.
    $file_system->copy(self::SOURCE_IMAGE, $uri, FileExists::Replace);
    self::assertFileExists($uri);

    $file_storage = $this->container->get('entity_type.manager')->getStorage('file');
    $file = $file_storage->create([
      'uri' => $uri,
      'status' => FileInterface::STATUS_PERMANENT,
    ]);
    $file_storage->save($file);
    return $file;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc