Same name in this branch
  1. 10 core/modules/ckeditor5/tests/src/FunctionalJavascript/ImageTest.php \Drupal\Tests\ckeditor5\FunctionalJavascript\ImageTest
  2. 10 core/tests/Drupal/KernelTests/Core/Theme/ImageTest.php \Drupal\KernelTests\Core\Theme\ImageTest
  3. 10 core/tests/Drupal/Tests/Component/Utility/ImageTest.php \Drupal\Tests\Component\Utility\ImageTest
  4. 10 core/tests/Drupal/Tests/Core/Image/ImageTest.php \Drupal\Tests\Core\Image\ImageTest
Same name and namespace in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Image/ImageTest.php \Drupal\Tests\Core\Image\ImageTest
  2. 9 core/tests/Drupal/Tests/Core/Image/ImageTest.php \Drupal\Tests\Core\Image\ImageTest

Tests the image class.

@requires extension gd @group Image

Hierarchy

Expanded class hierarchy of ImageTest

File

core/tests/Drupal/Tests/Core/Image/ImageTest.php, line 18

Namespace

Drupal\Tests\Core\Image
View source
class ImageTest extends UnitTestCase {

  /**
   * Image source path.
   *
   * @var string
   */
  protected $source;

  /**
   * Image object.
   *
   * @var \Drupal\Core\Image\Image
   */
  protected $image;

  /**
   * Mocked image toolkit.
   *
   * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
   */
  protected $toolkit;

  /**
   * Mocked image toolkit operation.
   *
   * @var \Drupal\Core\ImageToolkit\ImageToolkitOperationInterface
   */
  protected $toolkitOperation;

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

