diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Image/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Image/Upload.php index 285f4f1e3ffade4875266c634a241768b36215e9..25bd24ef70b9492d2da5b32e2a4146e3b1a0ab07 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Image/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Image/Upload.php @@ -50,8 +50,10 @@ class Upload extends \Magento\Backend\App\Action */ public function execute() { + $imageId = $this->_request->getParam('param_name', 'image'); + try { - $result = $this->imageUploader->saveFileToTmpDir('image'); + $result = $this->imageUploader->saveFileToTmpDir($imageId); $result['cookie'] = [ 'name' => $this->_getSession()->getName(), diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php index 55ae96faeb7e6424f51ec3d5a22054844ea5a812..492bf1c021cf04c071528821f2e966f506e6a17b 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Category; use Magento\Store\Model\StoreManagerInterface; +use \Magento\Catalog\Api\Data\CategoryAttributeInterface; /** * Class Save @@ -48,6 +49,11 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category */ private $storeManager; + /** + * @var \Magento\Eav\Model\Config + */ + private $eavConfig; + /** * Constructor * @@ -56,43 +62,22 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param StoreManagerInterface $storeManager + * @param \Magento\Eav\Model\Config $eavConfig */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Controller\Result\RawFactory $resultRawFactory, \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + \Magento\Eav\Model\Config $eavConfig ) { parent::__construct($context); $this->resultRawFactory = $resultRawFactory; $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->storeManager = $storeManager; - } - - /** - * Filter category data - * - * @param array $rawData - * @return array - */ - protected function _filterCategoryPostData(array $rawData) - { - $data = $rawData; - // @todo It is a workaround to prevent saving this data in category model and it has to be refactored in future - if (isset($data['image']) && is_array($data['image'])) { - if (!empty($data['image']['delete'])) { - $data['image'] = null; - } else { - if (isset($data['image'][0]['name']) && isset($data['image'][0]['tmp_name'])) { - $data['image'] = $data['image'][0]['name']; - } else { - unset($data['image']); - } - } - } - return $data; + $this->eavConfig = $eavConfig; } /** @@ -126,7 +111,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category $this->storeManager->setCurrentStore($store->getCode()); $parentId = isset($categoryPostData['parent']) ? $categoryPostData['parent'] : null; if ($categoryPostData) { - $category->addData($this->_filterCategoryPostData($categoryPostData)); + $category->addData($categoryPostData); if ($isNewCategory) { $parentCategory = $this->getParentCategory($parentId, $storeId); $category->setPath($parentCategory->getPath()); @@ -248,18 +233,29 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category } /** - * Image data preprocessing - * - * @param array $data - * - * @return array + * @param array $data Category data + * @return mixed + * @throws \Magento\Framework\Exception\LocalizedException */ - public function imagePreprocessing($data) + public function imagePreprocessing(array $data) { - if (empty($data['image'])) { - unset($data['image']); - $data['image']['delete'] = true; + $entityType = $this->eavConfig->getEntityType(CategoryAttributeInterface::ENTITY_TYPE_CODE); + + foreach ($entityType->getAttributeCollection() as $attributeModel) { + $attributeCode = $attributeModel->getAttributeCode(); + $backendModel = $attributeModel->getBackend(); + + if (isset($data[$attributeCode])) { + continue; + } + + if (!$backendModel instanceof \Magento\Catalog\Model\Category\Attribute\Backend\Image) { + continue; + } + + $data[$attributeCode] = false; } + return $data; } diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index b1f9dbf8c327a46176208cec90f8130065d8400a..86606278b19237a5a845b80282f0ba44471c6a05 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -652,14 +652,14 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements } /** - * Retrieve image URL - * - * @return string + * @param string $attributeCode + * @return bool|string + * @throws \Magento\Framework\Exception\LocalizedException */ - public function getImageUrl() + public function getImageUrl($attributeCode = 'image') { $url = false; - $image = $this->getImage(); + $image = $this->getData($attributeCode); if ($image) { if (is_string($image)) { $url = $this->_storeManager->getStore()->getBaseUrl( diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index 5eb4461ace5f0e88583337a9b8c2efe2c71bad64..efd3a4afb4a60d72490698b3c9453cec3609b4e7 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -13,6 +13,8 @@ namespace Magento\Catalog\Model\Category\Attribute\Backend; class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend { + const ADDITIONAL_DATA_PREFIX = '_additional_data_'; + /** * @var \Magento\MediaStorage\Model\File\UploaderFactory * @@ -21,8 +23,6 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend protected $_uploaderFactory; /** - * Filesystem facade - * * @var \Magento\Framework\Filesystem * * @deprecated @@ -30,8 +30,6 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend protected $_filesystem; /** - * File Uploader factory - * * @var \Magento\MediaStorage\Model\File\UploaderFactory * * @deprecated @@ -46,32 +44,68 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend protected $_logger; /** - * Image uploader - * * @var \Magento\Catalog\Model\ImageUploader */ private $imageUploader; /** - * Image constructor. - * + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory + * @param \Magento\Framework\ObjectManagerInterface $objectManager */ public function __construct( \Psr\Log\LoggerInterface $logger, \Magento\Framework\Filesystem $filesystem, - \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory + \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory, + \Magento\Framework\ObjectManagerInterface $objectManager ) { $this->_filesystem = $filesystem; $this->_fileUploaderFactory = $fileUploaderFactory; $this->_logger = $logger; + $this->objectManager = $objectManager; + } + + /** + * @param array $value Attribute value + * @return string + */ + protected function getUploadedImageName($value) + { + if (is_array($value) && isset($value[0]['name'])) { + return $value[0]['name']; + } + + return ''; } /** - * Get image uploader + * Avoiding saving potential upload data to DB * + * @param \Magento\Framework\DataObject $object + * @return $this + */ + public function beforeSave($object) + { + $attributeName = $this->getAttribute()->getName(); + $value = $object->getData($attributeName); + + if ($imageName = $this->getUploadedImageName($value)) { + $object->setData(self::ADDITIONAL_DATA_PREFIX . $attributeName, $value); + $object->setData($attributeName, $imageName); + } else if (!is_string($value)) { + $object->setData($attributeName, ''); + } + + return parent::beforeSave($object); + } + + /** * @return \Magento\Catalog\Model\ImageUploader * * @deprecated @@ -79,10 +113,9 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend private function getImageUploader() { if ($this->imageUploader === null) { - $this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Catalog\CategoryImageUpload::class - ); + $this->imageUploader = $this->objectManager->get(\Magento\Catalog\CategoryImageUpload::class); } + return $this->imageUploader; } @@ -94,15 +127,16 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend */ public function afterSave($object) { - $image = $object->getData($this->getAttribute()->getName(), null); + $value = $object->getData(self::ADDITIONAL_DATA_PREFIX . $this->getAttribute()->getName()); - if ($image !== null) { + if ($imageName = $this->getUploadedImageName($value)) { try { - $this->getImageUploader()->moveFileFromTmp($image); + $this->getImageUploader()->moveFileFromTmp($imageName); } catch (\Exception $e) { $this->_logger->critical($e); } } + return $this; } } diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index 8626d183e2fac36e2b2fb194c418384d9ff87d82..8ea60d54ec5564e7cea09c61ff7546283d3183de 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -17,6 +17,7 @@ use Magento\Ui\Component\Form\Field; use Magento\Ui\DataProvider\EavValidationRules; use Magento\Catalog\Model\CategoryFactory; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Catalog\Model\Category\Attribute\Backend\Image as ImageBackendModel; /** * Class DataProvider @@ -206,11 +207,8 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider $categoryData = $this->addUseDefaultSettings($category, $categoryData); $categoryData = $this->addUseConfigSettings($categoryData); $categoryData = $this->filterFields($categoryData); - if (isset($categoryData['image'])) { - unset($categoryData['image']); - $categoryData['image'][0]['name'] = $category->getData('image'); - $categoryData['image'][0]['url'] = $category->getImageUrl(); - } + $categoryData = $this->convertValues($category, $categoryData); + $this->loadedData[$category->getId()] = $categoryData; } return $this->loadedData; @@ -371,6 +369,29 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider return array_diff_key($categoryData, array_flip($this->ignoreFields)); } + /** + * @param \Magento\Catalog\Model\Category $category + * @param array $categoryData + * @return array + */ + protected function convertValues($category, $categoryData) + { + foreach ($category->getAttributes() as $attributeCode => $attribute) { + if (!isset($categoryData[$attributeCode])) { + continue; + } + + if ($attribute->getBackend() instanceof ImageBackendModel) { + unset($categoryData[$attributeCode]); + + $categoryData[$attributeCode][0]['name'] = $category->getData($attributeCode); + $categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode); + } + } + + return $categoryData; + } + /** * Category's fields default values * diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/Image/UploadTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/Image/UploadTest.php new file mode 100644 index 0000000000000000000000000000000000000000..40c40a17b8e52ec0cb0115db65bc11d1f0e9ae51 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/Image/UploadTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Category\Image; + +use \Magento\Catalog\Controller\Adminhtml\Category\Image\Upload as Model; +use \Magento\Framework\App\Request\Http as Request; +use \Magento\Catalog\Model\ImageUploader; +use \Magento\Framework\Controller\ResultFactory; +use \Magento\Framework\DataObject; +use \Magento\Backend\App\Action\Context; + +/** + * Class UploadTest + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class UploadTest extends \PHPUnit_Framework_TestCase +{ + protected $objectManager; + + protected function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + } + + public function uploadedImageNameProvider() + { + return [ + ['image1', 'image1'], + ['image2', 'image2'], + [null, 'image'], + ]; + } + + /** + * @param $name + * @param $savedName + * + * @dataProvider uploadedImageNameProvider + */ + public function testExecuteShouldSaveUploadedImageWithSpecifiedNameToTmpFolder($name, $savedName) + { + $request = $this->objectManager->getObject(Request::class); + + $uploader = $this->getMock(ImageUploader::class, ['saveFileToTmpDir'], [], '', false); + + $resultFactory = $this->getMock(ResultFactory::class, ['create'], [], '', false); + + $resultFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue(new DataObject())); + + $model = $this->objectManager->getObject(Model::class, [ + 'context' => $this->objectManager->getObject(Context::class, [ + 'request' => $request, + 'resultFactory' => $resultFactory + ]), + 'imageUploader' => $uploader + ]); + + $uploader->expects($this->once()) + ->method('saveFileToTmpDir') + ->with($savedName) + ->will($this->returnValue([])); + + $request->setParam('param_name', $name); + + $model->execute(); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/SaveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/SaveTest.php index 51d99f7219575c205b61de6e5d93727633874f79..9ef502b9640cac5d1c17606244f61015e0c2bbd0 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/SaveTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/SaveTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Category; +use \Magento\Catalog\Controller\Adminhtml\Category\Save as Model; + /** * Class SaveTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -84,7 +86,6 @@ class SaveTest extends \PHPUnit_Framework_TestCase */ protected function setUp() { - $this->markTestSkipped('Due to MAGETWO-48956'); $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->contextMock = $this->getMock( @@ -201,6 +202,8 @@ class SaveTest extends \PHPUnit_Framework_TestCase */ public function testExecute($categoryId, $storeId, $parentId) { + $this->markTestSkipped('Due to MAGETWO-48956'); + $rootCategoryId = \Magento\Catalog\Model\Category::TREE_ROOT_ID; $products = [['any_product']]; $postData = [ @@ -577,4 +580,92 @@ class SaveTest extends \PHPUnit_Framework_TestCase ] ]; } + + public function attributeValueDataProvider() + { + return [ + [['attribute1' => null, 'attribute2' => 123]], + [['attribute2' => 123]] + ]; + } + + /** + * @dataProvider attributeValueDataProvider + * + * @param $data + */ + public function testImagePreprocessingShouldSetAttributesWithImageBackendToFalse($data) + { + $eavConfig = $this->getMock(\Magento\Eav\Model\Config::class, ['getEntityType'], [], '', false); + + $imageBackendModel = $this->objectManager->getObject( + \Magento\Catalog\Model\Category\Attribute\Backend\Image::class + ); + + $collection = new \Magento\Framework\DataObject(['attribute_collection' => [ + new \Magento\Framework\DataObject([ + 'attribute_code' => 'attribute1', + 'backend' => $imageBackendModel + ]), + new \Magento\Framework\DataObject([ + 'attribute_code' => 'attribute2', + 'backend' => new \Magento\Framework\DataObject() + ]) + ]]); + + $eavConfig->expects($this->once()) + ->method('getEntityType') + ->with(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE) + ->will($this->returnValue($collection)); + + $model = $this->objectManager->getObject(\Magento\Catalog\Controller\Adminhtml\Category\Save::class, [ + 'eavConfig' => $eavConfig + ]); + + $result = $model->imagePreprocessing($data); + + $this->assertEquals([ + 'attribute1' => false, + 'attribute2' => 123 + ], $result); + } + + public function testImagePreprocessingShouldNotSetValueToFalseWhenValueSet() + { + $eavConfig = $this->getMock(\Magento\Eav\Model\Config::class, ['getEntityType'], [], '', false); + + $imageBackendModel = $this->objectManager->getObject( + \Magento\Catalog\Model\Category\Attribute\Backend\Image::class + ); + + $collection = new \Magento\Framework\DataObject(['attribute_collection' => [ + new \Magento\Framework\DataObject([ + 'attribute_code' => 'attribute1', + 'backend' => $imageBackendModel + ]), + new \Magento\Framework\DataObject([ + 'attribute_code' => 'attribute2', + 'backend' => new \Magento\Framework\DataObject() + ]) + ]]); + + $eavConfig->expects($this->once()) + ->method('getEntityType') + ->with(\Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE) + ->will($this->returnValue($collection)); + + $model = $this->objectManager->getObject(Model::class, [ + 'eavConfig' => $eavConfig + ]); + + $result = $model->imagePreprocessing([ + 'attribute1' => 'somevalue', + 'attribute2' => null + ]); + + $this->assertEquals([ + 'attribute1' => 'somevalue', + 'attribute2' => null + ], $result); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2bd41e6bca343fc399a11e620cdead60cc47c2ee --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php @@ -0,0 +1,296 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\Category\Attribute\Backend; + +use \Magento\Catalog\Model\Category\Attribute\Backend\Image as Model; + +class ImageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + */ + protected $attribute; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + + /** + * @var \Magento\Catalog\Model\ImageUploader + */ + protected $imageUploader; + + /** + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + + protected function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->attribute = $this->getMockForAbstractClass( + \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class, + [], + 'TestAttribute', + false, + false, + true, + ['getName'] + ); + + $this->attribute->expects($this->once()) + ->method('getName') + ->will($this->returnValue('test_attribute')); + + $this->logger = $this->getMockForAbstractClass( + \Psr\Log\LoggerInterface::class, + [], + 'TestLogger', + false, + false, + true, + ['critical'] + ); + + $this->imageUploader = $this->getMock( + \Magento\Catalog\Model\ImageUploader::class, + ['moveFileFromTmp'], + [], + '', + false + ); + } + + public function deletionValueProvider() + { + return [ + [false], + [['delete' => true]] + ]; + } + + /** + * @dataProvider deletionValueProvider + * + * @param $value + */ + public function testBeforeSaveShouldSetAttributeValueToBlankWhenImageValueRequiresDeletion($value) + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => $value + ]); + + $model->beforeSave($object); + + $this->assertEquals('', $object->getTestAttribute()); + } + + public function invalidValueProvider() + { + $closure = function () { + return false; + }; + + return [ + [1234], + [true], + [new \stdClass()], + [$closure], + [['a' => 1, 'b' => 2]] + ]; + } + + /** + * @dataProvider invalidValueProvider + * + * @param $value + */ + public function testBeforeSaveShouldSetAttributeValueToBlankWhenImageValueInvalid($value) + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => $value + ]); + + $model->beforeSave($object); + + $this->assertEquals('', $object->getTestAttribute()); + } + + public function testBeforeSaveShouldSetAttributeValueToUploadedImageName() + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => [ + ['name' => 'test123.jpg'] + ] + ]); + + $model->beforeSave($object); + + $this->assertEquals('test123.jpg', $object->getTestAttribute()); + } + + public function testBeforeSaveShouldSetAttributeUploadInformationToTemporaryAttribute() + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => [ + ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.test.com/test123.jpg'] + ] + ]); + + $model->beforeSave($object); + + $this->assertEquals([ + ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.test.com/test123.jpg'] + ], $object->getData('_additional_data_test_attribute')); + } + + public function testBeforeSaveShouldNotModifyAttributeValueWhenStringValue() + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => 'test123.jpg' + ]); + + $model->beforeSave($object); + + $this->assertEquals('test123.jpg', $object->getTestAttribute()); + } + + public function testBeforeSaveShouldNotSetAdditionalDataWhenStringValue() + { + $model = $this->objectManager->getObject(Model::class); + $model->setAttribute($this->attribute); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => 'test123.jpg' + ]); + + $model->beforeSave($object); + + $this->assertNull($object->getData('_additional_data_test_attribute')); + } + + protected function setUpModelForAfterSave() + { + $objectManagerMock = $this->getMock( + \Magento\Framework\App\ObjectManager::class, + ['get'], + [], + '', + false + ); + + $imageUploaderMock = $this->imageUploader; + + $objectManagerMock->expects($this->any()) + ->method('get') + ->will($this->returnCallback(function ($class, $params = []) use ($imageUploaderMock) { + if ($class == \Magento\Catalog\CategoryImageUpload::class) { + return $imageUploaderMock; + } + + return $this->objectManager->get($class, $params); + })); + + $model = $this->objectManager->getObject(Model::class, [ + 'objectManager' => $objectManagerMock, + 'logger' => $this->logger + ]); + + return $model->setAttribute($this->attribute); + } + + public function attributeValidValueProvider() + { + return [ + [[['name' => 'test1234.jpg']]], + ['test1234.jpg'], + [''], + [false] + ]; + } + + /** + * @dataProvider attributeValidValueProvider + * + * @param $value + */ + public function testAfterSaveShouldUploadImageWhenAdditionalDataSet($value) + { + $model = $this->setUpModelForAfterSave(); + + $this->imageUploader->expects($this->once()) + ->method('moveFileFromTmp') + ->with($this->equalTo('test1234.jpg')); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => $value, + '_additional_data_test_attribute' => [ + ['name' => 'test1234.jpg'] + ] + ]); + + $model->afterSave($object); + } + + /** + * @dataProvider attributeValidValueProvider + * + * @param $value + */ + public function testAfterSaveShouldNotUploadImageWhenAdditionalDataNotSet($value) + { + $model = $this->setUpModelForAfterSave(); + + $this->imageUploader->expects($this->never()) + ->method('moveFileFromTmp'); + + $object = new \Magento\Framework\DataObject([ + 'test_attribute' => $value + ]); + + $model->afterSave($object); + } + + public function testAfterSaveShouldCreateCriticalLogEntryOnUploadExceptions() + { + $model = $this->setUpModelForAfterSave(); + + $exception = new \Exception(); + + $this->imageUploader->expects($this->any()) + ->method('moveFileFromTmp') + ->will($this->throwException($exception)); + + $this->logger->expects($this->once()) + ->method('critical') + ->with($this->equalTo($exception)); + + $object = new \Magento\Framework\DataObject([ + '_additional_data_test_attribute' => [ + ['name' => 'test1234.jpg'] + ] + ]); + + $model->afterSave($object); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php index 471037f1d3f450c1b2281e06f823222e7f7e28b6..66403d39648901fb1c7f63b735dc1639ca462f87 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php @@ -9,6 +9,7 @@ namespace Magento\Catalog\Test\Unit\Model; use Magento\Catalog\Model\Indexer; +use Magento\Catalog\Model\Category as Model; /** * @SuppressWarnings(PHPMD.TooManyFields) @@ -89,9 +90,16 @@ class CategoryTest extends \PHPUnit_Framework_TestCase */ protected $attributeValueFactory; + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + protected function setUp() { - $this->context = $this->getMock( + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->context = $this->getMock( \Magento\Framework\Model\Context::class, ['getEventDispatcher', 'getCacheManager'], [], @@ -108,21 +116,21 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->registry = $this->getMock(\Magento\Framework\Registry::class); $this->storeManager = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); - $this->categoryTreeResource = $this->getMock( - \Magento\Catalog\Model\ResourceModel\Category\Tree::class, - [], - [], - '', - false + $this->categoryTreeResource = $this->getMock( + \Magento\Catalog\Model\ResourceModel\Category\Tree::class, + [], + [], + '', + false ); - $this->categoryTreeFactory = $this->getMock( + $this->categoryTreeFactory = $this->getMock( \Magento\Catalog\Model\ResourceModel\Category\TreeFactory::class, ['create'], [], '', false); $this->categoryRepository = $this->getMock(\Magento\Catalog\Api\CategoryRepositoryInterface::class); - $this->storeCollectionFactory = $this->getMock( + $this->storeCollectionFactory = $this->getMock( \Magento\Store\Model\ResourceModel\Store\CollectionFactory::class, ['create'], [], @@ -130,7 +138,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase false ); $this->url = $this->getMock(\Magento\Framework\UrlInterface::class); - $this->productCollectionFactory = $this->getMock( + $this->productCollectionFactory = $this->getMock( \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class, ['create'], [], @@ -138,7 +146,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase false ); $this->catalogConfig = $this->getMock(\Magento\Catalog\Model\Config::class, [], [], '', false); - $this->filterManager = $this->getMock( + $this->filterManager = $this->getMock( \Magento\Framework\Filter\FilterManager::class, ['translitUrl'], [], @@ -148,7 +156,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->flatState = $this->getMock(\Magento\Catalog\Model\Indexer\Category\Flat\State::class, [], [], '', false); $this->flatIndexer = $this->getMock(\Magento\Framework\Indexer\IndexerInterface::class); $this->productIndexer = $this->getMock(\Magento\Framework\Indexer\IndexerInterface::class); - $this->categoryUrlPathGenerator = $this->getMock( + $this->categoryUrlPathGenerator = $this->getMock( \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator::class, [], [], @@ -156,19 +164,19 @@ class CategoryTest extends \PHPUnit_Framework_TestCase false ); $this->urlFinder = $this->getMock(\Magento\UrlRewrite\Model\UrlFinderInterface::class); - $this->resource = $this->getMock( + $this->resource = $this->getMock( \Magento\Catalog\Model\ResourceModel\Category::class, [], [], '', false ); - $this->indexerRegistry = $this->getMock( - \Magento\Framework\Indexer\IndexerRegistry::class, - ['get'], - [], - '', - false + $this->indexerRegistry = $this->getMock( + \Magento\Framework\Indexer\IndexerRegistry::class, + ['get'], + [], + '', + false ); $this->metadataServiceMock = $this->getMock(\Magento\Catalog\Api\CategoryAttributeRepositoryInterface::class); @@ -198,7 +206,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase public function testMoveWhenCannotFindParentCategory() { $this->markTestIncomplete('MAGETWO-31165'); - $parentCategory = $this->getMock( + $parentCategory = $this->getMock( \Magento\Catalog\Model\Category::class, ['getId', 'setStoreId', 'load'], [], @@ -223,7 +231,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase */ public function testMoveWhenCannotFindNewCategory() { - $parentCategory = $this->getMock( + $parentCategory = $this->getMock( \Magento\Catalog\Model\Category::class, ['getId', 'setStoreId', 'load'], [], @@ -250,7 +258,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase public function testMoveWhenParentCategoryIsSameAsChildCategory() { $this->markTestIncomplete('MAGETWO-31165'); - $parentCategory = $this->getMock( + $parentCategory = $this->getMock( \Magento\Catalog\Model\Category::class, ['getId', 'setStoreId', 'load'], [], @@ -277,7 +285,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase ->method('get') ->with('catalog_category_product') ->will($this->returnValue($indexer)); - $parentCategory = $this->getMock( + $parentCategory = $this->getMock( \Magento\Catalog\Model\Category::class, ['getId', 'setStoreId', 'load'], [], @@ -313,7 +321,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase protected function getCategoryModel() { - return (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( + return $this->objectManager->getObject( \Magento\Catalog\Model\Category::class, [ 'context' => $this->context, @@ -487,4 +495,68 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->category->getCustomAttribute($descriptionAttributeCode)->getValue() ); } + + public function imageAttributeNameAndUrlProvider() + { + return [ + ['testimage', 'http://www.test123.com/catalog/category/testimage'], + [false, false] + ]; + } + + /** + * @param $value + * @param $url + * + * @dataProvider imageAttributeNameAndUrlProvider + */ + public function testGetImageUrlShouldGenerateMediaUrlForSpecifiedAttributeValue($value, $url) + { + $storeManager = $this->getMock(\Magento\Store\Model\StoreManager::class, ['getStore'], [], '', false); + $store = $this->getMock(\Magento\Store\Model\Store::class, ['getBaseUrl'], [], '', false); + + $storeManager->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($store)); + + $store->expects($this->any()) + ->method('getBaseUrl') + ->with(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) + ->will($this->returnValue('http://www.test123.com/')); + + $model = $this->objectManager->getObject(Model::class, [ + 'storeManager' => $storeManager + ]); + + $model->setData('attribute1', $value); + + $result = $model->getImageUrl('attribute1'); + + $this->assertEquals($url, $result); + } + + public function testGetImageUrlShouldGenerateMediaUrlForImageAttributeValue() + { + $storeManager = $this->getMock(\Magento\Store\Model\StoreManager::class, ['getStore'], [], '', false); + $store = $this->getMock(\Magento\Store\Model\Store::class, ['getBaseUrl'], [], '', false); + + $storeManager->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($store)); + + $store->expects($this->any()) + ->method('getBaseUrl') + ->with(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) + ->will($this->returnValue('http://www.test123.com/')); + + $model = $this->objectManager->getObject(Model::class, [ + 'storeManager' => $storeManager + ]); + + $model->setData('image', 'myimage'); + + $result = $model->getImageUrl(); + + $this->assertEquals('http://www.test123.com/catalog/category/myimage', $result); + } } diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index 1805dcd2f004ec91e5d3d1a96d2b0086e4b69e8c..5d06886fe91bd613134845706ab0ede28b277829 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -294,7 +294,7 @@ define([ /** * Handler which is invoked prior to the start of a file upload. * - * @param {Event} e - Event obejct. + * @param {Event} e - Event object. * @param {Object} data - File data that will be uploaded. */ onBeforeFileUpload: function (e, data) { @@ -302,7 +302,13 @@ define([ allowed = this.isFileAllowed(file); if (allowed.passed) { - $(e.target).fileupload('process', data).done(function () { + var $target = $(e.target); + + $target.on('fileuploadsend', function(event, postData) { + postData.data.set('param_name', this.paramName); + }.bind(data)); + + $target.fileupload('process', data).done(function () { data.submit(); }); } else {