diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 15ab59aaab2b3b5e2b694f685e7d7523fcb5c565..72810dc82611f66c38e19f027215af9cd063721f 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -802,7 +802,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity } } } catch (\Exception $e) { - $this->_logger->logException($e); + $this->_logger->critical($e); } return $exportData; } diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php index e556661f45b1a802fd4f9024cbcbbd4889653cd0..671aa6b136ab40b63ad67c9f7229dcdb7a8ae1f9 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php @@ -180,10 +180,6 @@ class Configurable extends \Magento\Framework\Model\Resource\Db\AbstractDb implode( ' AND ', [ - $this->_getReadAdapter()->quoteInto( - 'entity_value.entity_type_id = ?', - $product->getEntityTypeId() - ), 'entity_value.attribute_id = super_attribute.attribute_id', 'entity_value.store_id = 0', 'entity_value.entity_id = product_link.product_id' diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index f2885610281947d30f55abdccb526e6a270c6ac4..5fa2c3aa052638f3841cefcc5ddfe6bf1ef4358a 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -442,7 +442,6 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel $this->setStatusChanged(true); try { - $this->save(); if ($isConfirmNeed === true && $isOwnSubscribes === false ) { @@ -450,6 +449,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel } else { $this->sendConfirmationSuccessEmail(); } + $this->save(); return $this->getStatus(); } catch (\Exception $e) { throw new \Exception($e->getMessage()); diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bd8380299a52ee06f8d95a9ddea229ae2649160e --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php @@ -0,0 +1,164 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Newsletter\Test\Unit\Model; + +class SubscriberTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Newsletter\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + */ + protected $newsletterData; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $scopeConfig; + + /** + * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + protected $transportBuilder; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $storeManager; + + /** + * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject + */ + protected $customerSession; + + /** + * @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $customerRepository; + + /** + * @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $customerAccountManagement; + + /** + * @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $inlineTranslation; + + /** + * @var \Magento\Newsletter\Model\Resource\Subscriber|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resource; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + + /** + * @var \Magento\Newsletter\Model\Subscriber + */ + protected $subscriber; + + public function setUp() + { + $this->newsletterData = $this->getMock('Magento\Newsletter\Helper\Data', [], [], '', false); + $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $this->transportBuilder = $this->getMock( + 'Magento\Framework\Mail\Template\TransportBuilder', + [ + 'setTemplateIdentifier', + 'setTemplateOptions', + 'setTemplateVars', + 'setFrom', + 'addTo', + 'getTransport' + ], + [], + '', + false + ); + $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface'); + $this->customerSession = $this->getMock( + 'Magento\Customer\Model\Session', + [ + 'isLoggedIn', + 'getCustomerDataObject', + 'getCustomerId' + ], + [], + '', + false + ); + $this->customerRepository = $this->getMock('Magento\Customer\Api\CustomerRepositoryInterface'); + $this->customerAccountManagement = $this->getMock('Magento\Customer\Api\AccountManagementInterface'); + $this->inlineTranslation = $this->getMock('Magento\Framework\Translate\Inline\StateInterface'); + $this->resource = $this->getMock( + 'Magento\Newsletter\Model\Resource\Subscriber', + [ + 'loadByEmail', + 'getIdFieldName', + 'save' + ], + [], + '', + false + ); + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->subscriber = $this->objectManager->getObject( + 'Magento\Newsletter\Model\Subscriber', + [ + 'newsletterData' => $this->newsletterData, + 'scopeConfig' => $this->scopeConfig, + 'transportBuilder' => $this->transportBuilder, + 'storeManager' => $this->storeManager, + 'customerSession' => $this->customerSession, + 'customerRepository' => $this->customerRepository, + 'customerAccountManagement' => $this->customerAccountManagement, + 'inlineTranslation' => $this->inlineTranslation, + 'resource' => $this->resource + ] + ); + } + + public function testSubscribe() + { + $email = 'subscriber_email@magento.com'; + $this->resource->expects($this->any())->method('loadByEmail')->willReturn( + [ + 'subscriber_status' => 3, + 'subscriber_email' => $email, + 'name' => 'subscriber_name' + ] + ); + $this->resource->expects($this->any())->method('getIdFieldName')->willReturn('id_field'); + $this->scopeConfig->expects($this->any())->method('getValue')->willReturn(true); + $this->customerSession->expects($this->any())->method('isLoggedIn')->willReturn(true); + $customerDataModel = $this->getMock('\Magento\Customer\Api\Data\CustomerInterface'); + $this->customerSession->expects($this->any())->method('getCustomerDataObject')->willReturn($customerDataModel); + $this->customerSession->expects($this->any())->method('getCustomerId')->willReturn(1); + $customerDataModel->expects($this->any())->method('getEmail')->willReturn($email); + $this->customerRepository->expects($this->any())->method('getById')->willReturn($customerDataModel); + $customerDataModel->expects($this->any())->method('getStoreId')->willReturn(1); + $customerDataModel->expects($this->any())->method('getId')->willReturn(1); + $this->transportBuilder->expects($this->any())->method('setTemplateIdentifier')->willReturnSelf(); + $this->transportBuilder->expects($this->any())->method('setTemplateOptions')->willReturnSelf(); + $this->transportBuilder->expects($this->any())->method('setTemplateVars')->willReturnSelf(); + $this->transportBuilder->expects($this->any())->method('setFrom')->willReturnSelf(); + $this->transportBuilder->expects($this->any())->method('addTo')->willReturnSelf(); + $storeModel = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false); + $this->scopeConfig->expects($this->any())->method('getValue')->willReturn('owner_email@magento.com'); + $this->storeManager->expects($this->any())->method('getStore')->willReturn($storeModel); + $storeModel->expects($this->any())->method('getId')->willReturn(1); + $transport = $this->getMock('\Magento\Framework\Mail\TransportInterface'); + $this->transportBuilder->expects($this->any())->method('getTransport')->willReturn($transport); + $transport->expects($this->any())->method('sendMessage')->willReturnSelf(); + $inlineTranslation = $this->getMock('Magento\Framework\Translate\Inline\StateInterface'); + $inlineTranslation->expects($this->any())->method('resume')->willReturnSelf(); + $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); + $this->assertEquals(1, $this->subscriber->subscribe($email)); + } +} diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js index 251c057d689f12e75e85991ed46d8b0e2faee673..0cc7098574c9d120f5235644bdf74ded7d9c82b2 100644 --- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js @@ -5,6 +5,9 @@ var config = { "shim": { + "extjs/ext-tree": [ + "prototype" + ], "extjs/ext-tree-checkbox": [ "extjs/ext-tree", "extjs/defaults" diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php index def5584983e613573b91eeff95d766599b82655a..a83bb8be1c9feec57cb2e722d69021549a786615 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php @@ -125,4 +125,50 @@ class ProductTest extends \PHPUnit_Framework_TestCase ); } } + + /** + * Verifies if exception processing works properly + * + * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php + */ + public function testExceptionInGetExportData() + { + $exception = new \Exception('Error'); + + $rowCustomizerMock = $this->getMockBuilder('Magento\CatalogImportExport\Model\Export\RowCustomizerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $loggerMock = $this->getMockBuilder('\Psr\Log\LoggerInterface')->getMock(); + + $directoryMock = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false); + $directoryMock->expects($this->any())->method('getParentDirectory')->will($this->returnValue('some#path')); + $directoryMock->expects($this->any())->method('isWritable')->will($this->returnValue(true)); + + $filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); + $filesystemMock->expects($this->once())->method('getDirectoryWrite')->will($this->returnValue($directoryMock)); + + $exportAdapter = new \Magento\ImportExport\Model\Export\Adapter\Csv($filesystemMock); + + $rowCustomizerMock->expects($this->once())->method('prepareData')->willThrowException($exception); + $loggerMock->expects($this->once())->method('critical')->with($exception); + + $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + '\Magento\Catalog\Model\Resource\Product\Collection' + ); + + /** @var \Magento\CatalogImportExport\Model\Export\Product $model */ + $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\CatalogImportExport\Model\Export\Product', + [ + 'rowCustomizer' => $rowCustomizerMock, + 'logger' => $loggerMock, + 'collection' => $collection + ] + ); + + + $data = $model->setWriter($exportAdapter)->export(); + $this->assertEmpty($data); + } } diff --git a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml index 911f2482ebcec61f1d6bf914463511ffd1252359..0a0b04ba6836b74eb5d7584a9290136e540f8d8b 100644 --- a/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml +++ b/dev/tests/integration/testsuite/Magento/ToolkitFramework/_files/small.xml @@ -29,6 +29,8 @@ <!-- The price rule condition: minimum products amount in shopping cart for price rule to be applied --> <customers>20</customers> <!-- Number of customers to generate --> + <orders>80</orders> + <!-- Orders count --> <configs> <!-- Config variables and values for change --> <config> <path>admin/security/use_form_key</path> @@ -79,5 +81,39 @@ <value>8080</value> </config> </configs> + <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) --> + <indexer> + <id>catalog_category_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_category</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_price</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_attribute</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>cataloginventory_stock</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_rule</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogsearch_fulltext</id> + <set_scheduled>false</set_scheduled> + </indexer> + </indexers> </profile> -</config> \ No newline at end of file +</config> diff --git a/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php b/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php new file mode 100644 index 0000000000000000000000000000000000000000..8b072e2b68995399e051ab77cf868efb15638630 --- /dev/null +++ b/dev/tools/performance-toolkit/fixtures/indexers_states_apply.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** + * Class IndexersStatesApplyFixture + */ +class IndexersStatesApplyFixture extends \Magento\ToolkitFramework\Fixture +{ + /** + * @var int + */ + protected $priority = 170; + + /** + * {@inheritdoc} + */ + public function execute() + { + $indexers = \Magento\ToolkitFramework\Config::getInstance()->getValue('indexers', []); + if (!isset($indexers["indexer"]) || empty($indexers["indexer"])) { + return; + } + $this->application->resetObjectManager(); + foreach ($indexers["indexer"] as $indexer) { + $this->application->indexersStates[$indexer['id']] = ($indexer['set_scheduled'] == "true"); + } + $this->application->getObjectManager()->get('Magento\Framework\App\CacheInterface') + ->clean([\Magento\Framework\App\Config::CACHE_TAG]); + } + + /** + * {@inheritdoc} + */ + public function getActionTitle() + { + return 'Indexers Mode Changes'; + } + + /** + * {@inheritdoc} + */ + public function introduceParamLabels() + { + return []; + } +} + +return new IndexersStatesApplyFixture($this); diff --git a/dev/tools/performance-toolkit/framework/Magento/ToolkitFramework/Application.php b/dev/tools/performance-toolkit/framework/Magento/ToolkitFramework/Application.php index 083ac9fefbc6f619d4e0f2fecc1c007e23ae1cb5..d1df2a830d5d1b7a1df8785c278e3147ffe8d28a 100644 --- a/dev/tools/performance-toolkit/framework/Magento/ToolkitFramework/Application.php +++ b/dev/tools/performance-toolkit/framework/Magento/ToolkitFramework/Application.php @@ -69,6 +69,13 @@ class Application */ protected $_initArguments; + /** + * Indexers states values + * + * @var array + */ + public $indexersStates; + /** * @param string $applicationBaseDir * @param \Magento\Framework\Shell $shell diff --git a/dev/tools/performance-toolkit/generate.php b/dev/tools/performance-toolkit/generate.php index 861abee07ef81a10ceee9e80fc2aa9ef91ccb20d..3eae0197757f726c3e509d244dcf0c9ea88aab66 100644 --- a/dev/tools/performance-toolkit/generate.php +++ b/dev/tools/performance-toolkit/generate.php @@ -11,7 +11,8 @@ try { $shell = new Zend_Console_Getopt( [ - 'profile-s' => 'Profile configuration file', + 'profile=s' => 'Profile configuration file', + 'skip-reindex-i' => 'Skip reindex (Default - 0)', ] ); @@ -46,10 +47,10 @@ try { $indexerListIds = $config->getIndexers(); /** @var $indexerRegistry \Magento\Indexer\Model\IndexerRegistry */ $indexerRegistry = $application->getObjectManager()->create('Magento\Indexer\Model\IndexerRegistry'); - $indexersState = []; + $application->indexerStates = []; foreach ($indexerListIds as $key => $indexerId) { $indexer = $indexerRegistry->get($indexerId['indexer_id']); - $indexersState[$indexerId['indexer_id']] = $indexer->isScheduled(); + $application->indexersStates[$indexerId['indexer_id']] = $indexer->isScheduled(); $indexer->setScheduled(true); } @@ -65,10 +66,12 @@ try { foreach ($indexerListIds as $indexerId) { /** @var $indexer \Magento\Indexer\Model\Indexer */ $indexer = $indexerRegistry->get($indexerId['indexer_id']); - $indexer->setScheduled($indexersState[$indexerId['indexer_id']]); + $indexer->setScheduled($application->indexersStates[$indexerId['indexer_id']]); } - $application->reindex(); + if (!\Magento\ToolkitFramework\Helper\Cli::getOption('skip-reindex')) { + $application->reindex(); + } $totalEndTime = microtime(true); $totalResultTime = $totalEndTime - $totalStartTime; diff --git a/dev/tools/performance-toolkit/profiles/ce/extra_large.xml b/dev/tools/performance-toolkit/profiles/ce/extra_large.xml index 758fbef97f8730233c826ba009a5e24424b663fa..9d5767fbfba33f62963bed898213dc28ae30d95c 100644 --- a/dev/tools/performance-toolkit/profiles/ce/extra_large.xml +++ b/dev/tools/performance-toolkit/profiles/ce/extra_large.xml @@ -34,5 +34,39 @@ <value>1</value> </config> </configs> + <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) --> + <indexer> + <id>catalog_category_product</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_category</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_price</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_attribute</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>cataloginventory_stock</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_rule</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_product</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogsearch_fulltext</id> + <set_scheduled>true</set_scheduled> + </indexer> + </indexers> </profile> </config> diff --git a/dev/tools/performance-toolkit/profiles/ce/large.xml b/dev/tools/performance-toolkit/profiles/ce/large.xml index f89fa10faddc16f5e05f7be400b71f9ff94a8f1d..bdbce2f2b8b7ca464606e3b5b351cc658f5ce624 100644 --- a/dev/tools/performance-toolkit/profiles/ce/large.xml +++ b/dev/tools/performance-toolkit/profiles/ce/large.xml @@ -34,5 +34,39 @@ <value>1</value> </config> </configs> + <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) --> + <indexer> + <id>catalog_category_product</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_category</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_price</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_attribute</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>cataloginventory_stock</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_rule</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_product</id> + <set_scheduled>true</set_scheduled> + </indexer> + <indexer> + <id>catalogsearch_fulltext</id> + <set_scheduled>true</set_scheduled> + </indexer> + </indexers> </profile> </config> diff --git a/dev/tools/performance-toolkit/profiles/ce/medium.xml b/dev/tools/performance-toolkit/profiles/ce/medium.xml index fbcb4168bce8dbe2eb1b4f2bbe90a63c29bee4dd..8c91400d50bd697ab080985541bf35c760067642 100644 --- a/dev/tools/performance-toolkit/profiles/ce/medium.xml +++ b/dev/tools/performance-toolkit/profiles/ce/medium.xml @@ -34,5 +34,39 @@ <value>1</value> </config> </configs> + <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) --> + <indexer> + <id>catalog_category_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_category</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_price</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_attribute</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>cataloginventory_stock</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_rule</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogsearch_fulltext</id> + <set_scheduled>false</set_scheduled> + </indexer> + </indexers> </profile> </config> diff --git a/dev/tools/performance-toolkit/profiles/ce/small.xml b/dev/tools/performance-toolkit/profiles/ce/small.xml index 6507aa52f618843fac56a130461696f4342ac99f..79f2605bc775d7c3fdb0fe92106df966c6330c0c 100644 --- a/dev/tools/performance-toolkit/profiles/ce/small.xml +++ b/dev/tools/performance-toolkit/profiles/ce/small.xml @@ -34,5 +34,39 @@ <value>1</value> </config> </configs> + <indexers> <!-- Indexer mode value (true - Update by Schedule, false - Update on Save) --> + <indexer> + <id>catalog_category_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_category</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_price</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalog_product_attribute</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>cataloginventory_stock</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_rule</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogrule_product</id> + <set_scheduled>false</set_scheduled> + </indexer> + <indexer> + <id>catalogsearch_fulltext</id> + <set_scheduled>false</set_scheduled> + </indexer> + </indexers> </profile> </config>