Skip to content

Commit b1d1217

Browse files
committed
Merge remote-tracking branch 'mainline/2.4-develop' into 2.4-develop-pr1
2 parents 94032b1 + 27a3905 commit b1d1217

File tree

19 files changed

+444
-68
lines changed

19 files changed

+444
-68
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Test\Unit\Model\Product\Price\Validation;
10+
11+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
12+
use Magento\Catalog\Model\Product\Price\Validation\Result;
13+
use PHPUnit\Framework\TestCase;
14+
use Magento\Catalog\Api\Data\PriceUpdateResultInterface;
15+
use Magento\Catalog\Api\Data\PriceUpdateResultInterfaceFactory;
16+
17+
class ResultTest extends TestCase
18+
{
19+
/**
20+
* @var Result
21+
*/
22+
private $model;
23+
24+
/**
25+
* @var PriceUpdateResultInterfaceFactory|PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
private $priceUpdateResultFactory;
28+
29+
/**
30+
* @var ObjectManagerHelper|PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
private $objectManager;
33+
34+
/**
35+
* Setup environment for test
36+
*/
37+
protected function setUp()
38+
{
39+
$this->priceUpdateResultFactory = $this->getMockBuilder(PriceUpdateResultInterfaceFactory::class)
40+
->disableOriginalConstructor()
41+
->setMethods(['create'])
42+
->getMock();
43+
44+
$this->objectManager = new ObjectManagerHelper($this);
45+
$this->model = $this->objectManager->getObject(
46+
Result::class,
47+
[
48+
'priceUpdateResultFactory' => $this->priceUpdateResultFactory
49+
]
50+
);
51+
52+
$this->model->addFailedItem(1, 'Invalid attribute color = 1', ['SKU' => 'ABC', 'storeId' => 1]);
53+
$this->model->addFailedItem(2, 'Invalid attribute size = M', ['SKU' => 'DEF', 'storeId' => 1]);
54+
}
55+
56+
/**
57+
* Test getFailedRowIds() function
58+
*/
59+
public function testGetFailedRowIds()
60+
{
61+
$this->assertEquals([1, 2], $this->model->getFailedRowIds());
62+
}
63+
64+
/**
65+
* Test getFailedItems() function
66+
*/
67+
public function testGetFailedItems()
68+
{
69+
$priceUpdateResult1 = $this->createMock(PriceUpdateResultInterface::class);
70+
$priceUpdateResult2 = $this->createMock(PriceUpdateResultInterface::class);
71+
72+
$this->priceUpdateResultFactory->expects($this->at(0))
73+
->method('create')
74+
->willReturn($priceUpdateResult1);
75+
$this->priceUpdateResultFactory->expects($this->at(1))
76+
->method('create')
77+
->willReturn($priceUpdateResult2);
78+
79+
$priceUpdateResult1->expects($this->once())->method('setMessage')
80+
->with('Invalid attribute color = 1');
81+
$priceUpdateResult1->expects($this->once())->method('setParameters')
82+
->with(['SKU' => 'ABC', 'storeId' => 1]);
83+
84+
$priceUpdateResult2->expects($this->once())->method('setMessage')
85+
->with('Invalid attribute size = M');
86+
$priceUpdateResult2->expects($this->once())->method('setParameters')
87+
->with(['SKU' => 'DEF', 'storeId' => 1]);
88+
89+
$this->assertEquals([$priceUpdateResult1, $priceUpdateResult2], $this->model->getFailedItems());
90+
}
91+
}

app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,28 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
8+
declare(strict_types=1);
9+
710
namespace Magento\Cms\Controller\Adminhtml\Wysiwyg;
811

912
use Magento\Backend\App\Action;
1013
use Magento\Cms\Model\Template\Filter;
1114
use Magento\Cms\Model\Wysiwyg\Config;
1215
use Magento\Framework\App\Action\HttpGetActionInterface;
16+
use Magento\Framework\Image\Adapter\AdapterInterface;
17+
use Magento\Framework\Image\AdapterFactory;
18+
use Psr\Log\LoggerInterface;
19+
use Magento\Framework\Url\DecoderInterface;
20+
use Magento\Framework\Controller\Result\Raw;
21+
use Magento\Framework\Controller\Result\RawFactory;
22+
use Magento\Backend\App\Action\Context;
23+
use Magento\Framework\App\ObjectManager;
1324

