Skip to content

Commit 673f119

Browse files
committed
Merge remote-tracking branch 'act4/ACP2E-3558' into pr_january_doleksandr
2 parents aa203b5 + 0144f7e commit 673f119

File tree

4 files changed

+168
-34
lines changed

4 files changed

+168
-34
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\TestFramework\Fixture;
10+
11+
use Magento\Framework\App\Filesystem\DirectoryList;
12+
use Magento\Framework\DataObject;
13+
use Magento\Framework\DataObjectFactory;
14+
use Magento\Framework\Filesystem;
15+
use Magento\TestFramework\Fixture\Data\ProcessorInterface;
16+
17+
/**
18+
* Creates an image fixture
19+
*
20+
* Example: Basic usage. This will create a jpeg image in var/tmp/fixtures/ directory with unique name
21+
* ```php
22+
* #[
23+
* DataFixture(ImageFixture::class, as: 'image')
24+
* ],
25+
* ```
26+
* Example: Create an image and save it in a custom directory in var/tmp directory
27+
*
28+
* ```php
29+
* #[
30+
* DataFixture(ImageFixture::class, ['path' => 'custom/dir/image.jpeg'])
31+
* ],
32+
* ```
33+
* Example: Create an image with custom sizes
34+
*
35+
* ```php
36+
* #[
37+
* DataFixture(ImageFixture::class, ['width' => 200, 'height' => 100])
38+
* ],
39+
* ```
40+
*/
41+
class ImageFixture implements RevertibleDataFixtureInterface
42+
{
43+
private const array DEFAULT_DATA = [
44+
'directory' => DirectoryList::TMP,
45+
'type' => 'image/jpeg',
46+
'path' => 'fixtures/%uniqid%.%ext%',
47+
'content' => '',
48+
'width' => 1024,
49+
'height' => 768,
50+
];
51+
52+
/**
53+
* @param Filesystem $filesystem
54+
* @param ProcessorInterface $dataProcessor
55+
* @param DataObjectFactory $dataObjectFactory
56+
*/
57+
public function __construct(
58+
private readonly Filesystem $filesystem,
59+
private readonly ProcessorInterface $dataProcessor,
60+
private readonly DataObjectFactory $dataObjectFactory
61+
) {
62+
}
63+
64+
/**
65+
* @inheritdoc
66+
*/
67+
public function apply(array $data = []): ?DataObject
68+
{
69+
$data = $this->dataProcessor->process($this, array_merge(self::DEFAULT_DATA, $data));
70+
$directory = $this->filesystem->getDirectoryWrite($data['directory']);
71+
$ext = 'jpeg';
72+
if (!$data['content']) {
73+
ob_start();
74+
$image = imagecreatetruecolor($data['width'], $data['height']);
75+
switch ($data['type']) {
76+
case 'image/jpeg':
77+
imagejpeg($image);
78+
break;
79+
case 'image/png':
80+
imagepng($image);
81+
$ext = 'png';
82+
break;
83+
case 'image/gif':
84+
imagegif($image);
85+
$ext = 'gif';
86+
break;
87+
default:
88+
throw new \InvalidArgumentException('Unsupported image type');
89+
}
90+
$data['content'] = ob_get_clean();
91+
imagedestroy($image);
92+
}
93+
$data['path'] = str_replace('%ext%', $ext, $data['path']);
94+
$directory->writeFile($data['path'], $data['content']);
95+
$data['absolute_path'] = $directory->getAbsolutePath($data['path']);
96+
97+
return $this->dataObjectFactory->create(['data' => $data]);
98+
}
99+
100+
/**
101+
* @inheritDoc
102+
*/
103+
public function revert(DataObject $data): void
104+
{
105+
$directory = $this->filesystem->getDirectoryWrite($data['directory']);
106+
$directory->delete($data['path']);
107+
}
108+
}

dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2012 Adobe
4+
* All Rights Reserved.
55
*/
6+
67
namespace Magento\Framework\Image\Adapter;
78

89
use Magento\Framework\App\Filesystem\DirectoryList;
910
use Magento\Framework\Filesystem\Directory\WriteInterface;
11+
use Magento\TestFramework\Fixture\DataFixture;
12+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
13+
use Magento\TestFramework\Fixture\ImageFixture;
1014