    // Use the Druplicon image.
    $this->source = __DIR__ . '/../../../../../misc/druplicon.png';
  }

  /**
   * Mocks a toolkit.
   *
   * @param array $stubs
   *   (optional) Array containing methods to be replaced with stubs.
   *
   * @return \PHPUnit\Framework\MockObject\MockObject
   */
  protected function getToolkitMock(array $stubs = []) {
    $mock_builder = $this
      ->getMockBuilder('Drupal\\system\\Plugin\\ImageToolkit\\GDToolkit');
    $stubs = array_merge([
      'getPluginId',
      'save',
    ], $stubs);
    return $mock_builder
      ->disableOriginalConstructor()
      ->onlyMethods($stubs)
      ->getMock();
  }

  /**
   * Mocks a toolkit operation.
   *
   * @param string $class_name
   *   The name of the GD toolkit operation class to be mocked.
   * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
   *   The image toolkit object.
   *
   * @return \PHPUnit\Framework\MockObject\MockObject
   */
  protected function getToolkitOperationMock($class_name, ImageToolkitInterface $toolkit) {
    $mock_builder = $this
      ->getMockBuilder('Drupal\\system\\Plugin\\ImageToolkit\\Operation\\gd\\' . $class_name);
    $logger = $this
      ->createMock('Psr\\Log\\LoggerInterface');
    return $mock_builder
      ->onlyMethods([
      'execute',
    ])
      ->setConstructorArgs([
      [],
      '',
      [],
      $toolkit,
      $logger,
    ])
      ->getMock();
  }

  /**
   * Get an image with a mocked toolkit, for testing.
   *
   * @param bool $load_expected
   *   (optional) Whether the load() method is expected to be called. Defaults
   *   to TRUE.
   * @param array $stubs
   *   (optional) Array containing toolkit methods to be replaced with stubs.
   *
   * @return \Drupal\Core\Image\Image
   *   An image object.
   */
  protected function getTestImage($load_expected = TRUE, array $stubs = []) {
    if (!$load_expected && !in_array('load', $stubs)) {
      $stubs = array_merge([
        'load',
      ], $stubs);
    }
    $this->toolkit = $this
      ->getToolkitMock($stubs);
    $this->toolkit
      ->expects($this
      ->any())
      ->method('getPluginId')
      ->willReturn('gd');
    if (!$load_expected) {
      $this->toolkit
        ->expects($this
        ->never())
        ->method('load');
    }
    $this->image = new Image($this->toolkit, $this->source);
    return $this->image;
  }

  /**
   * Get an image with mocked toolkit and operation, for operation testing.
   *
   * @param string $class_name
   *   The name of the GD toolkit operation class to be mocked.
   *
   * @return \Drupal\Core\Image\Image
   *   An image object.
   */
  protected function getTestImageForOperation($class_name) {
    $this->toolkit = $this
      ->getToolkitMock([
      'getToolkitOperation',
    ]);
    $this->toolkitOperation = $this
      ->getToolkitOperationMock($class_name, $this->toolkit);
    $this->toolkit
      ->expects($this
      ->any())
      ->method('getPluginId')
      ->willReturn('gd');
    $this->toolkit
      ->expects($this
      ->any())
      ->method('getToolkitOperation')
      ->willReturn($this->toolkitOperation);
    $this->image = new Image($this->toolkit, $this->source);
    return $this->image;
  }

  /**
   * Tests \Drupal\Core\Image\Image::getHeight().
   */
  public function testGetHeight() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals(100, $this->image
      ->getHeight());
  }

  /**
   * Tests \Drupal\Core\Image\Image::getWidth().
   */
  public function testGetWidth() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals(88, $this->image
      ->getWidth());
  }

  /**
   * Tests \Drupal\Core\Image\Image::getFileSize.
   */
  public function testGetFileSize() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals(3905, $this->image
      ->getFileSize());
  }

  /**
   * Tests \Drupal\Core\Image\Image::getToolkit()->getType().
   */
  public function testGetType() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals(IMAGETYPE_PNG, $this->image
      ->getToolkit()
      ->getType());
  }

  /**
   * Tests \Drupal\Core\Image\Image::getMimeType().
   */
  public function testGetMimeType() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals('image/png', $this->image
      ->getMimeType());
  }

  /**
   * Tests \Drupal\Core\Image\Image::isValid().
   */
  public function testIsValid() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertTrue($this->image
      ->isValid());
    $this
      ->assertFileIsReadable($this->image
      ->getSource());
  }

  /**
   * Tests \Drupal\Core\Image\Image::getToolkitId().
   */
  public function testGetToolkitId() {
    $this
      ->getTestImage(FALSE);
    $this
      ->assertEquals('gd', $this->image
      ->getToolkitId());
  }

  /**
   * Tests \Drupal\Core\Image\Image::save().
   */
  public function testSave() {
    $this
      ->getTestImage();

    // This will fail if save() method isn't called on the toolkit.
    $toolkit = $this
      ->getToolkitMock();
    $toolkit
      ->expects($this
      ->once())
      ->method('save')
      ->willReturn(TRUE);
    $image = new Image($toolkit, $this->image
      ->getSource());
    $file_system = $this
      ->prophesize(FileSystemInterface::class);
    $file_system
      ->chmod($this->image
      ->getSource())
      ->willReturn(TRUE);
    $container = $this
      ->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')
      ->onlyMethods([
      'get',
    ])
      ->getMock();
    $container
      ->expects($this
      ->once())
      ->method('get')
      ->with('file_system')
      ->willReturn($file_system
      ->reveal());
    \Drupal::setContainer($container);
    $image
      ->save();
  }

  /**
   * Tests \Drupal\Core\Image\Image::save().
   */
  public function testSaveFails() {
    $this
      ->getTestImage();

    // This will fail if save() method isn't called on the toolkit.
    $this->toolkit
      ->expects($this
      ->once())
      ->method('save')
      ->willReturn(FALSE);
    $this
      ->assertFalse($this->image
      ->save());
  }

  /**
   * Tests \Drupal\Core\Image\Image::save().
   */
  public function testChmodFails() {
    $this
      ->getTestImage();

    // This will fail if save() method isn't called on the toolkit.
    $toolkit = $this
      ->getToolkitMock();
    $toolkit
      ->expects($this
      ->once())
      ->method('save')
      ->willReturn(TRUE);
    $image = new Image($toolkit, $this->image
      ->getSource());
    $file_system = $this
      ->prophesize(FileSystemInterface::class);
    $file_system
      ->chmod($this->image
      ->getSource())
      ->willReturn(FALSE);
    $container = $this
      ->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')
      ->onlyMethods([
      'get',
    ])
      ->getMock();
    $container
      ->expects($this
      ->once())
      ->method('get')
      ->with('file_system')
      ->willReturn($file_system
      ->reveal());
    \Drupal::setContainer($container);
    $this
      ->assertFalse($image
      ->save());
  }

  /**
   * Tests \Drupal\Core\Image\Image::parseFile().
   */
  public function testParseFileFails() {
    $toolkit = $this
      ->getToolkitMock();
    $image = new Image($toolkit, 'magic-foobar.png');
    $this
      ->assertFalse($image
      ->isValid());
    $this
      ->assertFalse($image
      ->save());
  }

  /**
   * Tests \Drupal\Core\Image\Image::scale().
   */
  public function testScaleWidth() {
    $this
      ->getTestImageForOperation('Scale');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scale(44, NULL, FALSE);
    $this
      ->assertEquals(50, $ret['height']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::scale().
   */
  public function testScaleHeight() {
    $this
      ->getTestImageForOperation('Scale');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scale(NULL, 50, FALSE);
    $this
      ->assertEquals(44, $ret['width']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::scale().
   */
  public function testScaleSame() {
    $this
      ->getTestImageForOperation('Scale');

    // Dimensions are the same, resize should not be called.
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scale(88, 100, FALSE);
    $this
      ->assertEquals(88, $ret['width']);
    $this
      ->assertEquals(100, $ret['height']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::scaleAndCrop().
   */
  public function testScaleAndCropWidth() {
    $this
      ->getTestImageForOperation('ScaleAndCrop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scaleAndCrop(34, 50);
    $this
      ->assertEquals(5, $ret['x']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::scaleAndCrop().
   */
  public function testScaleAndCropHeight() {
    $this
      ->getTestImageForOperation('ScaleAndCrop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scaleAndCrop(44, 40);
    $this
      ->assertEquals(5, $ret['y']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::scaleAndCrop().
   */
  public function testScaleAndCropFails() {
    $this
      ->getTestImageForOperation('ScaleAndCrop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->scaleAndCrop(44, 40);
    $this
      ->assertEquals(0, $ret['x']);
    $this
      ->assertEquals(5, $ret['y']);
    $this
      ->assertEquals(44, $ret['resize']['width']);
    $this
      ->assertEquals(50, $ret['resize']['height']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::crop().
   */
  public function testCropWidth() {
    $this
      ->getTestImageForOperation('Crop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);

    // Cropping with width only should preserve the aspect ratio.
    $ret = $this->image
      ->crop(0, 0, 44);
    $this
      ->assertEquals(50, $ret['height']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::crop().
   */
  public function testCropHeight() {
    $this
      ->getTestImageForOperation('Crop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);

    // Cropping with height only should preserve the aspect ratio.
    $ret = $this->image
      ->crop(0, 0, NULL, 50);
    $this
      ->assertEquals(44, $ret['width']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::crop().
   */
  public function testCrop() {
    $this
      ->getTestImageForOperation('Crop');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->crop(0, 0, 44, 50);
    $this
      ->assertEquals(44, $ret['width']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::convert().
   */
  public function testConvert() {
    $this
      ->getTestImageForOperation('Convert');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->convert('png');
    $this
      ->assertEquals('png', $ret['extension']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::resize().
   */
  public function testResize() {
    $this
      ->getTestImageForOperation('Resize');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);

    // Resize with integer for width and height.
    $ret = $this->image
      ->resize(30, 40);
    $this
      ->assertEquals(30, $ret['width']);
    $this
      ->assertEquals(40, $ret['height']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::resize().
   */
  public function testFloatResize() {
    $this
      ->getTestImageForOperation('Resize');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);

    // Pass a float for width.
    $ret = $this->image
      ->resize(30.4, 40);

    // Ensure that the float was rounded to an integer first.
    $this
      ->assertEquals(30, $ret['width']);
  }

  /**
   * Tests \Drupal\Core\Image\Image::desaturate().
   */
  public function testDesaturate() {
    $this
      ->getTestImageForOperation('Desaturate');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $this->image
      ->desaturate();
  }

  /**
   * Tests \Drupal\Core\Image\Image::rotate().
   */
  public function testRotate() {
    $this
      ->getTestImageForOperation('Rotate');
    $this->toolkitOperation
      ->expects($this
      ->once())
      ->method('execute')
      ->willReturnArgument(0);
    $ret = $this->image
      ->rotate(90);
    $this
      ->assertEquals(90, $ret['degrees']);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ImageTest::$image protected property Image object.
ImageTest::$source protected property Image source path.
ImageTest::$toolkit protected property Mocked image toolkit.
ImageTest::$toolkitOperation protected property Mocked image toolkit operation.
ImageTest::getTestImage protected function Get an image with a mocked toolkit, for testing.
ImageTest::getTestImageForOperation protected function Get an image with mocked toolkit and operation, for operation testing.
ImageTest::getToolkitMock protected function Mocks a toolkit.
ImageTest::getToolkitOperationMock protected function Mocks a toolkit operation.
ImageTest::setUp protected function Overrides UnitTestCase::setUp
ImageTest::testChmodFails public function Tests \Drupal\Core\Image\Image::save().
ImageTest::testConvert public function Tests \Drupal\Core\Image\Image::convert().
ImageTest::testCrop public function Tests \Drupal\Core\Image\Image::crop().
ImageTest::testCropHeight public function Tests \Drupal\Core\Image\Image::crop().
ImageTest::testCropWidth public function Tests \Drupal\Core\Image\Image::crop().
ImageTest::testDesaturate public function Tests \Drupal\Core\Image\Image::desaturate().
ImageTest::testFloatResize public function Tests \Drupal\Core\Image\Image::resize().
ImageTest::testGetFileSize public function Tests \Drupal\Core\Image\Image::getFileSize.
ImageTest::testGetHeight public function Tests \Drupal\Core\Image\Image::getHeight().
ImageTest::testGetMimeType public function Tests \Drupal\Core\Image\Image::getMimeType().
ImageTest::testGetToolkitId public function Tests \Drupal\Core\Image\Image::getToolkitId().
ImageTest::testGetType public function Tests \Drupal\Core\Image\Image::getToolkit()->getType().
ImageTest::testGetWidth public function Tests \Drupal\Core\Image\Image::getWidth().
ImageTest::testIsValid public function Tests \Drupal\Core\Image\Image::isValid().
ImageTest::testParseFileFails public function Tests \Drupal\Core\Image\Image::parseFile().
ImageTest::testResize public function Tests \Drupal\Core\Image\Image::resize().
ImageTest::testRotate public function Tests \Drupal\Core\Image\Image::rotate().
ImageTest::testSave public function Tests \Drupal\Core\Image\Image::save().
ImageTest::testSaveFails public function Tests \Drupal\Core\Image\Image::save().
ImageTest::testScaleAndCropFails public function Tests \Drupal\Core\Image\Image::scaleAndCrop().
ImageTest::testScaleAndCropHeight public function Tests \Drupal\Core\Image\Image::scaleAndCrop().
ImageTest::testScaleAndCropWidth public function Tests \Drupal\Core\Image\Image::scaleAndCrop().
ImageTest::testScaleHeight public function Tests \Drupal\Core\Image\Image::scale().
ImageTest::testScaleSame public function Tests \Drupal\Core\Image\Image::scale().
ImageTest::testScaleWidth public function Tests \Drupal\Core\Image\Image::scale().
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function
UnitTestCase::__get public function