1425
/**
1526
* Process template text for wysiwyg editor.
27+
*
28+
* Class Directive
1629
*/
1730
class Directive extends Action implements HttpGetActionInterface
1831
{
@@ -25,58 +38,94 @@ class Directive extends Action implements HttpGetActionInterface
2538
const ADMIN_RESOURCE = 'Magento_Cms::media_gallery';
2639

2740
/**
28-
* @var \Magento\Framework\Url\DecoderInterface
41+
* @var DecoderInterface
2942
*/
3043
protected $urlDecoder;
3144

3245
/**
33-
* @var \Magento\Framework\Controller\Result\RawFactory
46+
* @var RawFactory
3447
*/
3548
protected $resultRawFactory;
3649

3750
/**
38-
* @param Action\Context $context
39-
* @param \Magento\Framework\Url\DecoderInterface $urlDecoder
40-
* @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
51+
* @var LoggerInterface
52+
*/
53+
private $logger;
54+
55+
/**
56+
* @var AdapterFactory
57+
*/
58+
private $adapterFactory;
59+
60+
/**
61+
* @var Config
62+
*/
63+
private $config;
64+
65+
/**
66+
* @var Filter
67+
*/
68+
private $filter;
69+
70+
/**
71+
* Constructor
72+
*
73+
* @param Context $context
74+
* @param DecoderInterface $urlDecoder
75+
* @param RawFactory $resultRawFactory
76+
* @param AdapterFactory|null $adapterFactory
77+
* @param LoggerInterface|null $logger
78+
* @param Config|null $config
79+
* @param Filter|null $filter
4180
*/
4281
public function __construct(
43-
Action\Context $context,
44-
\Magento\Framework\Url\DecoderInterface $urlDecoder,
45-
\Magento\Framework\Controller\Result\RawFactory $resultRawFactory
82+
Context $context,
83+
DecoderInterface $urlDecoder,
84+
RawFactory $resultRawFactory,
85+
AdapterFactory $adapterFactory = null,
86+
LoggerInterface $logger = null,
87+
Config $config = null,
88+
Filter $filter = null
4689
) {
4790
parent::__construct($context);
4891
$this->urlDecoder = $urlDecoder;
4992
$this->resultRawFactory = $resultRawFactory;
93+
$this->adapterFactory = $adapterFactory ?: ObjectManager::getInstance()->get(AdapterFactory::class);
94+
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
95+
$this->config = $config ?: ObjectManager::getInstance()->get(Config::class);
96+
$this->filter = $filter ?: ObjectManager::getInstance()->get(Filter::class);
5097
}
5198

5299
/**
53100
* Template directives callback
54101
*
55-
* @return \Magento\Framework\Controller\Result\Raw
102+
* @return Raw
56103
*/
57104
public function execute()
58105
{
59106
$directive = $this->getRequest()->getParam('___directive');
60107
$directive = $this->urlDecoder->decode($directive);
61108
try {
62109
/** @var Filter $filter */
63-
$filter = $this->_objectManager->create(Filter::class);
64-
$imagePath = $filter->filter($directive);
65-
/** @var \Magento\Framework\Image\Adapter\AdapterInterface $image */
66-
$image = $this->_objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create();
67-
/** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
110+
$imagePath = $this->filter->filter($directive);
111+
/** @var AdapterInterface $image */
112+
$image = $this->adapterFactory->create();
113+
/** @var Raw $resultRaw */
68114
$resultRaw = $this->resultRawFactory->create();
69115
$image->open($imagePath);
70116
$resultRaw->setHeader('Content-Type', $image->getMimeType());
71117
$resultRaw->setContents($image->getImage());
72118
} catch (\Exception $e) {
73119
/** @var Config $config */
74-
$config = $this->_objectManager->get(Config::class);
75-
$imagePath = $config->getSkinImagePlaceholderPath();
76-
$image->open($imagePath);
77-
$resultRaw->setHeader('Content-Type', $image->getMimeType());
78-
$resultRaw->setContents($image->getImage());
79-
$this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
120+
$imagePath = $this->config->getSkinImagePlaceholderPath();
121+
try {
122+
$image->open($imagePath);
123+
$resultRaw->setHeader('Content-Type', $image->getMimeType());
124+
$resultRaw->setContents($image->getImage());
125+
$this->logger->warning($e);
126+
} catch (\Exception $e) {
127+
$this->logger->warning($e);
128+
}
80129
}
81130
return $resultRaw;
82131
}

app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ public function createDirectory($name, $path)
416416
{
417417
if (!preg_match(self::DIRECTORY_NAME_REGEXP, $name)) {
418418
throw new \Magento\Framework\Exception\LocalizedException(
419-
__('Please rename the folder using only letters, numbers, underscores and dashes.')
419+
__('Please rename the folder using only Latin letters, numbers, underscores and dashes.')
420420
);
421421
}
422422

app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Wysiwyg/DirectiveTest.php

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ protected function setUp()
151151
[
152152
'context' => $this->actionContextMock,
153153
'urlDecoder' => $this->urlDecoderMock,
154-
'resultRawFactory' => $this->rawFactoryMock
154+
'resultRawFactory' => $this->rawFactoryMock,
155+
'adapterFactory' => $this->imageAdapterFactoryMock,
156+
'logger' => $this->loggerMock,
157+
'config' => $this->wysiwygConfigMock,
158+
'filter' => $this->templateFilterMock
155159
]
156160
);
157161
}
@@ -228,7 +232,7 @@ public function testExecuteException()
228232
->method('getImage')
229233
->willReturn($imageBody);
230234
$this->loggerMock->expects($this->once())
231-
->method('critical')
235+
->method('warning')
232236
->with($exception);
233237
$this->rawFactoryMock->expects($this->any())
234238
->method('create')
@@ -253,25 +257,46 @@ protected function prepareExecuteTest()
253257
->method('decode')
254258
->with($directiveParam)
255259
->willReturn($directive);
256-
$this->objectManagerMock->expects($this->once())
257-
->method('create')
258-
->with(\Magento\Cms\Model\Template\Filter::class)
259-
->willReturn($this->templateFilterMock);
260+
260261
$this->templateFilterMock->expects($this->once())
261262
->method('filter')
262263
->with($directive)
263264
->willReturn(self::IMAGE_PATH);
264-
$this->objectManagerMock->expects($this->any())
265-
->method('get')
266-
->willReturnMap(
267-
[
268-
[\Magento\Framework\Image\AdapterFactory::class, $this->imageAdapterFactoryMock],
269-
[\Magento\Cms\Model\Wysiwyg\Config::class, $this->wysiwygConfigMock],
270-
[\Psr\Log\LoggerInterface::class, $this->loggerMock]
271-
]
272-
);
265+
273266
$this->imageAdapterFactoryMock->expects($this->once())
274267
->method('create')
275268
->willReturn($this->imageAdapterMock);
276269
}
270+
271+
/**
272+
* Test Execute With Deleted Image
273+
*
274+
* @covers \Magento\Cms\Controller\Adminhtml\Wysiwyg\Directive::execute
275+
*/
276+
public function testExecuteWithDeletedImage()
277+
{
278+
$exception = new \Exception('epic fail');
279+
$placeholderPath = 'pub/static/adminhtml/Magento/backend/en_US/Magento_Cms/images/wysiwyg_skin_image.png';
280+
$this->prepareExecuteTest();
281+
282+
$this->imageAdapterMock->expects($this->any())
283+
->method('open')
284+
->with(self::IMAGE_PATH)
285+
->willThrowException($exception);
286+
287+
$this->wysiwygConfigMock->expects($this->once())
288+
->method('getSkinImagePlaceholderPath')
289+
->willReturn($placeholderPath);
290+
291+
$this->imageAdapterMock->expects($this->any())
292+
->method('open')
293+
->with($placeholderPath)
294+
->willThrowException($exception);
295+
296+
$this->loggerMock->expects($this->once())
297+
->method('warning')
298+
->with($exception);
299+
300+
$this->wysiwygDirective->execute();
301+
}
277302
}