1115
/**
1216
* @magentoDataFixture Magento/Framework/Image/_files/image_fixture.php
@@ -267,36 +271,59 @@ public static function saveDataProvider()
267271
/**
268272
* @param string $image
269273
* @param array $dims (width, height)
274+
* @param boolean $keepRatio
275+
* @param array|null $expectedDims (width, height)
276+
* @param string|null $expectedException
270277
* @param string $adapterType
271278
*
272279
* @dataProvider resizeDataProvider
273280
* @depends testOpen
274281
*/
275-
public function testResize($image, $dims, $adapterType)
276-
{
282+
#[
283+
DataFixture(ImageFixture::class, ['width' => 1024, 'height' => 768], as: 'image1'),
284+
DataFixture(ImageFixture::class, ['width' => 1712, 'height' => 2], as: 'image2'),
285+
DataFixture(ImageFixture::class, ['width' => 2, 'height' => 1712], as: 'image3'),
286+
]
287+
public function testResize(
288+
string $image,
289+
array $dims,
290+
bool $keepRatio,
291+
?array $expectedDims,
292+
?string $expectedException,
293+
string $adapterType
294+
): void {
295+
$image = DataFixtureStorageManager::getStorage()->get($image)->getAbsolutePath();
277296
$adapter = $this->_getAdapter($adapterType);
278297
$adapter->open($image);
279-
try {
280-
$adapter->resize($dims[0], $dims[1]);
281-
$this->assertEquals($dims, [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()]);
282-
} catch (\Exception $e) {
283-
$result = $dims[0] !== null && $dims[0] <= 0 ||
284-
$dims[1] !== null && $dims[1] <= 0 ||
285-
empty(${$dims[0]}) && empty(${$dims[1]});
286-
$this->assertTrue($result);
298+
if ($keepRatio) {
299+
$adapter->keepAspectRatio($keepRatio);
300+
}
301+
if ($expectedException) {
302+
$this->expectExceptionMessage($expectedException);
287303
}
304+
$adapter->resize($dims[0], $dims[1]);
305+
$this->assertEquals($expectedDims, [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()]);
288306
}
289307

290-
public static function resizeDataProvider()
308+
public static function resizeDataProvider(): array
291309
{
292310
return self::_prepareData(
293311
[
294-
[self::_getFixture('image_adapters_test.png'), [150, 70]],
295-
[self::_getFixture('image_adapters_test.png'), [null, 70]],
296-
[self::_getFixture('image_adapters_test.png'), [100, null]],
297-
[self::_getFixture('image_adapters_test.png'), [null, null]],
298-
[self::_getFixture('image_adapters_test.png'), [-100, -50]],
299-
[self::_getFixture('image_adapters_test.png'), [200, 0]]
312+
['image1', [-100, -70], false, null, 'Invalid image dimensions.'],
313+
['image1', [-100, 70], false, null, 'Invalid image dimensions.'],
314+
['image1', [100, -70], false, null, 'Invalid image dimensions.'],
315+
['image1', [0, 0], false, null, 'Invalid image dimensions.'],
316+
['image1', [0, 70], false, null, 'Invalid image dimensions.'],
317+
['image1', [100, 0], false, null, 'Invalid image dimensions.'],
318+
['image1', [null, null], false, null, 'Invalid image dimensions.'],
319+
['image1', [null, 70], false, [93, 70], null],
320+
['image1', [100, null], false, [100, 75], null],
321+
['image1', [100, 70], false, [100, 70], null],
322+
['image1', [100, 70], true, [93, 70], null],
323+
['image2', [100, 2], false, [100, 2], null],
324+
['image2', [100, 2], true, [100, 1], null],
325+
['image3', [2, 100], false, [2, 100], null],
326+
['image3', [2, 100], true, [1, 100], null],
300327
]
301328
);
302329
}

dev/tests/static/testsuite/Magento/Test/Integrity/ParameterizedFixtureTest.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2022 Adobe
4+
* All Rights Reserved.
55
*/
6-
declare(strict_types=1);
76

7+
declare(strict_types=1);
88

99
namespace Magento\Test\Integrity;
1010

@@ -21,6 +21,10 @@
2121
*/
2222
class ParameterizedFixtureTest extends TestCase
2323
{
24+
private const array MODULES_WITH_FIXTURES = [
25+
'Magento\TestFramework\Fixture'
26+
];
27+
2428
/**
2529
* Validates parameterized data fixtures location
2630
*
@@ -48,7 +52,7 @@ public function testLocation(): void
4852
continue;
4953
}
5054

51-
if (!$this->isFileLocatedInModuleDirectory($file)) {
55+
if (!$this->isLocationValid($file, $classReflection->getNamespaceName())) {
5256
$errors[] = $errorMessage;
5357
}
5458
}
@@ -60,18 +64,13 @@ public function testLocation(): void
6064

6165
/**
6266
* @param string $file
67+
* @param string $namespace
6368
* @return bool
6469
*/
65-
private function isFileLocatedInModuleDirectory(string $file): bool
70+
private function isLocationValid(string $file, string $namespace): bool
6671
{
67-
$componentRegistrar = new ComponentRegistrar();
68-
$found = false;
69-
foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
70-
if ($file === $moduleDir . '/Test/Fixture/' . basename($file)) {
71-
$found = true;
72-
break;
73-
}
74-
}
75-
return $found;
72+
return in_array($namespace, self::MODULES_WITH_FIXTURES)
73+
|| (str_ends_with(dirname($file), '/Test/Fixture')
74+
&& in_array(dirname($file, 3), (new ComponentRegistrar())->getPaths(ComponentRegistrar::MODULE)));
7675
}
7776
}

lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ protected function _checkAspectRatio($frameWidth, $frameHeight)
614614
if ($this->_imageSrcWidth / $this->_imageSrcHeight >= $frameWidth / $frameHeight) {
615615
$dstHeight = max(1, round($dstWidth / $this->_imageSrcWidth * $this->_imageSrcHeight));
616616
} else {
617-
$dstWidth = round($dstHeight / $this->_imageSrcHeight * $this->_imageSrcWidth);
617+
$dstWidth = max(1, round($dstHeight / $this->_imageSrcHeight * $this->_imageSrcWidth));
618618
}
619619
}
620620
return [$dstWidth, $dstHeight];

0 commit comments

Comments
 (0)