Skip to content

Commit 14074ab

Browse files
committed
Merge remote-tracking branch 'mainline/develop' into publication
2 parents 62bda63 + 08b6497 commit 14074ab

File tree

13 files changed

+156
-48
lines changed

13 files changed

+156
-48
lines changed

.htaccess

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@
172172
## http://developer.yahoo.com/performance/rules.html#expires
173173

174174
ExpiresDefault "access plus 1 year"
175+
ExpiresByType text/html A0
176+
ExpiresByType text/plain A0
175177

176178
</IfModule>
177179

.htaccess.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@
169169
## http://developer.yahoo.com/performance/rules.html#expires
170170

171171
ExpiresDefault "access plus 1 year"
172+
ExpiresByType text/html A0
173+
ExpiresByType text/plain A0
172174

173175
</IfModule>
174176

app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/checkbox.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<input class="bundle-option-<?php echo $_option->getId() ?> checkbox product bundle option change-container-classname"
3030
id="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>"
3131
type="checkbox"
32-
<?php if ($_option->getRequired()) echo 'data-validate="{\'validate-one-required-by-name\':true}"'?>
32+
<?php if ($_option->getRequired()) echo 'data-validate="{\'validate-one-required-by-name\':\'input[name^=&quot;bundle_option[' . $_option->getId() . ']&quot;]:checked\'}"'?>
3333
name="bundle_option[<?php echo $_option->getId() ?>][<?php echo $_selection->getId() ?>]"
3434
<?php if ($block->isSelected($_selection)) echo ' checked="checked"' ?>
3535
<?php if (!$_selection->isSaleable()) echo ' disabled="disabled"' ?>

app/code/Magento/Cron/Model/Observer.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,13 @@ protected function _cleanup($groupId)
345345
return $this;
346346
}
347347

