file_browser-8.x-1.3/tests/src/Functional/FileBrowserControllerTest.php

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

namespace Drupal\Tests\file_browser\Functional;

use Drupal\Core\Url;
use Drupal\file\FileInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\UserInterface;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests the File Browser Controller functionality.
 */
#[Group("file_browser")]
class FileBrowserControllerTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   *
   * We set this to FALSE here as DropzoneJS and Entity Browser use dynamic
   * config settings which fail strict checks during installation.
   */
  protected $strictConfigSchema = FALSE;

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

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'file_browser',
    'dropzonejs',
    'entity_browser',
    'entity_embed',
    'image',
    'file',
    'user',
    'system',
  ];

  /**
   * A test file entity.
   *
   * @var \Drupal\file\FileInterface
   */
  protected FileInterface $testFile;

  /**
   * A test image file entity.
   *
   * @var \Drupal\file\FileInterface
   */
  protected FileInterface $testImage;

  /**
   * An authenticated user with file view permissions.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $authenticatedUser;

  /**
   * An admin user with all permissions.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $adminUser;

  /**
   * A user without file view permissions.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $restrictedUser;

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

    // Create test files.
    $this->testFile = $this->createTestFile();
    $this->testImage = $this->createTestImageFile();

    // Create users with different permission levels.
    $this->authenticatedUser = $this->drupalCreateUser([
      'access content',
    ]);

    $this->adminUser = $this->drupalCreateUser([
      'access content',
      'access files overview',
      'delete any file',
      'delete own files',
    ]);

    $this->restrictedUser = $this->drupalCreateUser([
      'access content',
    ]);

    // Install default image styles.
    $this->container->get('module_installer')->install(['image']);
  }

  /**
   * Creates a test file entity.
   *
   * @return \Drupal\file\FileInterface
   *   The created file entity.
   */
  protected function createTestFile() {
    $file_contents = 'This is a test file.';
    /** @var \Drupal\file\FileRepositoryInterface $file_repository */
    $file_repository = \Drupal::service('file.repository');
    $file = $file_repository->writeData($file_contents, 'public://test-file.txt');
    $file->setPermanent();
    $file->save();
    return $file;
  }

  /**
   * Creates a test image file entity.
   *
   * @return \Drupal\file\FileInterface
   *   The created image file entity.
   */
  protected function createTestImageFile() {
    // Create a minimal image file with proper MIME type.
    // This creates a 1x1 pixel PNG image.
    $image_data = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChAHF/mWAAAAASUVORK5CYII=');
    /** @var \Drupal\file\FileRepositoryInterface $file_repository */
    $file_repository = \Drupal::service('file.repository');
    $file = $file_repository->writeData($image_data, 'public://test-image.png');

    // Ensure proper MIME type is set.
    $file->setMimeType('image/png');
    $file->setPermanent();
    $file->save();

    // Debug: Check the created file properties.
    $mime_type = $file->getMimeType();
    if (!str_starts_with($mime_type, 'image/')) {
      throw new \Exception("Test image file has wrong MIME type: $mime_type");
    }

    return $file;
  }

  /**
   * Tests route access for authenticated users.
   */
  public function testPreviewRouteAccess() {
    // Test unauthenticated access to public files is allowed (returns 200).
    // This is correct behavior as public files can be viewed by anonymous
    // users.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testFile->id(),
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Test authenticated user with appropriate permissions can access.
    $this->drupalLogin($this->adminUser);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Verify the response contains expected elements.
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');
  }

  /**
   * Tests preview rendering with image files.
   */
  public function testImagePreviewRendering() {
    $this->drupalLogin($this->adminUser);

    // Test image file preview without image style.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Verify the response contains expected elements.
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');

    // Should contain image style selector for image files.
    $this->assertSession()->elementExists('css', 'select');

    // The image style selector exists but may have different field names.
    // Just verify that a select element exists for image files.
    $select_elements = $this->getSession()->getPage()->findAll('css', 'select');
    $this->assertNotEmpty($select_elements, 'No select elements found for image file preview');
  }

  /**
   * Tests preview rendering with image style parameter.
   */
  public function testImageStyleParameter() {
    $this->drupalLogin($this->adminUser);

    // Test with a specific image style.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
      'image_style' => 'thumbnail',
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Verify preview wrapper exists and page loads correctly.
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');

    // Test with empty image style.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
      'image_style' => '',
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');
  }

  /**
   * Tests preview rendering with non-image files.
   */
  public function testNonImagePreviewRendering() {
    $this->drupalLogin($this->adminUser);

    // Test non-image file preview.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testFile->id(),
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Verify the preview wrapper exists.
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');

    // Should NOT contain image style selector for non-image files.
    $select_elements = $this->getSession()->getPage()->findAll('css', 'select');
    $this->assertEmpty($select_elements, 'Non-image files should not have image style selectors');

    // Should contain some kind of preview content (image or other element).
    $has_preview_content =
      !empty($this->getSession()->getPage()->findAll('css', 'img')) ||
      !empty($this->getSession()->getPage()->findAll('css', '#file-browser-preview-wrapper *'));
    $this->assertTrue($has_preview_content, 'Preview should contain some content for non-image files');
  }

  /**
   * Tests behavior with invalid file IDs.
   */
  public function testInvalidFileIds() {
    $this->drupalLogin($this->adminUser);

    // Test with non-existent file ID.
    $non_existent_id = $this->testFile->id() + 999;
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $non_existent_id,
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(404);

    // Test with an invalid file ID format (should be handled by routing).
    $this->drupalGet('/admin/file-browser-preview/not-a-number/');
    $this->assertSession()->statusCodeEquals(404);
  }

  /**
   * Tests file access control.
   */
  public function testFileAccessControl() {
    // Create a private file for access control testing.
    $private_file_contents = 'Private file contents.';
    /** @var \Drupal\file\FileRepositoryInterface $file_repository */
    $file_repository = \Drupal::service('file.repository');
    $private_file = $file_repository->writeData($private_file_contents, 'private://private-test.txt');
    $private_file->setPermanent();
    $private_file->save();

    // Admin user may or may not be able to access private files depending
    // on configuration.
    $this->drupalLogin($this->adminUser);
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $private_file->id(),
    ]);
    $this->drupalGet($url);
    $status = $this->getSession()->getStatusCode();
    $this->assertContains(
      $status,
      [200, 403],
      'Admin access to private files should be either allowed (200) or forbidden (403)'
    );

    // Regular authenticated user without specific permissions.
    $this->drupalLogin($this->authenticatedUser);
    $this->drupalGet($url);
    // Private files may be restricted - check the actual response.
    $status = $this->getSession()->getStatusCode();
    $this->assertContains(
      $status,
      [200, 403],
      'Private file access should be either allowed (200) or forbidden (403)'
    );

    // Test access to a public file.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testFile->id(),
    ]);
    $this->drupalGet($url);
    // Public files should be accessible to authenticated users.
    $this->assertSession()->statusCodeEquals(200);

    // Clean up.
    $private_file->delete();
  }

  /**
   * Tests JavaScript integration and AJAX functionality.
   */
  public function testJavaScriptIntegration() {
    $this->drupalLogin($this->adminUser);

    // Test that the preview page includes required JavaScript libraries.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
    ]);
    $this->drupalGet($url);

    // Check that JavaScript libraries and settings are attached.
    // The library might be referenced in different ways in the HTML.
    $content = $this->getSession()->getPage()->getContent();

    // Check for any file_browser related JavaScript or settings.
    $has_js_integration =
      str_contains($content, 'file_browser') ||
      str_contains($content, 'preview') ||
      str_contains($content, 'drupalSettings');

    $this->assertTrue($has_js_integration, 'Page should contain JavaScript integration elements');

    // Verify the preview wrapper has the correct ID for JavaScript targeting.
    $this->assertSession()->elementExists('css', '#file-browser-preview-wrapper');
  }

  /**
   * Tests permission-based access with different user roles.
   */
  public function testPermissionBasedAccess() {
    // Create a user with explicit file view permissions.
    $file_viewer = $this->drupalCreateUser([
      'access content',
      'access files overview',
    ]);

    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testFile->id(),
    ]);

    // Test restricted user (no file permissions).
    $this->drupalLogin($this->restrictedUser);
    $this->drupalGet($url);
    // Public files should be accessible even to users with minimal permissions.
    $this->assertSession()->statusCodeEquals(200);

    // Test user with file view permissions.
    $this->drupalLogin($file_viewer);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Test admin user (all permissions).
    $this->drupalLogin($this->adminUser);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);
  }

  /**
   * Tests route parameter conversion and validation.
   */
  public function testRouteParameterHandling() {
    $this->drupalLogin($this->adminUser);

    // Test that a file parameter is properly converted to a file entity.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testFile->id(),
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Test that the image_style parameter is optional.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);

    // Test with explicit empty image_style.
    $url = Url::fromRoute('file_browser.preview', [
      'file' => $this->testImage->id(),
      'image_style' => '',
    ]);
    $this->drupalGet($url);
    $this->assertSession()->statusCodeEquals(200);
  }

}

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

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