image_to_media_swapper-2.x-dev/tests/src/Functional/SwapperControllerRecheckTest.php

tests/src/Functional/SwapperControllerRecheckTest.php
<?php

namespace Drupal\Tests\image_to_media_swapper\Functional;

use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\Core\File\FileExists;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\image_to_media_swapper\Traits\MediaFieldSetupTrait;
use Drupal\image_to_media_swapper\Entity\MediaSwapRecord;
use Drupal\node\Entity\Node;

/**
 * Tests the MediaSwapRecord recheck functionality in SwapperController.
 *
 * @group image_to_media_swapper
 */
class SwapperControllerRecheckTest extends BrowserTestBase {

  use MediaFieldSetupTrait;

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

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * A user with permission to access the recheck functionality.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $adminUser;

  /**
   * A user without permission to access the recheck functionality.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $regularUser;

  /**
   * The media swap record to be rechecked.
   *
   * @var \Drupal\image_to_media_swapper\Entity\MediaSwapRecord
   */
  protected $mediaSwapRecord;

  /**
   * The node with image content to be processed.
   *
   * @var \Drupal\node\NodeInterface
   */
  protected $nodeWithImage;

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

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

    // In BrowserTestBase, entity schemas are installed automatically
    // by the profile, so we don't need to install them manually.
    // Just ensure we've got our file usage schema.
    $this->container->get('config.installer')->installDefaultConfig('module', 'file');

    // Get the file URL generator service.
    $this->fileUrlGenerator = $this->container->get('file_url_generator');

    // Set up test content types and fields using the trait.
    $this->createNodeTypeWithBody();
    $this->createMediaImageType();
    $this->createFilterFormatWithMediaEmbed();

    // Create users with different permission levels.
    $this->adminUser = $this->drupalCreateUser([
      'access batch media swapper',
      'administer nodes',
    ]);

    $this->regularUser = $this->drupalCreateUser([
      'administer nodes',
    ]);

    // Create a node with an image in a text field.
    $this->nodeWithImage = $this->createNodeWithImageInTextField();

    // Create a pending MediaSwapRecord for the node.
    $this->mediaSwapRecord = $this->createPendingMediaSwapRecord($this->nodeWithImage);
  }

  /**
   * Tests that a user with appropriate permissions can recheck a record.
   */
  public function testRecheckRecordWithPermission(): void {
    // Login as admin user who has proper permissions.
    $this->drupalLogin($this->adminUser);

    // Access the recheck URL.
    $url = Url::fromRoute('image_to_media_swapper.recheck_record', [
      'media_swap_record' => $this->mediaSwapRecord->id(),
    ]);

    $this->drupalGet($url);

    // Verify response.
    $this->assertSession()->statusCodeEquals(200);

    // Verify status message appears.
    $this->assertSession()->pageTextContains('The record has been rechecked');

    // Reload the record from storage to check if its status changed.
    $updated_record = MediaSwapRecord::load($this->mediaSwapRecord->id());

    // The status should still be 'pending': we didn't modify the test node.
    $this->assertEquals('pending', $updated_record->getProcessingStatus());

    // Now update the node to remove the image, then recheck again.
    $this->updateNodeToRemoveImage($this->nodeWithImage);

    // Revisit the recheck URL.
    $this->drupalGet($url);

    // Reload the record again - use static load method instead of service.
    $updated_record = MediaSwapRecord::load($this->mediaSwapRecord->id());

    // Now the status should be 'completed' since the image was removed.
    $this->assertEquals('completed', $updated_record->getProcessingStatus());
  }

  /**
   * Tests that a user without appropriate permissions cannot recheck a record.
   */
  public function testRecheckRecordWithoutPermission(): void {
    // Login as regular user without proper permissions.
    $this->drupalLogin($this->regularUser);

    // Try to access the recheck URL.
    $url = Url::fromRoute('image_to_media_swapper.recheck_record', [
      'media_swap_record' => $this->mediaSwapRecord->id(),
    ]);

    $this->drupalGet($url);

    // Verify access is denied.
    $this->assertSession()->statusCodeEquals(403);
  }

  /**
   * Creates a node with an image tag in a text field.
   *
   * @return \Drupal\node\NodeInterface
   *   The created node.
   */
  protected function createNodeWithImageInTextField(): Node {
    // We'll use the article content type created with body field in setup.
    // Create a file in the public files directory.
    $file = $this->createTestFile('example.jpg');

    // Generate URL using the file URL generator service.
    $file_url = $this->fileUrlGenerator->generateAbsoluteString($file->getFileUri());

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

    return $node;
  }

  /**
   * Creates a test file.
   *
   * @param string $filename
   *   The filename.
   *
   * @return \Drupal\file\FileInterface
   *   The created file entity.
   */
  protected function createTestFile($filename) {
    $file_system = $this->container->get('file_system');

    // Ensure the directory exists.
    $directory = 'public://';
    $file_system->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);

    // Define the target URI for the file.
    $uri = 'public://' . $filename;

    // Get the module extension path using the modern approach.
    $module_path = $this->container->get('extension.list.module')->getPath('image_to_media_swapper');
    $source = $module_path . '/tests/fixtures/test-image.png';

    if (!file_exists($source)) {
      // Fallback to core test image if module test image doesn't exist.
      $source = DRUPAL_ROOT . '/core/misc/druplicon.png';
    }

    $file_system->copy($source, $uri, FileExists::Replace);

    // Create the file entity.
    $file = File::create([
      'uri' => $uri,
      'filename' => $filename,
      'status' => FileInterface::STATUS_PERMANENT,
    ]);
    $file->save();

    return $file;
  }

  /**
   * Creates a pending MediaSwapRecord entity for the given node.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node to create a record for.
   *
   * @return \Drupal\image_to_media_swapper\Entity\MediaSwapRecord
   *   The created MediaSwapRecord.
   */
  protected function createPendingMediaSwapRecord($node): MediaSwapRecord {
    // Create a MediaSwapRecord entity.
    $media_swap_record = MediaSwapRecord::create([
      'field_selector' => 'node.article.body',
      'target_entity_type' => 'node',
      'target_bundle' => 'article',
      'target_entity_id' => $node->id(),
      'batch_category' => 'images',
      'processing_status' => 'pending',
      'processed_time' => time(),
      'uid' => $this->adminUser->id(),
    ]);
    $media_swap_record->save();

    return $media_swap_record;
  }

  /**
   * Updates a node to remove image tags from its content.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node to update.
   */
  protected function updateNodeToRemoveImage($node): void {
    // Update the node to remove the image tag.
    $node->set('body', [
      'value' => '<p>Test content with no image.</p>',
      'format' => 'full_html',
    ]);
    $node->save();
  }

}

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

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