diff --git a/.htaccess b/.htaccess index 61a6e70d03e7fa02725f65564b63b4b91e93a249..f3dbe217081acf1a326db6567cc15e4c3fc3bc7f 100644 --- a/.htaccess +++ b/.htaccess @@ -32,34 +32,6 @@ DirectoryIndex index.php -<IfModule mod_php5.c> - -############################################ -## adjust memory limit - - php_value memory_limit 768M - php_value max_execution_time 18000 - -############################################ -## disable automatic session start -## before autoload was initialized - - php_flag session.auto_start off - -############################################ -## enable resulting html compression - - #php_flag zlib.output_compression on - -########################################### -## disable user agent verification to not break multiple image upload - - php_flag suhosin.session.cryptua off - -</IfModule> - -<IfModule mod_php7.c> - ############################################ ## adjust memory limit @@ -82,8 +54,6 @@ php_flag suhosin.session.cryptua off -</IfModule> - <IfModule mod_security.c> ########################################### ## disable POST processing to not break multiple image upload diff --git a/.htaccess.sample b/.htaccess.sample index 61a6e70d03e7fa02725f65564b63b4b91e93a249..f3dbe217081acf1a326db6567cc15e4c3fc3bc7f 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -32,34 +32,6 @@ DirectoryIndex index.php -<IfModule mod_php5.c> - -############################################ -## adjust memory limit - - php_value memory_limit 768M - php_value max_execution_time 18000 - -############################################ -## disable automatic session start -## before autoload was initialized - - php_flag session.auto_start off - -############################################ -## enable resulting html compression - - #php_flag zlib.output_compression on - -########################################### -## disable user agent verification to not break multiple image upload - - php_flag suhosin.session.cryptua off - -</IfModule> - -<IfModule mod_php7.c> - ############################################ ## adjust memory limit @@ -82,8 +54,6 @@ php_flag suhosin.session.cryptua off -</IfModule> - <IfModule mod_security.c> ########################################### ## disable POST processing to not break multiple image upload diff --git a/app/code/Magento/Backup/Cron/SystemBackup.php b/app/code/Magento/Backup/Cron/SystemBackup.php index 384f731f6afed46b1b1bb6ed7dc90ddaecc5acaa..a6474cd84131bb4465ecf5b932e27d6212edb4e4 100644 --- a/app/code/Magento/Backup/Cron/SystemBackup.php +++ b/app/code/Magento/Backup/Cron/SystemBackup.php @@ -97,6 +97,7 @@ class SystemBackup * Create Backup * * @return $this + * @throws \Exception */ public function execute() { @@ -138,8 +139,7 @@ class SystemBackup } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); $this->_errors[] = $e->getTrace(); - $this->_logger->info($e->getMessage()); - $this->_logger->critical($e); + throw $e; } if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) { diff --git a/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php b/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php new file mode 100644 index 0000000000000000000000000000000000000000..dafa061d401b33d0f493b612727319de02b239c9 --- /dev/null +++ b/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Backup\Test\Unit\Cron; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class SystemBackupTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + + /** + * @var \Magento\Backup\Cron\SystemBackup + */ + private $systemBackup; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + + /** + * @var \Magento\Backup\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + */ + private $backupDataMock; + + /** + * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject + */ + private $registryMock; + + /** + * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + + /** + * Filesystem facade + * + * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject + */ + private $filesystemMock; + + /** + * @var \Magento\Framework\Backup\Factory|\PHPUnit_Framework_MockObject_MockObject + */ + private $backupFactoryMock; + + /** + * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject + */ + private $maintenanceModeMock; + + /** + * @var \Magento\Framework\Backup\Db|\PHPUnit_Framework_MockObject_MockObject + */ + private $backupDbMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + protected function setUp() + { + $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->getMock(); + $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->getMock(); + $this->backupDataMock = $this->getMockBuilder(\Magento\Backup\Helper\Data::class) + ->disableOriginalConstructor() + ->getMock(); + $this->registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) + ->disableOriginalConstructor() + ->getMock(); + $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) + ->getMock(); + $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) + ->disableOriginalConstructor() + ->getMock(); + $this->backupFactoryMock = $this->getMockBuilder(\Magento\Framework\Backup\Factory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->maintenanceModeMock = $this->getMockBuilder(\Magento\Framework\App\MaintenanceMode::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->backupDbMock = $this->getMockBuilder(\Magento\Framework\Backup\Db::class) + ->disableOriginalConstructor() + ->getMock(); + $this->backupDbMock->expects($this->any())->method('setBackupExtension')->willReturnSelf(); + $this->backupDbMock->expects($this->any())->method('setTime')->willReturnSelf(); + $this->backupDbMock->expects($this->any())->method('setBackupsDir')->willReturnSelf(); + + $this->objectManager = new ObjectManager($this); + $this->systemBackup = $this->objectManager->getObject( + \Magento\Backup\Cron\SystemBackup::class, + [ + 'backupData' => $this->backupDataMock, + 'coreRegistry' => $this->registryMock, + 'logger' => $this->loggerMock, + 'scopeConfig' => $this->scopeConfigMock, + 'filesystem' => $this->filesystemMock, + 'backupFactory' => $this->backupFactoryMock, + 'maintenanceMode' => $this->maintenanceModeMock, + ] + ); + } + + /** + * @expectedException \Exception + */ + public function testExecuteThrowsException() + { + $type = 'db'; + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(true); + + $this->scopeConfigMock->expects($this->once())->method('getValue') + ->with('system/backup/type', 'store') + ->willReturn($type); + + $this->backupFactoryMock->expects($this->once())->method('create')->willReturn($this->backupDbMock); + + $this->backupDbMock->expects($this->once())->method('create')->willThrowException(new \Exception); + + $this->backupDataMock->expects($this->never())->method('getCreateSuccessMessageByType')->with($type); + $this->loggerMock->expects($this->never())->method('info'); + + $this->systemBackup->execute(); + } +} diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index f2a2cb4ab7cb55b9451e220598f35ef2015b2090..b0ac406914166a926e8e6cf99b3c37aaf3dec75a 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -303,6 +303,7 @@ class BundlePanel extends AbstractModifier 'data' => [ 'config' => [ 'componentType' => 'fieldset', + 'collapsible' => true, 'label' => '', 'opened' => true, ], diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 8dda2e845dfaf8283c7c5d27ba02410b61eeb7e0..20a56a92acee3c1cd05207af8c0dd79cceba1243 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -386,6 +386,7 @@ class CustomOptions extends AbstractModifier 'data' => [ 'config' => [ 'componentType' => Fieldset::NAME, + 'collapsible' => true, 'label' => null, 'sortOrder' => 10, 'opened' => true, diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index edd6324d3de95cdf3a566ef184e75c67788aae13..f45115181fe4c628c88d3b5a26129629c21415b5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -8,7 +8,7 @@ <!-- ko text: currentBillingAddress().prefix --><!-- /ko --> <!-- ko text: currentBillingAddress().firstname --><!-- /ko --> <!-- ko text: currentBillingAddress().lastname --><!-- /ko --> <!-- ko text: currentBillingAddress().suffix --><!-- /ko --><br/> <!-- ko text: currentBillingAddress().street --><!-- /ko --><br/> - <!-- ko text: currentBillingAddress().city --><!-- /ko -->, <!-- ko text: currentBillingAddress().region --><!-- /ko --> <!-- ko text: currentBillingAddress().postcode --><!-- /ko --><br/> + <!-- ko text: currentBillingAddress().city --><!-- /ko -->, <span data-bind="html: currentBillingAddress().region"></span> <!-- ko text: currentBillingAddress().postcode --><!-- /ko --><br/> <!-- ko text: getCountryName(currentBillingAddress().countryId) --><!-- /ko --><br/> <!-- ko if: (currentBillingAddress().telephone) --> <a data-bind="text: currentBillingAddress().telephone, attr: {'href': 'tel:' + currentBillingAddress().telephone}"></a> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index b71cc710d65f888c413cd0e3be21ed19a9cbcd78..eeecbf346636613366db1f9d3fa33c4c7835b681 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -8,7 +8,7 @@ <!-- ko text: address().prefix --><!-- /ko --> <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().lastname --><!-- /ko --> <!-- ko text: address().suffix --><!-- /ko --><br/> <!-- ko text: address().street --><!-- /ko --><br/> - <!-- ko text: address().city --><!-- /ko -->, <!-- ko text: address().region --><!-- /ko --> <!-- ko text: address().postcode --><!-- /ko --><br/> + <!-- ko text: address().city --><!-- /ko -->, <span data-bind="html: address().region"></span> <!-- ko text: address().postcode --><!-- /ko --><br/> <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/> <!-- ko if: (address().telephone) --> <a data-bind="text: address().telephone, attr: {'href': 'tel:' + address().telephone}"></a> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 9d93c365ed382f003c48203ce6652e23c47e99ab..f02eef5ded99ab86bb3a445f7de3355f810e94e8 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -8,7 +8,7 @@ <!-- ko text: address().prefix --><!-- /ko --> <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().lastname --><!-- /ko --> <!-- ko text: address().suffix --><!-- /ko --><br/> <!-- ko text: address().street --><!-- /ko --><br/> - <!-- ko text: address().city --><!-- /ko -->, <!-- ko text: address().region --><!-- /ko --> <!-- ko text: address().postcode --><!-- /ko --><br/> + <!-- ko text: address().city --><!-- /ko -->, <span data-bind="html: address().region"></span> <!-- ko text: address().postcode --><!-- /ko --><br/> <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/> <!-- ko if: (address().telephone) --> <a data-bind="text: address().telephone, attr: {'href': 'tel:' + address().telephone}"></a> diff --git a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php index 27460006737c921fe97956be31ac907be8d420db..f7223a8f63667b1992cd73b19a108763719c12a8 100644 --- a/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php +++ b/app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php @@ -9,6 +9,7 @@ */ namespace Magento\Cron\Observer; +use Magento\Framework\App\State; use Magento\Framework\Console\CLI; use Magento\Framework\Event\ObserverInterface; use \Magento\Cron\Model\Schedule; @@ -105,16 +106,28 @@ class ProcessCronQueueObserver implements ObserverInterface */ protected $phpExecutableFinder; + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + /** + * @var \Magento\Framework\App\State + */ + private $state; + /** * @param \Magento\Framework\ObjectManagerInterface $objectManager - * @param ScheduleFactory $scheduleFactory + * @param \Magento\Cron\Model\ScheduleFactory $scheduleFactory * @param \Magento\Framework\App\CacheInterface $cache - * @param ConfigInterface $config + * @param \Magento\Cron\Model\ConfigInterface $config * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\App\Console\Request $request * @param \Magento\Framework\ShellInterface $shell * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone * @param \Magento\Framework\Process\PhpExecutableFinderFactory $phpExecutableFinderFactory + * @param \Psr\Log\LoggerInterface $logger + * @param \Magento\Framework\App\State $state */ public function __construct( \Magento\Framework\ObjectManagerInterface $objectManager, @@ -125,7 +138,9 @@ class ProcessCronQueueObserver implements ObserverInterface \Magento\Framework\App\Console\Request $request, \Magento\Framework\ShellInterface $shell, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone, - \Magento\Framework\Process\PhpExecutableFinderFactory $phpExecutableFinderFactory + \Magento\Framework\Process\PhpExecutableFinderFactory $phpExecutableFinderFactory, + \Psr\Log\LoggerInterface $logger, + \Magento\Framework\App\State $state ) { $this->_objectManager = $objectManager; $this->_scheduleFactory = $scheduleFactory; @@ -136,6 +151,8 @@ class ProcessCronQueueObserver implements ObserverInterface $this->_shell = $shell; $this->timezone = $timezone; $this->phpExecutableFinder = $phpExecutableFinderFactory->create(); + $this->logger = $logger; + $this->state = $state; } /** @@ -196,6 +213,21 @@ class ProcessCronQueueObserver implements ObserverInterface } } catch (\Exception $e) { $schedule->setMessages($e->getMessage()); + if ($schedule->getStatus() === Schedule::STATUS_ERROR) { + $this->logger->critical($e); + } + if ($schedule->getStatus() === Schedule::STATUS_MISSED + && $this->state->getMode() === State::MODE_DEVELOPER + ) { + $this->logger->info( + sprintf( + "%s Schedule Id: %s Job Code: %s", + $schedule->getMessages(), + $schedule->getScheduleId(), + $schedule->getJobCode() + ) + ); + } } $schedule->save(); } diff --git a/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php b/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php index 3da2ad3273043931dff17f3573d4d10a73b78863..d079c962cad3716d557feb593a10d246433bdd66 100644 --- a/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php +++ b/app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php @@ -7,6 +7,7 @@ namespace Magento\Cron\Test\Unit\Observer; use Magento\Cron\Model\Schedule; use Magento\Cron\Observer\ProcessCronQueueObserver as ProcessCronQueueObserver; +use Magento\Framework\App\State; /** * Class \Magento\Cron\Test\Unit\Model\ObserverTest @@ -72,6 +73,16 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase */ protected $observer; + /** + * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $loggerMock; + + /** + * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject + */ + protected $appStateMock; + /** * Prepare parameters */ @@ -107,6 +118,11 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase )->disableOriginalConstructor()->setMethods( ['execute'] )->getMock(); + $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class); + + $this->appStateMock = $this->getMockBuilder(\Magento\Framework\App\State::class) + ->disableOriginalConstructor() + ->getMock(); $this->observer = $this->getMock(\Magento\Framework\Event\Observer::class, [], [], '', false); @@ -133,7 +149,9 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase $this->_request, $this->_shell, $this->timezone, - $phpExecutableFinderFactory + $phpExecutableFinderFactory, + $this->loggerMock, + $this->appStateMock ); } @@ -234,46 +252,64 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase public function testDispatchExceptionTooLate() { $exceptionMessage = 'Too late for the schedule'; + $scheduleId = 42; + $jobCode = 'test_job1'; + $exception = $exceptionMessage . ' Schedule Id: ' . $scheduleId . ' Job Code: ' . $jobCode; $lastRun = time() + 10000000; - $this->_cache->expects($this->any())->method('load')->will($this->returnValue($lastRun)); - $this->_scopeConfig->expects($this->any())->method('getValue')->will($this->returnValue(0)); - $this->_request->expects($this->any())->method('getParam')->will($this->returnValue('test_group')); + $this->_cache->expects($this->any())->method('load')->willReturn($lastRun); + $this->_scopeConfig->expects($this->any())->method('getValue')->willReturn(0); + $this->_request->expects($this->any())->method('getParam')->willReturn('test_group'); $schedule = $this->getMockBuilder( \Magento\Cron\Model\Schedule::class )->setMethods( - ['getJobCode', 'tryLockJob', 'getScheduledAt', 'save', 'setStatus', 'setMessages', '__wakeup'] + [ + 'getJobCode', + 'tryLockJob', + 'getScheduledAt', + 'save', + 'setStatus', + 'setMessages', + '__wakeup', + 'getStatus', + 'getMessages', + 'getScheduleId', + ] )->disableOriginalConstructor()->getMock(); - $schedule->expects($this->any())->method('getJobCode')->will($this->returnValue('test_job1')); - $schedule->expects($this->once())->method('getScheduledAt')->will($this->returnValue('-1 day')); - $schedule->expects($this->once())->method('tryLockJob')->will($this->returnValue(true)); + $schedule->expects($this->any())->method('getJobCode')->willReturn($jobCode); + $schedule->expects($this->once())->method('getScheduledAt')->willReturn('-1 day'); + $schedule->expects($this->once())->method('tryLockJob')->willReturn(true); $schedule->expects( $this->once() )->method( 'setStatus' )->with( $this->equalTo(\Magento\Cron\Model\Schedule::STATUS_MISSED) - )->will( - $this->returnSelf() - ); + )->willReturnSelf(); $schedule->expects($this->once())->method('setMessages')->with($this->equalTo($exceptionMessage)); + $schedule->expects($this->any())->method('getStatus')->willReturn(Schedule::STATUS_MISSED); + $schedule->expects($this->once())->method('getMessages')->willReturn($exceptionMessage); + $schedule->expects($this->once())->method('getScheduleId')->willReturn($scheduleId); $schedule->expects($this->once())->method('save'); + $this->appStateMock->expects($this->once())->method('getMode')->willReturn(State::MODE_DEVELOPER); + + $this->loggerMock->expects($this->once())->method('info')->with($exception); + $this->_collection->addItem($schedule); $this->_config->expects( $this->once() )->method( 'getJobs' - )->will( - $this->returnValue(['test_group' => ['test_job1' => ['test_data']]]) + )->willReturn( + ['test_group' => ['test_job1' => ['test_data']]] ); - $scheduleMock = $this->getMockBuilder( - \Magento\Cron\Model\Schedule::class - )->disableOriginalConstructor()->getMock(); - $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); - $this->_scheduleFactory->expects($this->once())->method('create')->will($this->returnValue($scheduleMock)); + $scheduleMock = $this->getMockBuilder(\Magento\Cron\Model\Schedule::class) + ->disableOriginalConstructor()->getMock(); + $scheduleMock->expects($this->any())->method('getCollection')->willReturn($this->_collection); + $this->_scheduleFactory->expects($this->once())->method('create')->willReturn($scheduleMock); $this->_observer->execute($this->observer); } @@ -284,11 +320,12 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase public function testDispatchExceptionNoCallback() { $exceptionMessage = 'No callbacks found'; + $exception = new \Exception(__($exceptionMessage)); $schedule = $this->getMockBuilder( \Magento\Cron\Model\Schedule::class )->setMethods( - ['getJobCode', 'tryLockJob', 'getScheduledAt', 'save', 'setStatus', 'setMessages', '__wakeup'] + ['getJobCode', 'tryLockJob', 'getScheduledAt', 'save', 'setStatus', 'setMessages', '__wakeup', 'getStatus'] )->disableOriginalConstructor()->getMock(); $schedule->expects($this->any())->method('getJobCode')->will($this->returnValue('test_job1')); $schedule->expects($this->once())->method('getScheduledAt')->will($this->returnValue('-1 day')); @@ -303,10 +340,13 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase $this->returnSelf() ); $schedule->expects($this->once())->method('setMessages')->with($this->equalTo($exceptionMessage)); + $schedule->expects($this->any())->method('getStatus')->willReturn(Schedule::STATUS_ERROR); $schedule->expects($this->once())->method('save'); $this->_request->expects($this->any())->method('getParam')->will($this->returnValue('test_group')); $this->_collection->addItem($schedule); + $this->loggerMock->expects($this->once())->method('critical')->with($exception); + $jobConfig = ['test_group' => ['test_job1' => ['instance' => 'Some_Class']]]; $this->_config->expects($this->once())->method('getJobs')->will($this->returnValue($jobConfig)); @@ -332,11 +372,17 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase * @param mixed $cronJobObject * @param string $exceptionMessage * @param int $saveCalls + * @param \Exception $exception * * @dataProvider dispatchExceptionInCallbackDataProvider */ - public function testDispatchExceptionInCallback($cronJobType, $cronJobObject, $exceptionMessage, $saveCalls) - { + public function testDispatchExceptionInCallback( + $cronJobType, + $cronJobObject, + $exceptionMessage, + $saveCalls, + $exception + ) { $jobConfig = [ 'test_group' => [ 'test_job1' => ['instance' => $cronJobType, 'method' => 'execute'], @@ -344,9 +390,11 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase ]; $this->_request->expects($this->any())->method('getParam')->will($this->returnValue('test_group')); - $schedule = $this->getMockBuilder(\Magento\Cron\Model\Schedule::class) - ->setMethods(['getJobCode', 'tryLockJob', 'getScheduledAt', 'save', 'setStatus', 'setMessages', '__wakeup']) - ->disableOriginalConstructor()->getMock(); + $schedule = $this->getMockBuilder( + \Magento\Cron\Model\Schedule::class + )->setMethods( + ['getJobCode', 'tryLockJob', 'getScheduledAt', 'save', 'setStatus', 'setMessages', '__wakeup', 'getStatus'] + )->disableOriginalConstructor()->getMock(); $schedule->expects($this->any())->method('getJobCode')->will($this->returnValue('test_job1')); $schedule->expects($this->once())->method('getScheduledAt')->will($this->returnValue('-1 day')); $schedule->expects($this->once())->method('tryLockJob')->will($this->returnValue(true)); @@ -355,8 +403,11 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase ->with($this->equalTo(\Magento\Cron\Model\Schedule::STATUS_ERROR)) ->will($this->returnSelf()); $schedule->expects($this->once())->method('setMessages')->with($this->equalTo($exceptionMessage)); + $schedule->expects($this->any())->method('getStatus')->willReturn(Schedule::STATUS_ERROR); $schedule->expects($this->exactly($saveCalls))->method('save'); + $this->loggerMock->expects($this->once())->method('critical')->with($exception); + $this->_collection->addItem($schedule); $this->_config->expects($this->once())->method('getJobs')->will($this->returnValue($jobConfig)); @@ -389,13 +440,15 @@ class ProcessCronQueueObserverTest extends \PHPUnit_Framework_TestCase 'Not_Existed_Class', '', 'Invalid callback: Not_Existed_Class::execute can\'t be called', - 1 + 1, + new \Exception(__('Invalid callback: Not_Existed_Class::execute can\'t be called')) ], 'exception in execution' => [ 'CronJobException', new \Magento\Cron\Test\Unit\Model\CronJobException(), 'Test exception', - 2 + 2, + new \Exception(__('Test exception')) ], ]; } diff --git a/app/code/Magento/Deploy/Model/Deployer.php b/app/code/Magento/Deploy/Model/Deployer.php index 253360a4f92938e781a2339a88363bf79f8b114d..a7dd163c952d82251dac7de31c006753f41874f9 100644 --- a/app/code/Magento/Deploy/Model/Deployer.php +++ b/app/code/Magento/Deploy/Model/Deployer.php @@ -17,6 +17,7 @@ use Magento\Framework\Config\Theme; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Translate\Js\Config as JsTranslationConfig; use Symfony\Component\Console\Output\OutputInterface; +use Psr\Log\LoggerInterface; use Magento\Framework\View\Asset\Minification; use Magento\Framework\App\ObjectManager; @@ -81,6 +82,11 @@ class Deployer */ private $minification; + /** + * @var LoggerInterface + */ + private $logger; + /** * Constructor * @@ -166,7 +172,7 @@ class Deployer ); $fileManager->createRequireJsConfigAsset(); foreach ($appFiles as $info) { - list($fileArea, $fileTheme, , $module, $filePath) = $info; + list($fileArea, $fileTheme, , $module, $filePath, $fullPath) = $info; if (($fileArea == $area || $fileArea == 'base') && ($fileTheme == '' || $fileTheme == $themePath || in_array( @@ -174,9 +180,9 @@ class Deployer $this->findAncestors($area . Theme::THEME_PATH_SEPARATOR . $themePath) )) ) { - $compiledFile = $this->deployFile($filePath, $area, $themePath, $locale, $module); + $compiledFile = $this->deployFile($filePath, $area, $themePath, $locale, $module, $fullPath); if ($compiledFile !== '') { - $this->deployFile($compiledFile, $area, $themePath, $locale, $module); + $this->deployFile($compiledFile, $area, $themePath, $locale, $module, $fullPath); } } } @@ -321,6 +327,7 @@ class Deployer * @param string $themePath * @param string $locale * @param string $module + * @param string|null $fullPath * @return string * @throws \InvalidArgumentException * @throws LocalizedException @@ -328,7 +335,7 @@ class Deployer * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - private function deployFile($filePath, $area, $themePath, $locale, $module) + private function deployFile($filePath, $area, $themePath, $locale, $module, $fullPath = null) { $compiledFile = ''; $extension = pathinfo($filePath, PATHINFO_EXTENSION); @@ -368,7 +375,13 @@ class Deployer } $this->count++; } catch (ContentProcessorException $exception) { - throw $exception; + $pathInfo = $fullPath ?: $filePath; + $errorMessage = __('Compilation from source: ') . $pathInfo + . PHP_EOL . $exception->getMessage(); + $this->errorCount++; + $this->output->write(PHP_EOL . PHP_EOL . $errorMessage . PHP_EOL, true); + + $this->getLogger()->critical($errorMessage); } catch (\Exception $exception) { $this->output->write('.'); $this->verboseLog($exception->getTraceAsString()); @@ -409,4 +422,19 @@ class Deployer $this->output->writeln($message); } } + + /** + * Retrieves LoggerInterface instance + * + * @return LoggerInterface + * @deprecated + */ + private function getLogger() + { + if (!$this->logger) { + $this->logger = $this->objectManager->get(LoggerInterface::class); + } + + return $this->logger; + } } diff --git a/app/code/Magento/Directory/Model/Observer.php b/app/code/Magento/Directory/Model/Observer.php index 8cdb1d8d8d17bc14f614e02df02d0fdd8d68a31c..a7f0f6f84b3bb18e5695fecc169d7aa2df28c1ce 100644 --- a/app/code/Magento/Directory/Model/Observer.php +++ b/app/code/Magento/Directory/Model/Observer.php @@ -84,6 +84,7 @@ class Observer /** * @param mixed $schedule * @return void + * @throws \Exception * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function scheduledUpdateCurrencyRates($schedule) @@ -113,6 +114,7 @@ class Observer $errors = $importModel->getMessages(); } catch (\Exception $e) { $importWarnings[] = __('FATAL ERROR:') . ' ' . __('We can\'t initialize the import model.'); + throw $e; } } else { $importWarnings[] = __('FATAL ERROR:') . ' ' . __('Please specify the correct Import Service.'); diff --git a/app/code/Magento/Directory/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Directory/Test/Unit/Model/ObserverTest.php index a27ba87f885d54e5395cb2c0ba8b24fca5afcf2a..9f73947cbcd5c221bb43aafb4821e96c5b1e83e8 100644 --- a/app/code/Magento/Directory/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Directory/Test/Unit/Model/ObserverTest.php @@ -126,4 +126,28 @@ class ObserverTest extends \PHPUnit_Framework_TestCase $this->observer->scheduledUpdateCurrencyRates(null); } + + /** + * @expectedException \Exception + */ + public function testScheduledUpdateCurrencyRatesThrowsException() + { + $this->scopeConfig->expects($this->exactly(3)) + ->method('getValue') + ->willReturnMap( + [ + [Observer::IMPORT_ENABLE, ScopeInterface::SCOPE_STORE, null, 1], + [Observer::CRON_STRING_PATH, ScopeInterface::SCOPE_STORE, null, 'cron-path'], + [Observer::IMPORT_SERVICE, ScopeInterface::SCOPE_STORE, null, 'import-service'] + ] + ); + + $this->importFactory + ->expects($this->once()) + ->method('create') + ->with('import-service') + ->willThrowException(new \Exception()); + + $this->observer->scheduledUpdateCurrencyRates(null); + } } diff --git a/app/code/Magento/NewRelicReporting/Model/Cron/ReportNewRelicCron.php b/app/code/Magento/NewRelicReporting/Model/Cron/ReportNewRelicCron.php index 9565294c3c16fce9295b14a0229019df97832e84..cd980c9e3db231741e1691ee71470ae5e32d4d6c 100644 --- a/app/code/Magento/NewRelicReporting/Model/Cron/ReportNewRelicCron.php +++ b/app/code/Magento/NewRelicReporting/Model/Cron/ReportNewRelicCron.php @@ -41,11 +41,6 @@ class ReportNewRelicCron */ protected $deploymentsFactory; - /** - * @var \Psr\Log\LoggerInterface - */ - protected $logger; - /** * Parameters to be sent to Insights * @var array @@ -60,22 +55,19 @@ class ReportNewRelicCron * @param Counter $counter * @param CronEventFactory $cronEventFactory * @param DeploymentsFactory $deploymentsFactory - * @param \Psr\Log\LoggerInterface $logger */ public function __construct( Config $config, Collect $collect, Counter $counter, CronEventFactory $cronEventFactory, - DeploymentsFactory $deploymentsFactory, - \Psr\Log\LoggerInterface $logger + DeploymentsFactory $deploymentsFactory ) { $this->config = $config; $this->collect = $collect; $this->counter = $counter; $this->cronEventFactory = $cronEventFactory; $this->deploymentsFactory = $deploymentsFactory; - $this->logger = $logger; } /** @@ -155,6 +147,7 @@ class ReportNewRelicCron * Reports counts info to New Relic * * @return void + * @throws \Exception */ protected function reportCounts() { @@ -168,19 +161,9 @@ class ReportNewRelicCron Config::CUSTOMER_COUNT => $this->counter->getCustomerCount(), ]); if (!empty($this->customParameters)) { - try { - $this->cronEventFactory->create() - ->addData($this->customParameters) - ->sendRequest(); - } catch (\Exception $e) { - $this->logger->critical( - sprintf( - "New Relic Cron Event exception: %s\n%s", - $e->getMessage(), - $e->getTraceAsString() - ) - ); - } + $this->cronEventFactory->create() + ->addData($this->customParameters) + ->sendRequest(); } } diff --git a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Cron/ReportNewRelicCronTest.php b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Cron/ReportNewRelicCronTest.php index 7a49cd7345aafc2f23044359d4e258ff3f2eba41..d8574174ba956c5a46ba7d7af4b62773c0f91902 100644 --- a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Cron/ReportNewRelicCronTest.php +++ b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Cron/ReportNewRelicCronTest.php @@ -55,7 +55,7 @@ class ReportNewRelicCronTest extends \PHPUnit_Framework_TestCase /** * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $logger; + private $logger; /** * Setup @@ -101,8 +101,6 @@ class ReportNewRelicCronTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['setDeployment']) ->getMock(); - $this->logger = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) - ->getMock(); $this->cronEventFactory->expects($this->any()) ->method('create') @@ -110,6 +108,7 @@ class ReportNewRelicCronTest extends \PHPUnit_Framework_TestCase $this->deploymentsFactory->expects($this->any()) ->method('create') ->willReturn($this->deploymentsModel); + $this->logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface'); $this->model = new ReportNewRelicCron( $this->config, @@ -195,7 +194,7 @@ class ReportNewRelicCronTest extends \PHPUnit_Framework_TestCase /** * Test case when module is enabled and request is failed * - * @return void + * @expectedException \Exception */ public function testReportNewRelicCronRequestFailed() { @@ -237,17 +236,12 @@ class ReportNewRelicCronTest extends \PHPUnit_Framework_TestCase $this->cronEventModel->expects($this->once()) ->method('sendRequest'); - $this->cronEventModel->expects($this->once())->method('sendRequest')->willThrowException( - new \Exception() - ); - $this->logger->expects($this->once())->method('critical'); + $this->cronEventModel->expects($this->once())->method('sendRequest')->willThrowException(new \Exception()); + $this->logger->expects($this->never())->method('critical'); $this->deploymentsModel->expects($this->any()) ->method('setDeployment'); - $this->assertSame( - $this->model, - $this->model->report() - ); + $this->model->report(); } } diff --git a/app/code/Magento/NewRelicReporting/Test/Unit/Model/CronTest.php b/app/code/Magento/NewRelicReporting/Test/Unit/Model/CronTest.php index 7af4817423e0ace96b43176806b2e853ffc7e6f8..a32f7abca88179b29272b51f9f73217f0d84fa71 100644 --- a/app/code/Magento/NewRelicReporting/Test/Unit/Model/CronTest.php +++ b/app/code/Magento/NewRelicReporting/Test/Unit/Model/CronTest.php @@ -40,9 +40,7 @@ class CronTest extends \PHPUnit_Framework_TestCase protected function setUp() { $this->configMock = $this->getMockBuilder(\Magento\NewRelicReporting\Model\Config::class) - ->setMethods([ - 'isCronEnabled' - ]) + ->setMethods(['isCronEnabled']) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Newsletter/Model/Observer.php b/app/code/Magento/Newsletter/Model/Observer.php index a8e5318b5e501e0525beb3a7d9970ace87d61017..65e08f69c92dda01882655ead8100712f174b834 100644 --- a/app/code/Magento/Newsletter/Model/Observer.php +++ b/app/code/Magento/Newsletter/Model/Observer.php @@ -5,8 +5,6 @@ */ namespace Magento\Newsletter\Model; -use Magento\Cron\Model\Schedule; - /** * Newsletter module observer * @@ -36,7 +34,6 @@ class Observer * Scheduled send handler * * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function scheduledSend() { diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index d6746f48dcbe54b44a15723b9a144f9cf77447c7..06a278aef6d48692c856f56daf213e4bab162db8 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -9,7 +9,6 @@ "magento/module-backend": "100.2.*", "magento/module-cms": "101.1.*", "magento/module-email": "100.2.*", - "magento/module-cron": "100.2.*", "magento/module-eav": "100.2.*", "magento/module-require-js": "100.2.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/Payment/view/adminhtml/web/transparent.js b/app/code/Magento/Payment/view/adminhtml/web/transparent.js index cf60a0dcee97c249e1c31965831336415353d9b6..583945d39612e67ad99318dafca192a9355bd453 100644 --- a/app/code/Magento/Payment/view/adminhtml/web/transparent.js +++ b/app/code/Magento/Payment/view/adminhtml/web/transparent.js @@ -91,6 +91,9 @@ define([ } else { this._processErrors(response); } + }, + complete: function () { + $('body').trigger('processStop'); } }); }, diff --git a/app/code/Magento/Paypal/Cron/FetchReports.php b/app/code/Magento/Paypal/Cron/FetchReports.php index 4feae1b3251a54a906a838a683532372f3632e1a..c4d82a6d42809f5edec5305f31a7f6c8bb3c7702 100644 --- a/app/code/Magento/Paypal/Cron/FetchReports.php +++ b/app/code/Magento/Paypal/Cron/FetchReports.php @@ -7,11 +7,6 @@ namespace Magento\Paypal\Cron; class FetchReports { - /** - * @var \Psr\Log\LoggerInterface - */ - protected $_logger; - /** * @var \Magento\Paypal\Model\Report\SettlementFactory */ @@ -20,14 +15,11 @@ class FetchReports /** * Constructor * - * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Paypal\Model\Report\SettlementFactory $settlementFactory */ public function __construct( - \Psr\Log\LoggerInterface $logger, \Magento\Paypal\Model\Report\SettlementFactory $settlementFactory ) { - $this->_logger = $logger; $this->_settlementFactory = $settlementFactory; } @@ -35,23 +27,16 @@ class FetchReports * Goes to reports.paypal.com and fetches Settlement reports. * * @return void + * @throws \Exception */ public function execute() { - try { - /** @var \Magento\Paypal\Model\Report\Settlement $reports */ - $reports = $this->_settlementFactory->create(); - /* @var $reports \Magento\Paypal\Model\Report\Settlement */ - $credentials = $reports->getSftpCredentials(true); - foreach ($credentials as $config) { - try { - $reports->fetchAndSave(\Magento\Paypal\Model\Report\Settlement::createConnection($config)); - } catch (\Exception $e) { - $this->_logger->critical($e); - } - } - } catch (\Exception $e) { - $this->_logger->critical($e); + /** @var \Magento\Paypal\Model\Report\Settlement $reports */ + $reports = $this->_settlementFactory->create(); + /* @var $reports \Magento\Paypal\Model\Report\Settlement */ + $credentials = $reports->getSftpCredentials(true); + foreach ($credentials as $config) { + $reports->fetchAndSave(\Magento\Paypal\Model\Report\Settlement::createConnection($config)); } } } diff --git a/app/code/Magento/Paypal/Test/Unit/Cron/FetchReportsTest.php b/app/code/Magento/Paypal/Test/Unit/Cron/FetchReportsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d3d3910cc4dbb93c69683c43685b40d10734e250 --- /dev/null +++ b/app/code/Magento/Paypal/Test/Unit/Cron/FetchReportsTest.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Paypal\Test\Unit\Cron; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class FetchReportsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + + /** + * @var \Magento\Paypal\Cron\FetchReports + */ + private $fetchReports; + + /** + * @var \Magento\Paypal\Model\Report\SettlementFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $settlementFactoryMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + /** + * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $logger; + + protected function setUp() + { + $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->getMock(); + $this->settlementFactoryMock = $this->getMockBuilder(\Magento\Paypal\Model\Report\SettlementFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface'); + + $this->objectManager = new ObjectManager($this); + $this->fetchReports = $this->objectManager->getObject( + \Magento\Paypal\Cron\FetchReports::class, + [ + 'settlementFactory' => $this->settlementFactoryMock + ] + ); + } + + /** + * @expectedException \Exception + */ + public function testExecuteThrowsException() + { + $sftpCredentials = [ + 'hostname' => ['test_hostname'], + 'username' => ['test_username'], + 'password' => ['test_password'], + 'path' => ['test_path'] + ]; + $settlementMock = $this->getMockBuilder('Magento\Paypal\Model\Report\Settlement') + ->disableOriginalConstructor() + ->getMock(); + + $this->settlementFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($settlementMock); + + $settlementMock->expects($this->once())->method('getSftpCredentials')->with(true)->willReturn($sftpCredentials); + $settlementMock->expects($this->any())->method('fetchAndSave')->willThrowException(new \Exception); + $this->logger->expects($this->never())->method('critical'); + + $this->fetchReports->execute(); + } +} diff --git a/app/code/Magento/ProductAlert/Model/Observer.php b/app/code/Magento/ProductAlert/Model/Observer.php index 9a2b6fdc30e02a205622e4994ae76fd46861bbc0..1888c2acccf6dad0205f0d286972768b15263efa 100644 --- a/app/code/Magento/ProductAlert/Model/Observer.php +++ b/app/code/Magento/ProductAlert/Model/Observer.php @@ -157,6 +157,7 @@ class Observer * Retrieve website collection array * * @return array + * @throws \Exception */ protected function _getWebsites() { @@ -165,6 +166,7 @@ class Observer $this->_websites = $this->_storeManager->getWebsites(); } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); + throw $e; } } return $this->_websites; @@ -175,6 +177,7 @@ class Observer * * @param \Magento\ProductAlert\Model\Email $email * @return $this + * @throws \Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -183,7 +186,6 @@ class Observer $email->setType('price'); foreach ($this->_getWebsites() as $website) { /* @var $website \Magento\Store\Model\Website */ - if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) { continue; } @@ -201,7 +203,7 @@ class Observer )->setCustomerOrder(); } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); - return $this; + throw $e; } $previousCustomer = null; @@ -244,6 +246,7 @@ class Observer } } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); + throw $e; } } if ($previousCustomer) { @@ -251,6 +254,7 @@ class Observer $email->send(); } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); + throw $e; } } } @@ -262,6 +266,7 @@ class Observer * * @param \Magento\ProductAlert\Model\Email $email * @return $this + * @throws \Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -291,7 +296,7 @@ class Observer )->setCustomerOrder(); } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); - return $this; + throw $e; } $previousCustomer = null; @@ -331,6 +336,7 @@ class Observer } } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); + throw $e; } } @@ -339,6 +345,7 @@ class Observer $email->send(); } catch (\Exception $e) { $this->_errors[] = $e->getMessage(); + throw $e; } } } diff --git a/app/code/Magento/ProductAlert/Test/Unit/Model/ObserverTest.php b/app/code/Magento/ProductAlert/Test/Unit/Model/ObserverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b67568dc0d0d5d1c554355fb933d8e40668f7326 --- /dev/null +++ b/app/code/Magento/ProductAlert/Test/Unit/Model/ObserverTest.php @@ -0,0 +1,402 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ProductAlert\Test\Unit\Model; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class ObserverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + + /** + * @var \Magento\ProductAlert\Model\Observer + */ + private $observer; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + + /** + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionFactoryMock; + + /** + * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $transportBuilderMock; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $inlineTranslationMock; + + /** + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection|\PHPUnit_Framework_MockObject_MockObject + */ + private $sitemapCollectionMock; + + /** + * @var \Magento\Sitemap\Model\Sitemap|\PHPUnit_Framework_MockObject_MockObject + */ + private $sitemapMock; + + /** + * @var \Magento\ProductAlert\Model\EmailFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $emailFactoryMock; + + /** + * @var \Magento\ProductAlert\Model\Email|\PHPUnit_Framework_MockObject_MockObject + */ + private $emailMock; + + /** + * @var \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $priceColFactoryMock; + + /** + * @var \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockColFactoryMock; + + /** + * @var \Magento\Store\Model\Website|\PHPUnit_Framework_MockObject_MockObject + */ + private $websiteMock; + + /** + * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $customerRepositoryMock; + + /** + * @var \Magento\Catalog\Api\ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productRepositoryMock; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $productMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + protected function setUp() + { + $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->getMock(); + $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->getMock(); + $this->collectionFactoryMock = $this->getMockBuilder( + \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory::class + )->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->transportBuilderMock = $this->getMockBuilder(\Magento\Framework\Mail\Template\TransportBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->getMock(); + $this->inlineTranslationMock = $this->getMockBuilder(\Magento\Framework\Translate\Inline\StateInterface::class) + ->getMock(); + $this->sitemapCollectionMock = $this->getMock( + \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection::class, + ['getIterator'], + [], + '', + false + ); + $this->sitemapMock = $this->getMock(\Magento\Sitemap\Model\Sitemap::class, ['generateXml'], [], '', false); + + $this->emailFactoryMock = $this->getMockBuilder( + \Magento\ProductAlert\Model\EmailFactory::class + )->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->emailMock = $this->getMockBuilder(\Magento\ProductAlert\Model\Email::class) + ->disableOriginalConstructor() + ->getMock(); + $this->priceColFactoryMock = $this->getMockBuilder( + \Magento\ProductAlert\Model\ResourceModel\Price\CollectionFactory::class + )->disableOriginalConstructor() + ->setMethods(['create', 'addWebsiteFilter', 'setCustomerOrder']) + ->getMock(); + $this->stockColFactoryMock = $this->getMockBuilder( + \Magento\ProductAlert\Model\ResourceModel\Stock\CollectionFactory::class + )->disableOriginalConstructor() + ->setMethods(['create', 'addWebsiteFilter', 'setCustomerOrder', 'addStatusFilter']) + ->getMock(); + + $this->websiteMock = $this->getMock( + '\Magento\Store\Model\Website', + ['getDefaultGroup', 'getDefaultStore'], + [], + '', + false + ); + $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + ->disableOriginalConstructor() + ->setMethods(['getDefaultStore', 'getId']) + ->getMock(); + $this->customerRepositoryMock = $this->getMockBuilder(\Magento\Customer\Api\CustomerRepositoryInterface::class) + ->getMock(); + $this->productRepositoryMock = $this->getMockBuilder(\Magento\Catalog\Api\ProductRepositoryInterface::class) + ->getMock(); + $this->productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->setMethods( + [ + 'setCustomerGroupId', + 'getFinalPrice', + 'isSalable', + ] + )->getMock(); + + $this->objectManager = new ObjectManager($this); + $this->observer = $this->objectManager->getObject( + \Magento\ProductAlert\Model\Observer::class, + [ + 'scopeConfig' => $this->scopeConfigMock, + 'collectionFactory' => $this->collectionFactoryMock, + 'storeManager' => $this->storeManagerMock, + 'transportBuilder' => $this->transportBuilderMock, + 'inlineTranslation' => $this->inlineTranslationMock, + 'emailFactory' => $this->emailFactoryMock, + 'priceColFactory' => $this->priceColFactoryMock, + 'stockColFactory' => $this->stockColFactoryMock, + 'customerRepository' => $this->customerRepositoryMock, + 'productRepository' => $this->productRepositoryMock + ] + ); + } + + /** + * @expectedException \Exception + */ + public function testGetWebsitesThrowsException() + { + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessPriceThrowsException() + { + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(true); + + $this->priceColFactoryMock->expects($this->once())->method('create')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessPriceCustomerRepositoryThrowsException() + { + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(true); + + $this->priceColFactoryMock->expects($this->once())->method('create')->willReturnSelf(); + $this->priceColFactoryMock->expects($this->once())->method('addWebsiteFilter')->willReturnSelf(); + $items = [ + new \Magento\Framework\DataObject([ + 'customer_id' => '42' + ]) + ]; + + $this->priceColFactoryMock->expects($this->once()) + ->method('setCustomerOrder') + ->willReturn(new \ArrayIterator($items)); + + $this->customerRepositoryMock->expects($this->once())->method('getById')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessPriceEmailThrowsException() + { + $id = 1; + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + $this->websiteMock->expects($this->once())->method('getDefaultStore')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getId')->willReturn(2); + + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(true); + + $this->priceColFactoryMock->expects($this->once())->method('create')->willReturnSelf(); + $this->priceColFactoryMock->expects($this->once())->method('addWebsiteFilter')->willReturnSelf(); + + $items = [ + new \Magento\Framework\DataObject([ + 'customer_id' => $id + ]) + ]; + $this->priceColFactoryMock->expects($this->once()) + ->method('setCustomerOrder') + ->willReturn(new \ArrayIterator($items)); + + $customer = new \Magento\Framework\DataObject(['group_id' => $id]); + $this->customerRepositoryMock->expects($this->once())->method('getById')->willReturn($customer); + + $this->productMock->expects($this->once())->method('setCustomerGroupId')->willReturnSelf(); + $this->productMock->expects($this->once())->method('getFinalPrice')->willReturn('655.99'); + $this->productRepositoryMock->expects($this->once())->method('getById')->willReturn($this->productMock); + + $this->emailMock->expects($this->once())->method('send')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessStockThrowsException() + { + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + + $this->scopeConfigMock->expects($this->at(0))->method('getValue')->willReturn(false); + $this->scopeConfigMock->expects($this->at(1))->method('getValue')->willReturn(true); + + $this->stockColFactoryMock->expects($this->once())->method('create')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessStockCustomerRepositoryThrowsException() + { + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + + $this->scopeConfigMock->expects($this->at(0))->method('getValue')->willReturn(false); + $this->scopeConfigMock->expects($this->at(1))->method('getValue')->willReturn(true); + + $this->stockColFactoryMock->expects($this->once())->method('create')->willReturnSelf(); + $this->stockColFactoryMock->expects($this->once())->method('addWebsiteFilter')->willReturnSelf(); + $this->stockColFactoryMock->expects($this->once())->method('addStatusFilter')->willReturnSelf(); + $items = [ + new \Magento\Framework\DataObject([ + 'customer_id' => '42' + ]) + ]; + + $this->stockColFactoryMock->expects($this->once()) + ->method('setCustomerOrder') + ->willReturn(new \ArrayIterator($items)); + + $this->customerRepositoryMock->expects($this->once())->method('getById')->willThrowException(new \Exception); + + $this->observer->process(); + } + + /** + * @expectedException \Exception + */ + public function testProcessStockEmailThrowsException() + { + $id = 1; + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + + $this->emailFactoryMock->expects($this->once())->method('create')->willReturn($this->emailMock); + + $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$this->websiteMock]); + $this->websiteMock->expects($this->any())->method('getDefaultGroup')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getDefaultStore')->willReturnSelf(); + $this->websiteMock->expects($this->once())->method('getDefaultStore')->willReturn($this->storeMock); + $this->storeMock->expects($this->any())->method('getId')->willReturn(2); + + $this->scopeConfigMock->expects($this->at(0))->method('getValue')->willReturn(false); + $this->scopeConfigMock->expects($this->at(1))->method('getValue')->willReturn(true); + + $this->stockColFactoryMock->expects($this->once())->method('create')->willReturnSelf(); + $this->stockColFactoryMock->expects($this->once())->method('addWebsiteFilter')->willReturnSelf(); + $this->stockColFactoryMock->expects($this->once())->method('addStatusFilter')->willReturnSelf(); + $items = [ + new \Magento\Framework\DataObject([ + 'customer_id' => '42' + ]) + ]; + + $this->stockColFactoryMock->expects($this->once()) + ->method('setCustomerOrder') + ->willReturn(new \ArrayIterator($items)); + + $customer = new \Magento\Framework\DataObject(['group_id' => $id]); + $this->customerRepositoryMock->expects($this->once())->method('getById')->willReturn($customer); + + $this->productMock->expects($this->once())->method('setCustomerGroupId')->willReturnSelf(); + $this->productMock->expects($this->once())->method('isSalable')->willReturn(false); + $this->productRepositoryMock->expects($this->once())->method('getById')->willReturn($this->productMock); + + $this->emailMock->expects($this->once())->method('send')->willThrowException(new \Exception); + + $this->observer->process(); + } +} diff --git a/app/code/Magento/Sales/Model/CronJob/CleanExpiredOrders.php b/app/code/Magento/Sales/Model/CronJob/CleanExpiredOrders.php index 1932e8b19c84ed412c091e86316102c58cd124f1..43be14d66f49352a45d95bf99b5d01647e4cb038 100644 --- a/app/code/Magento/Sales/Model/CronJob/CleanExpiredOrders.php +++ b/app/code/Magento/Sales/Model/CronJob/CleanExpiredOrders.php @@ -20,23 +20,15 @@ class CleanExpiredOrders */ protected $orderCollectionFactory; - /** - * @var \Psr\Log\LoggerInterface - */ - protected $logger; - /** * @param StoresConfig $storesConfig - * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $collectionFactory */ public function __construct( StoresConfig $storesConfig, - \Psr\Log\LoggerInterface $logger, \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $collectionFactory ) { $this->storesConfig = $storesConfig; - $this->logger = $logger; $this->orderCollectionFactory = $collectionFactory; } @@ -56,13 +48,8 @@ class CleanExpiredOrders $orders->getSelect()->where( new \Zend_Db_Expr('TIME_TO_SEC(TIMEDIFF(CURRENT_TIMESTAMP, `updated_at`)) >= ' . $lifetime * 60) ); - - try { - $orders->walk('cancel'); - $orders->walk('save'); - } catch (\Exception $e) { - $this->logger->error('Error cancelling deprecated orders: ' . $e->getMessage()); - } + $orders->walk('cancel'); + $orders->walk('save'); } } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/CronJob/CleanExpiredOrdersTest.php b/app/code/Magento/Sales/Test/Unit/Model/CronJob/CleanExpiredOrdersTest.php index 5f69de657c5b2faef35e4789be5567edea68700f..e5dc2e0ed65e4d78490cb7f2dfcf97f9a436ab3d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/CronJob/CleanExpiredOrdersTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/CronJob/CleanExpiredOrdersTest.php @@ -26,11 +26,6 @@ class CleanExpiredOrdersTest extends \PHPUnit_Framework_TestCase */ protected $orderCollectionMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $loggerMock; - /** * @var ObjectManager */ @@ -65,11 +60,8 @@ class CleanExpiredOrdersTest extends \PHPUnit_Framework_TestCase false ); - $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class); - $this->model = new CleanExpiredOrders( $this->storesConfigMock, - $this->loggerMock, $this->collectionFactoryMock ); } @@ -94,10 +86,13 @@ class CleanExpiredOrdersTest extends \PHPUnit_Framework_TestCase $selectMock->expects($this->exactly(2))->method('where')->willReturnSelf(); $this->orderCollectionMock->expects($this->exactly(2))->method('getSelect')->willReturn($selectMock); - $this->loggerMock->expects($this->never())->method('error'); $this->model->execute(); } + /** + * @expectedException \Exception + * @expectedExceptionMessage Error500 + */ public function testExecuteWithException() { $schedule = [ @@ -121,9 +116,6 @@ class CleanExpiredOrdersTest extends \PHPUnit_Framework_TestCase $this->orderCollectionMock->expects($this->once()) ->method('walk') ->willThrowException(new \Exception($exceptionMessage)); - $this->loggerMock->expects($this->once()) - ->method('error') - ->with('Error cancelling deprecated orders: ' . $exceptionMessage); $this->model->execute(); } diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php index 1b0c9799503a07cf947241f8babe8e334529d87d..d6ee51d8c367d58ac0ad32af67c05d2e71d75ffc 100644 --- a/app/code/Magento/Sitemap/Model/Observer.php +++ b/app/code/Magento/Sitemap/Model/Observer.php @@ -89,6 +89,7 @@ class Observer * Generate sitemaps * * @return void + * @throws \Exception * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function scheduledGenerateSitemaps() @@ -108,11 +109,11 @@ class Observer /* @var $collection \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection */ foreach ($collection as $sitemap) { /* @var $sitemap \Magento\Sitemap\Model\Sitemap */ - try { $sitemap->generateXml(); } catch (\Exception $e) { $errors[] = $e->getMessage(); + throw $e; } } diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6e11b931607aac0977abd4fbc0df0b03c839bdf4 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sitemap\Test\Unit\Model; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class ObserverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + + /** + * @var \Magento\Sitemap\Model\Observer + */ + private $observer; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + + /** + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionFactoryMock; + + /** + * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $transportBuilderMock; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $inlineTranslationMock; + + /** + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection|\PHPUnit_Framework_MockObject_MockObject + */ + private $sitemapCollectionMock; + + /** + * @var \Magento\Sitemap\Model\Sitemap|\PHPUnit_Framework_MockObject_MockObject + */ + private $sitemapMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + protected function setUp() + { + $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->getMock(); + $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->getMock(); + $this->collectionFactoryMock = $this->getMockBuilder( + \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory::class + )->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->transportBuilderMock = $this->getMockBuilder(\Magento\Framework\Mail\Template\TransportBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->getMock(); + $this->inlineTranslationMock = $this->getMockBuilder(\Magento\Framework\Translate\Inline\StateInterface::class) + ->getMock(); + $this->sitemapCollectionMock = $this->getMock( + \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection::class, + ['getIterator'], + [], + '', + false + ); + $this->sitemapMock = $this->getMock(\Magento\Sitemap\Model\Sitemap::class, ['generateXml'], [], '', false); + + $this->objectManager = new ObjectManager($this); + $this->observer = $this->objectManager->getObject( + \Magento\Sitemap\Model\Observer::class, + [ + 'scopeConfig' => $this->scopeConfigMock, + 'collectionFactory' => $this->collectionFactoryMock, + 'storeManager' => $this->storeManagerMock, + 'transportBuilder' => $this->transportBuilderMock, + 'inlineTranslation' => $this->inlineTranslationMock + ] + ); + } + + /** + * @expectedException \Exception + */ + public function testScheduledGenerateSitemapsThrowsException() + { + $this->scopeConfigMock->expects($this->once())->method('isSetFlag')->willReturn(true); + + $this->collectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->sitemapCollectionMock); + + $this->sitemapCollectionMock->expects($this->any()) + ->method('getIterator') + ->willReturn(new \ArrayIterator([$this->sitemapMock])); + + $this->sitemapMock->expects($this->once())->method('generateXml')->willThrowException(new \Exception); + + $this->observer->scheduledGenerateSitemaps(); + } +} diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index abe587777dd9c0f0b786faffcb09686d3f6378a4..3f83f46e430c1e292d2582f2e413ebe0cc4a5460 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -57,6 +57,11 @@ var config = { "jquery/jstree/jquery.jstree": { "mage/backend/jstree-mixin": true } + }, + "text": { + "headers": { + "X-Requested-With": "XMLHttpRequest" + } } } }; diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 7c2bbc65cbd9b4a5e999f036e8d382c1b303ea61..917b62a5042f84337fed4f687da861b8b4c5a659 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -106,8 +106,8 @@ define([ this._super(); - scope = this.dataScope; - name = scope.split('.').slice(1); + scope = this.dataScope; + name = scope.split('.').slice(1); valueUpdate = this.showFallbackReset ? 'afterkeydown' : this.valueUpdate; @@ -264,7 +264,7 @@ define([ * @returns {Abstract} Chainable. */ setValidation: function (rule, options) { - var rules = utils.copy(this.validation), + var rules = utils.copy(this.validation), changed; if (_.isObject(rule)) { @@ -306,7 +306,7 @@ define([ * * @returns {Boolean} */ - hasService: function() { + hasService: function () { return this.service && this.service.template; }, @@ -379,8 +379,8 @@ define([ * @returns {Object} Validate information. */ validate: function () { - var value = this.value(), - result = validator(this.validation, value, this.validationParams), + var value = this.value(), + result = validator(this.validation, value, this.validationParams), message = !this.disabled() && this.visible() ? result.message : '', isValid = this.disabled() || !this.visible() || result.passed; @@ -412,6 +412,7 @@ define([ */ restoreToDefault: function () { this.value(this.default); + this.focused(true); }, /** @@ -433,7 +434,7 @@ define([ /** * Callback when value is changed by user */ - userChanges: function() { + userChanges: function () { this.valueChangedByUser = true; } }); diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 60ffd0e69903b9037cb3eefbb459caccd858b5ac..672af8a7ed845a12efe19f0801325e23c06932a6 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -155,6 +155,7 @@ define([ additionalInvalid: false, selectorPrefix: '.page-content', messagesClass: 'messages', + errorClass: '.admin__field._error', eventPrefix: '.${ $.index }', ajaxSave: false, ajaxSaveType: 'default', @@ -247,11 +248,16 @@ define([ * @param {Object} data */ save: function (redirect, data) { + var scrollTop; + this.validate(); if (!this.additionalInvalid && !this.source.get('params.invalid')) { this.setAdditionalData(data) .submit(redirect); + } else { + scrollTop = $(this.errorClass).offset().top - window.innerHeight / 2; + window.scrollTo(0, scrollTop); } }, diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index 84a4114254830439a36d31fc4b9872862d0146cf..64f78bd64fc0e84d41d852ee5e535875d4323ca0 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -33,9 +33,9 @@ <td css="$parents[1].setClasses(elem)" if="elem.template"> <div class="fieldset-wrapper admin__collapsible-block-wrapper" collapsible="openClass: '_show', closeOnOuter: false, opened: elem.opened()"> - <div class="fieldset-wrapper-title" toggleCollapsible> + <div class="fieldset-wrapper-title"> - <div class="admin__collapsible-title" data-role="collapsible-title"> + <div class="admin__collapsible-title" data-role="collapsible-title" click="elem.toggleOpened"> <render args="name: $parents[1].dndConfig.template, data: $parents[1].dnd" if="$parents[1].dndConfig.enabled" /> @@ -53,7 +53,7 @@ </div> <div class="admin__collapsible-content" - css="{_show: $collapsible.opened()}" + css="{_show: $data.opened()}" data-role="collapsible-content" template="elem.template"></div> </div> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php index 034b3522ba8788937133dfde0944f68d6604be73..a6527a6c66936b794b9eb38588e335e9076b8880 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php @@ -270,7 +270,7 @@ class FilterTest extends \PHPUnit_Framework_TestCase 'File with compilation error results in error message' => [ TemplateTypesInterface::TYPE_HTML, 'file="css/file-with-error.css"', - \Magento\Framework\View\Asset\ContentProcessorInterface::ERROR_MESSAGE_PREFIX, + 'variable @non-existent-variable is undefined', ], ]; } @@ -356,7 +356,7 @@ class FilterTest extends \PHPUnit_Framework_TestCase ], 'Developer mode - File with compilation error results in error message' => [ '<html><p></p> {{inlinecss file="css/file-with-error.css"}}</html>', - \Magento\Framework\View\Asset\ContentProcessorInterface::ERROR_MESSAGE_PREFIX, + 'CSS inlining error:', false, ], ]; diff --git a/lib/internal/Magento/Framework/App/StaticResource.php b/lib/internal/Magento/Framework/App/StaticResource.php index 4367e8905e8c29e0c030a6565ead797226f36f0a..beeeb716260e93f10cf810ddd3321ceb6f42e8d1 100644 --- a/lib/internal/Magento/Framework/App/StaticResource.php +++ b/lib/internal/Magento/Framework/App/StaticResource.php @@ -8,6 +8,7 @@ namespace Magento\Framework\App; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\ObjectManager\ConfigLoaderInterface; use Magento\Framework\Filesystem; +use Psr\Log\LoggerInterface; /** * Entry point for retrieving static resources like JS, CSS, images by requested public path @@ -43,6 +44,9 @@ class StaticResource implements \Magento\Framework\AppInterface /** @var Filesystem */ private $filesystem; + /** @var LoggerInterface */ + private $logger; + /** * @param State $state * @param Response\FileInterface $response @@ -105,6 +109,7 @@ class StaticResource implements \Magento\Framework\AppInterface */ public function catchException(Bootstrap $bootstrap, \Exception $exception) { + $this->getLogger()->critical($exception->getMessage()); if ($bootstrap->isDeveloperMode()) { $this->response->setHttpResponseCode(404); $this->response->setHeader('Content-Type', 'text/plain'); @@ -161,4 +166,19 @@ class StaticResource implements \Magento\Framework\AppInterface } return $this->filesystem; } + + /** + * Retrieves LoggerInterface instance + * + * @return LoggerInterface + * @deprecated + */ + private function getLogger() + { + if (!$this->logger) { + $this->logger = $this->objectManager->get(LoggerInterface::class); + } + + return $this->logger; + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php b/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php index 7b745a5088483dc3320e88fc094d849d24ce64b2..002e4746f6fb021ac6850ecb44f469f98d72ecd3 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php @@ -61,6 +61,11 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase */ private $object; + /** + * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $logger; + protected function setUp() { $this->state = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false); @@ -70,6 +75,7 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase $this->assetRepo = $this->getMock(\Magento\Framework\View\Asset\Repository::class, [], [], '', false); $this->moduleList = $this->getMock(\Magento\Framework\Module\ModuleList::class, [], [], '', false); $this->objectManager = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class); + $this->logger = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); $this->configLoader = $this->getMock( \Magento\Framework\App\ObjectManager\ConfigLoader::class, [], [], '', false ); @@ -196,6 +202,12 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase public function testCatchExceptionDeveloperMode() { + $this->objectManager->expects($this->once()) + ->method('get') + ->with('Psr\Log\LoggerInterface') + ->willReturn($this->logger); + $this->logger->expects($this->once()) + ->method('critical'); $bootstrap = $this->getMockBuilder(Bootstrap::class)->disableOriginalConstructor()->getMock(); $bootstrap->expects($this->once())->method('isDeveloperMode')->willReturn(true); $exception = new \Exception('Error: nothing works'); diff --git a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/Less/Processor.php b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/Less/Processor.php index 6387ac46e038c1fd84d31b3d30dff5b7bd9473a0..49d2545ea5bb807bdd7853047e0496966e5ba177 100644 --- a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/Less/Processor.php +++ b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/Less/Processor.php @@ -94,10 +94,7 @@ class Processor implements ContentProcessorInterface return $content; } catch (\Exception $e) { - $errorMessage = PHP_EOL . self::ERROR_MESSAGE_PREFIX . PHP_EOL . $path . PHP_EOL . $e->getMessage(); - $this->logger->critical($errorMessage); - - throw new ContentProcessorException(new Phrase($errorMessage)); + throw new ContentProcessorException(new Phrase($e->getMessage())); } } } diff --git a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/Adapter/Less/ProcessorTest.php b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/Adapter/Less/ProcessorTest.php index 852a2138c773b1ce7ae1a1fbee6e45b6d124d52c..4a8f35751bd4c0b710febcf6541b9cd5e18e1697 100644 --- a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/Adapter/Less/ProcessorTest.php +++ b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/Adapter/Less/ProcessorTest.php @@ -81,7 +81,7 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase * Test for processContent method (exception) * * @expectedException \Magento\Framework\View\Asset\ContentProcessorException - * @expectedExceptionMessageRegExp (Compilation from source:.*Test exception) + * @expectedExceptionMessageRegExp (Test exception) */ public function testProcessContentException() { @@ -96,11 +96,8 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase ->with($assetMock) ->willThrowException(new \Exception(self::ERROR_MESSAGE)); - $this->loggerMock->expects(self::once()) - ->method('critical') - ->with( - PHP_EOL . Processor::ERROR_MESSAGE_PREFIX . PHP_EOL . self::ASSET_PATH . PHP_EOL . self::ERROR_MESSAGE - ); + $this->loggerMock->expects(self::never()) + ->method('critical'); $this->temporaryFileMock->expects(self::never()) ->method('createFile'); diff --git a/lib/web/mage/requirejs/text.js b/lib/web/mage/requirejs/text.js index b1df6f2078756cf3ae5b1cf7456f2616782b75e1..879eeeeebd2315c1c07077845423c6cf0dc22f50 100644 --- a/lib/web/mage/requirejs/text.js +++ b/lib/web/mage/requirejs/text.js @@ -89,6 +89,8 @@ define(['module'], function (module) { header, errorHandler = fail || Function(); + xhr.open('GET', url); + /*eslint-disable max-depth */ if ('setRequestHeader' in xhr && headers) { for (header in headers) { @@ -127,7 +129,6 @@ define(['module'], function (module) { } }; - xhr.open('GET', url); xhr.send(); } diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js index 0257f6f13262f7dbe3e1f5af21e0fee62d57c232..decce85a620ba525e12765202c84aedfe0b5c882 100644 --- a/lib/web/mage/utils/misc.js +++ b/lib/web/mage/utils/misc.js @@ -171,12 +171,12 @@ define([ config.response.status(undefined); config.response.status(!data.error); }) - .fail(function (xhr) { + .fail(function () { config.response.status(undefined); config.response.status(false); config.response.data({ error: true, - messages: xhr.statusText, + messages: 'Something went wrong.', t: t }); }) diff --git a/nginx.conf.sample b/nginx.conf.sample index bb872a609e6446aea46b0a96427e880e1e2b4714..36adc71d0c3161412a7b4ba283b1a021ab3fcf5a 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -167,7 +167,7 @@ location ~ (index|get|static|report|404|503)\.php$ { fastcgi_buffers 1024 4k; fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; - fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=600"; + fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=18000"; fastcgi_read_timeout 600s; fastcgi_connect_timeout 600s; diff --git a/pub/.htaccess b/pub/.htaccess index 926c012eef6a577d36dbf953e6797cb291bed5af..a8fc2ccf222dbb6a7ba562a0e18ddff9cfdca21c 100644 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -32,12 +32,10 @@ DirectoryIndex index.php -<IfModule mod_php5.c> - ############################################ ## Adjust memory limit - php_value memory_limit 256M + php_value memory_limit 768M php_value max_execution_time 18000 ############################################ @@ -56,34 +54,6 @@ php_flag suhosin.session.cryptua off -</IfModule> - -<IfModule mod_php7.c> - -############################################ -## Adjust memory limit - - php_value memory_limit 256M - php_value max_execution_time 18000 - -############################################ -## Disable automatic session start -## before autoload was initialized - - php_flag session.auto_start off - -############################################ -## Enable resulting html compression - - #php_flag zlib.output_compression on - -########################################### -# Disable user agent verification to not break multiple image upload - - php_flag suhosin.session.cryptua off - -</IfModule> - <IfModule mod_security.c> ########################################### # Disable POST processing to not break multiple image upload