image_to_media_swapper-2.x-dev/tests/src/Kernel/BatchProcessorServiceKernelTest.php

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

declare(strict_types=1);

namespace Drupal\Tests\image_to_media_swapper\Kernel;

use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\file\FileInterface;
use Drupal\image_to_media_swapper\BatchProcessorService;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\NodeInterface;
use Drupal\user\UserInterface;

/**
 * Tests access to BatchProcessorService.
 *
 * @group image_to_media_swapper
 */
class BatchProcessorServiceKernelTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'user',
    'field',
    'file',
    'media',
    'filter',
    'editor',
    'text',
    'image',
    'node',
    'options',
    'ckeditor5',
    'image_to_media_swapper',
  ];

  /**
   * The BatchProcessor service under test.
   *
   * @var \Drupal\image_to_media_swapper\BatchProcessorService
   */
  protected BatchProcessorService $service;

  /**
   * The entity definition update manager.
   *
   * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
   */
  protected EntityDefinitionUpdateManagerInterface $entityDefinitionUpdateManager;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * The file URL generator service.
   *
   * @var \Drupal\Core\File\FileUrlGeneratorInterface
   */
  protected FileUrlGeneratorInterface $fileUrlGenerator;

  /**
   * The file entity used in tests.
   *
   * @var \Drupal\file\FileInterface
   */
  protected FileInterface $file;

  /**
   * The node entity used in tests.
   *
   * @var \Drupal\node\NodeInterface
   */
  protected NodeInterface $node;

  /**
   * The user entity used in tests.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $user;

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

    // Install required schemas.
    $this->installEntitySchema('node');
    $this->installSchema('node', ['node_access']);

    $this->installEntitySchema('user');
    $this->installEntitySchema('file');
    $this->installSchema('file', ['file_usage']);
    $this->installEntitySchema('media');

    // Install configuration for needed modules.
    $this->installConfig(['filter', 'editor', 'media']);

    // Retrieve services.
    // Create the test-specific SwapperService first.
    $testSwapperService = new TestSwapperService(
      $this->container->get('entity_type.manager'),
      $this->container->get('http_client'),
      $this->container->get('file_system'),
      $this->container->get('logger.factory'),
      $this->container->get('image_to_media_swapper.security_validation'),
      $this->container->get('config.factory'),
      $this->container->get('entity_type.bundle.info'),
      $this->container->get('entity_field.manager'),
      $this->container->get('module_handler'),
      $this->container->get('file.mime_type.guesser'),
      $this->container->get('image_to_media_swapper.content_verification')
    );

    // Create and use the test-specific batch processor service.
    $this->service = new TestBatchProcessorService(
      $this->container->get('entity_type.manager'),
      $this->container->get('entity_field.manager'),
      $this->container->get('logger.factory'),
      $testSwapperService,
      $this->container->get('entity_display.repository'),
      $this->container->get('current_user'),
      $this->container->get('datetime.time'),
      $this->container->get('module_handler')
    );

    $this->entityDefinitionUpdateManager = $this->container->get('entity.definition_update_manager');
    $this->entityTypeManager = $this->container->get('entity_type.manager');
    $fileSystem = $this->container->get('file_system');
    $this->fileUrlGenerator = $this->container->get('file_url_generator');

    // Create the 'image' media type bundle if it doesn't exist.
    if (!$this->entityTypeManager->getStorage('media_type')->load('image')) {
      $this->entityTypeManager->getStorage('media_type')->create([
        'id' => 'image',
        'label' => 'Image',
        'source' => 'image',
        'status' => TRUE,
        'description' => 'Image media type',
        'source_configuration' => [
          'source_field' => 'field_media_image',
        ],
        'field_map' => [
          'image' => 'field_media_image',
        ],
      ])->save();
    }

    // Create field storage and field config for field_media_image.
    if (!$this->entityTypeManager->getStorage('field_storage_config')
      ->load('media.field_media_image')) {
      $this->entityTypeManager->getStorage('field_storage_config')->create([
        'field_name' => 'field_media_image',
        'entity_type' => 'media',
        'type' => 'image',
        'cardinality' => 1,
        'settings' => [
          'file_directory' => 'media/image',
          'file_extensions' => 'png gif jpg jpeg',
          'max_filesize' => '',
          'max_resolution' => '',
          'min_resolution' => '',
          'alt_field' => TRUE,
          'alt_field_required' => TRUE,
          'title_field' => FALSE,
          'title_field_required' => FALSE,
          'default_image' => [
            'uuid' => NULL,
            'alt' => '',
            'title' => '',
            'width' => NULL,
            'height' => NULL,
          ],
        ],
      ])->save();
    }

    if (!$this->entityTypeManager->getStorage('field_config')
      ->load('media.image.field_media_image')) {
      $this->entityTypeManager->getStorage('field_config')->create([
        'field_name' => 'field_media_image',
        'entity_type' => 'media',
        'bundle' => 'image',
        'label' => 'Image',
        'required' => TRUE,
      ])->save();
    }

    if (!$this->entityTypeManager->getStorage('node_type')->load('node_type.article')) {
      $this->entityTypeManager->getStorage('node_type')->create([
        'type' => 'article',
        'name' => 'Article',
      ])->save();
    }

    if (!$this->entityTypeManager->getStorage('field_storage_config')->load('field_storage_config.field_name.body')) {
      $this->entityTypeManager->getStorage('field_storage_config')->create([
        'field_name' => 'body',
        'entity_type' => 'node',
        'type' => 'text_long',
      ])->save();
    }
    if (!$this->entityTypeManager->getStorage('field_config')->load('field_config.field_name.body')) {
      $this->entityTypeManager->getStorage('field_config')->create([
        'field_name' => 'body',
        'entity_type' => 'node',
        'bundle' => 'article',
        'label' => 'Body',
        'settings' => [
          'allowed_formats' => ['full_html'],
        ],
      ])->save();
    }

    // Create a filter format with media_embed enabled.
    $format = $this->entityTypeManager->getStorage('filter_format')->create([
      'format' => 'full_html',
      'name' => 'Full HTML',
      'filters' => [
        'media_embed' => ['status' => TRUE],
      ],
    ]);
    $format->save();

    // Create an editor using CKEditor 5.
    $this->entityTypeManager->getStorage('editor')->create([
      'format' => 'full_html',
      'editor' => 'ckeditor5',
    ])->save();

    // Prepare the public directory.
    $publicDirectory = 'public://';
    $fileSystem->prepareDirectory($publicDirectory, FileSystemInterface::CREATE_DIRECTORY |
      FileSystemInterface::MODIFY_PERMISSIONS);

    // Create a test image in the public directory with real content.
    $fileName = 'test_image.jpg';
    $filePath = $publicDirectory . $fileName;

    // Create a simple JPEG image content (minimal valid JPEG header)
    $imageContent = base64_decode('/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==');
    file_put_contents($filePath, $imageContent);

    /** @var \Drupal\file\FileInterface $file */
    $file = $this->entityTypeManager->getStorage('file')->create([
      'uri' => $filePath,
      'filename' => $fileName,
      'filemime' => 'image/jpeg',
      'status' => 1,
    ]);
    $file->save();
    $this->file = $file;

    // Create a user.
    $user = $this->entityTypeManager->getStorage('user')->create([
      'name' => 'tester',
    ]);
    $user->save();
    $this->user = $user;

    // Get the file URL (important for tests to use the correct path format)
    $file_url = $this->fileUrlGenerator->generateAbsoluteString($this->file->getFileUri());
    // Strip the domain part for internal URL - but ensure it starts with the
    // public files path.
    $file_url = parse_url($file_url, PHP_URL_PATH);

    // Create a node with a raw <img> tag in the body.
    $node = $this->entityTypeManager->getStorage('node')->create([
      'type' => 'article',
      'title' => 'Test Node',
      'body' => [
        'value' => '<p>Image: <img src="' . $file_url . '" alt="test image" /></p>',
        'format' => 'full_html',
      ],
      'uid' => $user->id(),
    ]);
    $node->save();
    $this->node = $node;

    // Assertions to confirm the setup is valid.
    $this->assertNotNull($this->entityTypeManager->getStorage('media_type')
      ->load('image'));
    $this->assertTrue($this->entityTypeManager->getStorage('media')
      ->getEntityType()
      ->hasKey('bundle'));
    $this->assertTrue($node->hasField('body'));
  }

  /**
   * Tests that the service can find eligible text fields.
   *
   * @covers \Drupal\image_to_media_swapper\BatchProcessorService::getEligibleTextFields
   */
  public function testEligibleTextFieldsWithAllowedFormat(): void {
    $fields = $this->service->getEligibleTextFields();
    $this->assertArrayHasKey('node.article.body', $fields);
  }

  /**
   * Tests that the service can find entities with images in a specific field.
   *
   * @covers \Drupal\image_to_media_swapper\BatchProcessorService::getEntitiesWithFiles
   */
  public function testGetEntitiesWithFilesFindsNodes(): void {
    $result = $this->service->getEntitiesWithFiles('node.article.body');
    $this->assertArrayHasKey($this->node->id(), $result);
    $this->assertCount(1, $result);
  }

  /**
   * Tests that the service can find a file entity from a public URI.
   *
   * @covers \Drupal\image_to_media_swapper\BatchProcessorService::processContentByCategory
   */
  public function testSwapImagesToMedia(): void {
    // Debug the file URL to verify it's what we expect.
    $file_url = $this->fileUrlGenerator->generateAbsoluteString($this->file->getFileUri());
    $file_path = parse_url($file_url, PHP_URL_PATH);
    $this->assertNotEmpty($file_path, 'File path should not be empty');

    // Debug the node body content to verify the img tag is correct.
    $body_value = $this->node->get('body')->value;
    $this->assertStringContainsString('<img src="', $body_value, 'Body should contain img tag');
    $this->assertStringContainsString($file_path, $body_value, 'Body should contain correct file path');

    // Process the node to convert images to media entities.
    $result = $this->service->processContentByCategory('node.article.body', [$this->node], 'images');

    // Debug the result array.
    if (empty($result)) {
      $this->fail('Result array is empty - no entities were processed');
    }

    // Check that the node was processed.
    $this->assertArrayHasKey($this->node->id(), $result);

    // Load the updated node.
    $updated = $this->entityTypeManager->getStorage('node')
      ->load($this->node->id());
    $this->assertNotNull($updated, 'Updated node was loaded.');

    // Check that the node body now contains drupal-media tag.
    $value = $updated->get('body')->value;
    $this->assertStringContainsString('<drupal-media', $value);
    $this->assertStringContainsString('data-entity-uuid', $value);
  }

}

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

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