348+
// check how long the record should stay unprocessed before marked as MISSED
349+
$scheduleLifetime = (int)$this->_scopeConfig->getValue(
350+
'system/cron/' . $groupId . '/' . self::XML_PATH_SCHEDULE_LIFETIME,
351+
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
352+
);
353+
$scheduleLifetime = $scheduleLifetime * self::SECONDS_IN_MINUTE;
354+
348355
/**
349356
* @var \Magento\Cron\Model\Resource\Schedule\Collection $history
350357
*/
@@ -370,7 +377,8 @@ protected function _cleanup($groupId)
370377
$now = $this->timezone->scopeTimeStamp();
371378
/** @var Schedule $record */
372379
foreach ($history as $record) {
373-
$checkTime = strtotime($record->getExecutedAt() ? $record->getExecutedAt() : $record->getScheduledAt());
380+
$checkTime = $record->getExecutedAt() ? strtotime($record->getExecutedAt()) :
381+
strtotime($record->getScheduledAt()) + $scheduleLifetime;
374382
if ($checkTime < $now - $historyLifetimes[$record->getStatus()]) {
375383
$record->delete();
376384
}

app/code/Magento/Cron/Test/Unit/Model/ObserverTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Cron\Test\Unit\Model;
77

8+
use Magento\Cron\Model\Schedule;
9+
810
/**
911
* Class \Magento\Cron\Test\Unit\Model\ObserverTest
1012
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -607,4 +609,84 @@ public function testDispatchCleanup()
607609

608610
$this->_observer->dispatch('');
609611
}
612+
613+
public function testMissedJobsCleanedInTime()
614+
{
615+
/* 1. Initialize dependencies of _generate() method which is called first */
616+
$jobConfig = [
617+
'test_group' => ['test_job1' => ['instance' => 'CronJob', 'method' => 'execute']],
618+
];
619+
620+
// This item was scheduled 2 days ago
621+
$schedule1 = $this->getMockBuilder(
622+
'Magento\Cron\Model\Schedule'
623+
)->disableOriginalConstructor()->setMethods(
624+
['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup']
625+
)->getMock();
626+
$schedule1->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null));
627+
$schedule1->expects($this->any())->method('getScheduledAt')->will($this->returnValue('-2 day -1 hour'));
628+
$schedule1->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED));
629+
//we expect this job be deleted from the list
630+
$schedule1->expects($this->once())->method('delete')->will($this->returnValue(true));
631+
632+
// This item was scheduled 1 day ago
633+
$schedule2 = $this->getMockBuilder(
634+
'Magento\Cron\Model\Schedule'
635+
)->disableOriginalConstructor()->setMethods(
636+
['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup']
637+
)->getMock();
638+
$schedule2->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null));
639+
$schedule2->expects($this->any())->method('getScheduledAt')->will($this->returnValue('-1 day'));
640+
$schedule2->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED));
641+
//we don't expect this job be deleted from the list
642+
$schedule2->expects($this->never())->method('delete');
643+
644+
$this->_collection->addItem($schedule1);
645+
$this->_config->expects($this->once())->method('getJobs')->will($this->returnValue($jobConfig));
646+
647+
//get configuration value CACHE_KEY_LAST_HISTORY_CLEANUP_AT in the "_generate()"
648+
$this->_cache->expects($this->at(0))->method('load')->will($this->returnValue(time() + 10000000));
649+
//get configuration value CACHE_KEY_LAST_HISTORY_CLEANUP_AT in the "_cleanup()"
650+
$this->_cache->expects($this->at(1))->method('load')->will($this->returnValue(time() - 10000000));
651+
652+
$this->_scopeConfig->expects($this->at(0))->method('getValue')
653+
->with($this->equalTo('system/cron/test_group/use_separate_process'))
654+
->will($this->returnValue(0));
655+
$this->_scopeConfig->expects($this->at(1))->method('getValue')
656+
->with($this->equalTo('system/cron/test_group/schedule_generate_every'))
657+
->will($this->returnValue(0));
658+
$this->_scopeConfig->expects($this->at(2))->method('getValue')
659+
->with($this->equalTo('system/cron/test_group/history_cleanup_every'))
660+
->will($this->returnValue(0));
661+
$this->_scopeConfig->expects($this->at(3))->method('getValue')
662+
->with($this->equalTo('system/cron/test_group/schedule_lifetime'))
663+
->will($this->returnValue(2*24*60));
664+
$this->_scopeConfig->expects($this->at(4))->method('getValue')
665+
->with($this->equalTo('system/cron/test_group/history_success_lifetime'))
666+
->will($this->returnValue(0));
667+
$this->_scopeConfig->expects($this->at(5))->method('getValue')
668+
->with($this->equalTo('system/cron/test_group/history_failure_lifetime'))
669+
->will($this->returnValue(0));
670+
671+
/* 2. Initialize dependencies of _cleanup() method which is called second */
672+
$scheduleMock = $this->getMockBuilder('Magento\Cron\Model\Schedule')->disableOriginalConstructor()->getMock();
673+
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
674+
$this->_scheduleFactory->expects($this->at(0))->method('create')->will($this->returnValue($scheduleMock));
675+
676+
$collection = $this->getMockBuilder(
677+
'Magento\Cron\Model\Resource\Schedule\Collection'
678+
)->setMethods(
679+
['addFieldToFilter', 'load', '__wakeup']
680+
)->disableOriginalConstructor()->getMock();
681+
$collection->expects($this->any())->method('addFieldToFilter')->will($this->returnSelf());
682+
$collection->expects($this->any())->method('load')->will($this->returnSelf());
683+
$collection->addItem($schedule1);
684+
$collection->addItem($schedule2);
685+
686+
$scheduleMock = $this->getMockBuilder('Magento\Cron\Model\Schedule')->disableOriginalConstructor()->getMock();
687+
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($collection));
688+
$this->_scheduleFactory->expects($this->at(1))->method('create')->will($this->returnValue($scheduleMock));
689+
690+
$this->_observer->dispatch('');
691+
}
610692
}

app/code/Magento/Customer/Model/AccountManagement.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,7 @@ protected function sendPasswordResetNotificationEmail($customer)
839839
$storeId = $this->getWebsiteStoreId($customer);
840840
}
841841