app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Cms\Model\Wysiwyg\Images\Storage\Collection as StorageCollection;
99
use Magento\Framework\App\Filesystem\DirectoryList;
10+
use Magento\Framework\Exception\LocalizedException;
1011

1112
/**
1213
* @SuppressWarnings(PHPMD.LongVariable)
@@ -539,4 +540,18 @@ public function testUploadFile()
539540

540541
$this->assertEquals($result, $this->imagesStorage->uploadFile($targetPath, $type));
541542
}
543+
544+
/**
545+
* Test create directory with invalid name
546+
*/
547+
public function testCreateDirectoryWithInvalidName()
548+
{
549+
$name = 'папка';
550+
$path = '/tmp/path';
551+
$this->expectException(LocalizedException::class);
552+
$this->expectExceptionMessage(
553+
(string)__('Please rename the folder using only Latin letters, numbers, underscores and dashes.')
554+
);
555+
$this->imagesStorage->createDirectory($name, $path);
556+
}
542557
}

app/code/Magento/Cms/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Pages,Pages
7676
"The page URL key contains capital letters or disallowed symbols.","The page URL key contains capital letters or disallowed symbols."
7777
"The page URL key cannot be made of only numbers.","The page URL key cannot be made of only numbers."
7878
"Please rename the folder using only letters, numbers, underscores and dashes.","Please rename the folder using only letters, numbers, underscores and dashes."
79+
"Please rename the folder using only Latin letters, numbers, underscores and dashes.","Please rename the folder using only Latin letters, numbers, underscores and dashes."
7980
"We found a directory with the same name. Please try another folder name.","We found a directory with the same name. Please try another folder name."
8081
"We cannot create a new directory.","We cannot create a new directory."
8182
"We cannot delete directory %1.","We cannot delete directory %1."

0 commit comments

Comments
 (0)