842+
$customerEmailData = $this->getFullCustomerObject($customer);
842843
/** @var \Magento\Framework\Mail\TransportInterface $transport */
843844
$transport = $this->transportBuilder->setTemplateIdentifier(
844845
$this->scopeConfig->getValue(
@@ -849,7 +850,7 @@ protected function sendPasswordResetNotificationEmail($customer)
849850
)->setTemplateOptions(
850851
['area' => \Magento\Framework\App\Area::AREA_FRONTEND, 'store' => $storeId]
851852
)->setTemplateVars(
852-
['customer' => $customer, 'store' => $this->storeManager->getStore($storeId)]
853+
['customer' => $customerEmailData, 'store' => $this->storeManager->getStore($storeId)]
853854
)->setFrom(
854855
$this->scopeConfig->getValue(
855856
self::XML_PATH_FORGOT_EMAIL_IDENTITY,

app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
1010
use Magento\Backend\App\Action;
11+
use Magento\Framework\View\Result\LayoutFactory;
1112

1213
class AddComment extends \Magento\Backend\App\Action
1314
{
@@ -21,18 +22,26 @@ class AddComment extends \Magento\Backend\App\Action
2122
*/
2223
protected $shipmentSender;
2324

25+
/**
26+
* @var LayoutFactory
27+
*/
28+
protected $resultLayoutFactory;
29+
2430
/**
2531
* @param Action\Context $context
2632
* @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
2733
* @param ShipmentSender $shipmentSender
34+
* @param LayoutFactory $resultLayoutFactory
2835
*/
2936
public function __construct(
3037
Action\Context $context,
3138
\Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
32-
ShipmentSender $shipmentSender
39+
ShipmentSender $shipmentSender,
40+
LayoutFactory $resultLayoutFactory
3341
) {
3442
$this->shipmentLoader = $shipmentLoader;
3543
$this->shipmentSender = $shipmentSender;
44+
$this->resultLayoutFactory = $resultLayoutFactory;
3645
parent::__construct($context);
3746
}
3847

@@ -72,10 +81,9 @@ public function execute()
7281

7382
$this->shipmentSender->send($shipment, !empty($data['is_customer_notified']), $data['comment']);
7483
$shipment->save();
75-
76-
$this->_view->loadLayout(false);
77-
$this->_view->getPage()->getConfig()->getTitle()->prepend(__('Shipments'));
78-
$response = $this->_view->getLayout()->getBlock('shipment_comments')->toHtml();
84+
$resultLayout = $this->resultLayoutFactory->create();
85+
$resultLayout->addDefaultHandle();
86+
$response = $resultLayout->getLayout()->getBlock('shipment_comments')->toHtml();
7987
} catch (\Magento\Framework\Exception\LocalizedException $e) {
8088
$response = ['error' => true, 'message' => $e->getMessage()];
8189
} catch (\Exception $e) {

app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/AddCommentTest.php

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,11 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
3030
*/
3131
protected $responseMock;
3232

33-
/**
34-
* @var \Magento\Framework\View\Page\Title|\PHPUnit_Framework_MockObject_MockObject
35-
*/
36-
protected $titleMock;
37-
3833
/**
3934
* @var \PHPUnit_Framework_MockObject_MockObject
4035
*/
4136
protected $resultPageMock;
4237

43-
/**
44-
* @var \PHPUnit_Framework_MockObject_MockObject
45-
*/
46-
protected $pageConfigMock;
47-
4838
/**
4939
* @var \Magento\Sales\Model\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject
5040
*/
@@ -55,6 +45,11 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
5545
*/
5646
protected $viewInterfaceMock;
5747

48+
/**
49+
* @var \Magento\Framework\View\Result\LayoutFactory|\PHPUnit_Framework_MockObject_MockObject
50+
*/
51+
protected $resultLayoutFactoryMock;
52+
5853
/**
5954
* @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
6055
*/
@@ -95,9 +90,9 @@ protected function setUp()
9590
'',
9691
false
9792
);
98-
$this->titleMock = $this->getMock(
99-
'Magento\Framework\View\Page\Title',
100-
['prepend', '__wakeup'],
93+
$this->resultLayoutFactoryMock = $this->getMock(
94+
'Magento\Framework\View\Result\LayoutFactory',
95+
['create'],
10196
[],
10297
'',
10398
false
@@ -106,9 +101,6 @@ protected function setUp()
106101
$this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
107102
->disableOriginalConstructor()
108103
->getMock();
109-
$this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
110-
->disableOriginalConstructor()
111-
->getMock();
112104

113105
$this->shipmentMock = $this->getMock(
114106
'Magento\Sales\Model\Order\Shipment',
@@ -136,15 +128,9 @@ protected function setUp()
136128
$this->viewInterfaceMock->expects($this->any())->method('getPage')->will(
137129
$this->returnValue($this->resultPageMock)
138130
);
139-
$this->resultPageMock->expects($this->any())->method('getConfig')->will(
140-
$this->returnValue($this->pageConfigMock)
141-
);
142-
143-
$this->pageConfigMock->expects($this->any())->method('getTitle')->will($this->returnValue($this->titleMock));
144131

145132
$contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->requestMock));
146133
$contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->responseMock));
147-
$contextMock->expects($this->any())->method('getTitle')->will($this->returnValue($this->titleMock));
148134
$contextMock->expects($this->any())->method('getView')->will($this->returnValue($this->viewInterfaceMock));
149135
$contextMock->expects($this->any())
150136
->method('getObjectManager')
@@ -153,7 +139,8 @@ protected function setUp()
153139
$this->controller = new \Magento\Shipping\Controller\Adminhtml\Order\Shipment\AddComment(
154140
$contextMock,
155141
$this->shipmentLoaderMock,
156-
$this->shipmentSenderMock
142+
$this->shipmentSenderMock,
143+
$this->resultLayoutFactoryMock
157144
);
158145
}
159146

@@ -189,15 +176,19 @@ public function testExecute()
189176
$shipment = [];
190177
$tracking = [];
191178

192-
$layoutMock = $this->getMock('Magento\Framework\View\Layout', ['getBlock'], [], '', false);
193-
$blockMock = $this->getMock('Magento\Shipping\Block\Adminhtml\View\Comments', ['toHtml'], [], '', false);
179+
$resultLayoutMock = $this->getMock(
180+
'Magento\Framework\View\Result\Layout',
181+
['getBlock', 'getDefaultLayoutHandle', 'addDefaultHandle', 'getLayout'],
182+
[],
183+
'',
184+
false
185+
);
194186

195187
$this->requestMock->expects($this->once())->method('setParam')->with('shipment_id', $shipmentId);
196188
$this->requestMock->expects($this->once())
197189
->method('getPost')
198190
->with('comment')
199191
->will($this->returnValue($data));
200-
$this->titleMock->expects($this->once())->method('prepend');
201192
$this->requestMock->expects($this->any())
202193
->method('getParam')
203194
->will(
@@ -221,10 +212,15 @@ public function testExecute()
221212
$this->shipmentMock->expects($this->once())->method('addComment');
222213
$this->shipmentSenderMock->expects($this->once())->method('send');
223214
$this->shipmentMock->expects($this->once())->method('save');
224-
$this->viewInterfaceMock->expects($this->once())->method('loadLayout')->with(false);
225-
$this->viewInterfaceMock->expects($this->once())->method('getLayout')->will($this->returnValue($layoutMock));
226-
$layoutMock->expects($this->once())->method('getBlock')->will($this->returnValue($blockMock));
227-
$blockMock->expects($this->once())->method('toHtml')->will($this->returnValue($result));
215+
$layoutMock = $this->getMock('Magento\Framework\View\Layout', ['getBlock'], [], '', false);
216+
$blockMock = $this->getMock('Magento\Shipping\Block\Adminhtml\View\Comments', ['toHtml'], [], '', false);
217+
$blockMock->expects($this->once())->method('toHtml')->willReturn($result);
218+
$layoutMock->expects($this->once())->method('getBlock')
219+
->with('shipment_comments')->willReturn($blockMock);
220+
$resultLayoutMock->expects($this->once())->method('getLayout')->willReturn($layoutMock);
221+
$resultLayoutMock->expects($this->once())->method('addDefaultHandle');
222+
$this->resultLayoutFactoryMock->expects($this->once())->method('create')
223+
->will($this->returnValue($resultLayoutMock));
228224
$this->responseMock->expects($this->once())->method('setBody')->with($result);
229225

230226
$this->assertNull($this->controller->execute());

dev/tests/functional/.htaccess

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@
170170
## http://developer.yahoo.com/performance/rules.html#expires
171171

172172
ExpiresDefault "access plus 1 year"
173+
ExpiresByType text/html A0
174+
ExpiresByType text/plain A0
173175

174176
</IfModule>
175177

@@ -191,4 +193,4 @@
191193
## If running in cluster environment, uncomment this
192194
## http://developer.yahoo.com/performance/rules.html#etags
193195

194-
#FileETag none
196+
#FileETag none

lib/web/mage/backend/suggest.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -811,15 +811,19 @@
811811
* @private
812812
*/
813813
_renderMultiselect: function () {
814+
var that = this;
814815
this.element.wrap(this.options.multiSuggestWrapper);
815816
this.elementWrapper = this.element.closest('[data-role="parent-choice-element"]');
816-
this._getOptions().each($.proxy(function (i, option) {
817-
option = $(option);
818-
this._createOption({
819-
id: option.val(),
820-
label: option.text()
821-
});
822-
}, this));
817+
$(function () {
818+
that._getOptions()
819+
.each(function (i, option) {
820+
option = $(option);
821+
that._createOption({
822+
id: option.val(),
823+
label: option.text()
824+
});
825+
});
826+
});
823827
},
824828

825829
/**

lib/web/mage/validation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,10 +916,10 @@
916916
'This is a required field.'
917917
],
918918
"validate-one-required-by-name": [
919-
function(v, elm) {
919+
function(v, elm, selector) {
920920
var name = elm.name.replace(/([\\"])/g, '\\$1'),
921921
container = this.currentForm,
922-
selector = 'input[name="' + name + '"]:checked';
922+
selector = selector === true ? 'input[name="' + name + '"]:checked' : selector;
923923

924924
return !!container.querySelectorAll(selector).length;
925925
},

0 commit comments

Comments
 (0)