Skip to content

Commit a3f8af9

Browse files
committed
Merge branch 'develop' of github.com:magento/magento2ce into MAGETWO-54211
2 parents 7ed3a7d + e7d6678 commit a3f8af9

File tree

26 files changed

+615
-107
lines changed

26 files changed

+615
-107
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,4 @@ Pagination,Pagination
456456
"Anchor Text for Next","Anchor Text for Next"
457457
"Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used.","Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used."
458458
"Theme Name","Theme Name"
459+
"Deployment config file %1 is not writable.","Deployment config file %1 is not writable."
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © 2016 Magento. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
9+
<event name="catalog_product_to_website_change">
10+
<observer name="catalog_product_to_website_change" instance="Magento\CatalogUrlRewrite\Observer\ProductToWebsiteChangeObserver"/>
11+
</event>
12+
</config>

app/code/Magento/Checkout/CustomerData/DefaultItem.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ protected function doGetItemData()
7171
'configure_url' => $this->getConfigureUrl(),
7272
'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(),
7373
'product_name' => $this->item->getProduct()->getName(),
74+
'product_sku' => $this->item->getProduct()->getSku(),
7475
'product_url' => $this->getProductUrl(),
7576
'product_has_url' => $this->hasProductUrl(),
7677
'product_price' => $this->checkoutHelper->formatPrice($this->item->getCalculationPrice()),
78+
'product_price_value' => $this->item->getCalculationPrice(),
7779
'product_image' => [
7880
'src' => $imageHelper->getUrl(),
7981
'alt' => $imageHelper->getLabel(),
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Checkout\Test\Unit\CustomerData;
7+
8+
class DefaultItemTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var \Magento\Checkout\CustomerData\DefaultItem
12+
*/
13+
protected $model;
14+
15+
/**
16+
* @var \Magento\Catalog\Helper\Image
17+
*/
18+
private $imageHelper;
19+
20+
/**
21+
* @var \Magento\Catalog\Helper\Product\ConfigurationPool
22+
*/
23+
private $configurationPool;
24+
25+
protected function setUp()
26+
{
27+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
28+
$this->imageHelper = $this->getMockBuilder(\Magento\Catalog\Helper\Image::class)
29+
->disableOriginalConstructor()
30+
->getMock();
31+
$this->configurationPool = $this->getMockBuilder(\Magento\Catalog\Helper\Product\ConfigurationPool::class)
32+
->setMethods([])
33+
->disableOriginalConstructor()
34+
->getMock();
35+
$checkoutHelper = $this->getMockBuilder(\Magento\Checkout\Helper\Data::class)
36+
->setMethods(['formatPrice'])->disableOriginalConstructor()->getMock();
37+
$checkoutHelper->expects($this->any())->method('formatPrice')->willReturn(5);
38+
$this->model = $objectManager->getObject(
39+
\Magento\Checkout\CustomerData\DefaultItem::class,
40+
[
41+
'imageHelper' => $this->imageHelper,
42+
'configurationPool' => $this->configurationPool,
43+
'checkoutHelper' => $checkoutHelper
44+
]
45+
);
46+
}
47+
48+
public function testGetItemData()
49+
{
50+
$urlModel = $this->getMockBuilder(\Magento\Catalog\Model\Product\Url::class)
51+
->disableOriginalConstructor()
52+
->getMock();
53+
$product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
54+
->setMethods(['getUrlModel', 'isVisibleInSiteVisibility', 'getSku'])
55+
->disableOriginalConstructor()
56+
->getMock();
57+
$product->expects($this->any())->method('getUrlModel')->willReturn($urlModel);
58+
$product->expects($this->any())->method('isVisibleInSiteVisibility')->willReturn(true);
59+
$product->expects($this->any())->method('getSku')->willReturn('simple');
60+
/** @var \Magento\Quote\Model\Quote\Item $item */
61+
$item = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class)
62+
->setMethods(['getProductType', 'getProduct', 'getCalculationPrice'])
63+
->disableOriginalConstructor()
64+
->getMock();
65+
$item->expects($this->any())->method('getProduct')->willReturn($product);
66+
$item->expects($this->any())->method('getProductType')->willReturn('simple');
67+
$item->expects($this->any())->method('getCalculationPrice')->willReturn(5);
68+
69+
$this->imageHelper->expects($this->any())->method('init')->with($product)->willReturnSelf();
70+
$this->imageHelper->expects($this->any())->method('getUrl')->willReturn('url');
71+
$this->imageHelper->expects($this->any())->method('getLabel')->willReturn('label');
72+
$this->imageHelper->expects($this->any())->method('getWidth')->willReturn(100);
73+
$this->imageHelper->expects($this->any())->method('getHeight')->willReturn(100);
74+
$this->configurationPool->expects($this->any())->method('getByProductType')->willReturn($product);
75+
76+
$itemData = $this->model->getItemData($item);
77+
$this->assertArrayHasKey('options', $itemData);
78+
$this->assertArrayHasKey('qty', $itemData);
79+
$this->assertArrayHasKey('item_id', $itemData);
80+
$this->assertArrayHasKey('configure_url', $itemData);
81+
$this->assertArrayHasKey('is_visible_in_site_visibility', $itemData);
82+
$this->assertArrayHasKey('product_type', $itemData);
83+
$this->assertArrayHasKey('product_name', $itemData);
84+
$this->assertArrayHasKey('product_sku', $itemData);
85+
$this->assertArrayHasKey('product_url', $itemData);
86+
$this->assertArrayHasKey('product_has_url', $itemData);
87+
$this->assertArrayHasKey('product_price', $itemData);
88+
$this->assertArrayHasKey('product_price_value', $itemData);
89+
$this->assertArrayHasKey('product_image', $itemData);
90+
$this->assertArrayHasKey('canApplyMsrp', $itemData);
91+
}
92+
}
93+

app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
<input data-bind="attr: {
7575
id: 'cart-item-'+item_id+'-qty',
7676
'data-cart-item': item_id,
77-
'data-item-qty': qty
77+
'data-item-qty': qty,
78+
'data-cart-item-id': product_sku
7879
}, value: qty"
7980
type="number"
8081
size="4"

app/code/Magento/PageCache/etc/varnish3.vcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ sub vcl_recv {
4949
return (pass);
5050
}
5151

52-
# Bypass shopping cart and checkout requests
53-
if (req.url ~ "/checkout") {
52+
# Bypass shopping cart, checkout and search requests
53+
if (req.url ~ "/checkout" || req.url ~ "/catalogsearch") {
5454
return (pass);
5555
}
5656

app/code/Magento/PageCache/etc/varnish4.vcl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ sub vcl_recv {
4141
return (pass);
4242
}
4343

44-
# Bypass shopping cart and checkout requests
45-
if (req.url ~ "/checkout") {
44+
# Bypass shopping cart, checkout and search requests
45+
if (req.url ~ "/checkout" || req.url ~ "/catalogsearch") {
4646
return (pass);
4747
}
4848

@@ -136,6 +136,16 @@ sub vcl_backend_response {
136136
set beresp.grace = 1m;
137137
}
138138
}
139+
140+
# If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
141+
if (beresp.ttl <= 0s ||
142+
beresp.http.Surrogate-control ~ "no-store" ||
143+
(!beresp.http.Surrogate-Control && beresp.http.Vary == "*")) {
144+
# Mark as Hit-For-Pass for the next 2 minutes
145+
set beresp.ttl = 120s;
146+
set beresp.uncacheable = true;
147+
}
148+
return (deliver);
139149
}
140150

141151
sub vcl_deliver {

app/code/Magento/Translation/Model/Inline/Parser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,12 @@ private function _prepareTagAttributesForContent(&$content)
436436
$tagHtml = str_replace($matches[0], '', $tagHtml);
437437
$trAttr = ' ' . $this->_getHtmlAttribute(
438438
self::DATA_TRANSLATE,
439-
'[' . htmlspecialchars($matches[1]) . ',' . join(',', $trArr) . ']'
439+
'[' . htmlspecialchars($matches[1]) . ',' . str_replace("\"", "'", join(',', $trArr)) . ']'
440440
);
441441
} else {
442442
$trAttr = ' ' . $this->_getHtmlAttribute(
443443
self::DATA_TRANSLATE,
444-
'[' . join(',', $trArr) . ']'
444+
'[' . str_replace("\"", "'", join(',', $trArr)) . ']'
445445
);
446446
}
447447
$trAttr = $this->_addTranslateAttribute($trAttr);
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Translation\Test\Unit\Model\Inline;
7+
8+
/**
9+
* Class ParserTest to test \Magento\Translation\Model\Inline\Parser
10+
*/
11+
class ParserTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* @var \Magento\Translation\Model\Inline\Parser|\PHPUnit_Framework_MockObject_MockObject
15+
*/
16+
private $model;
17+
18+
/**
19+
* @var \Magento\Translation\Model\ResourceModel\StringUtilsFactory|\PHPUnit_Framework_MockObject_MockObject
20+
*/
21+
private $resourceMock;
22+
23+
/**
24+
* @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $storeManagerMock;
27+
28+
/**
29+
* @var \Zend_Filter_Interface|\PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $inputFilterMock;
32+
33+
/**
34+
* @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject
35+
*/
36+
private $appStateMock;
37+
38+
/**
39+
* @var \Magento\Framework\App\Cache\TypeListInterface|\PHPUnit_Framework_MockObject_MockObject
40+
*/
41+
private $appCacheMock;
42+
43+
/**
44+
* @var \Magento\Framework\Translate\InlineInterface|\PHPUnit_Framework_MockObject_MockObject
45+
*/
46+
private $translateInlineMock;
47+
48+
protected function setUp()
49+
{
50+
$this->resourceMock = $this->getMockBuilder('Magento\Translation\Model\ResourceModel\StringUtilsFactory')
51+
->disableOriginalConstructor()
52+
->setMethods([])
53+
->getMock();
54+
55+
$this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
56+
->disableOriginalConstructor()
57+
->setMethods([])
58+
->getMock();
59+
60+
$this->inputFilterMock = $this->getMockBuilder('Zend_Filter_Interface')
61+
->disableOriginalConstructor()
62+
->setMethods([])
63+
->getMock();
64+
65+
$this->appStateMock = $this->getMockBuilder('Magento\Framework\App\State')
66+
->disableOriginalConstructor()
67+
->setMethods([])
68+
->getMock();
69+
70+
$this->appCacheMock = $this->getMockBuilder('Magento\Framework\App\Cache\TypeListInterface')
71+
->disableOriginalConstructor()
72+
->setMethods([])
73+
->getMock();
74+
75+
$this->translateInlineMock= $this->getMockBuilder('Magento\Framework\Translate\InlineInterface')
76+
->disableOriginalConstructor()
77+
->setMethods([])
78+
->getMock();
79+
80+
$objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
81+
$this->model = $objectManagerHelper->getObject(
82+
'Magento\Translation\Model\Inline\Parser',
83+
[
84+
"_resourceFactory" => $this->resourceMock,
85+
"_storeManager" => $this->storeManagerMock,
86+
"_inputFilter" => $this->inputFilterMock,
87+
"_appState" => $this->appStateMock,
88+
"_appCache" => $this->appCacheMock,
89+
"_translateInline" => $this->translateInlineMock
90+
]
91+
);
92+
}
93+
94+
public function testProcessResponseBodyStringProcessingAttributesCorrectly()
95+
{
96+
$testContent = file_get_contents(__DIR__ . '/_files/datatranslate_fixture.html');
97+
$processedAttributes = [
98+
"data-translate=\"[{'shown':'* Required Fields','translated':'* Required Fields',"
99+
. "'original':'* Required Fields','location':'Tag attribute (ALT, TITLE, etc.)'}]\"",
100+
"data-translate=\"[{'shown':'Email','translated':'Email','original':'Email',"
101+
. "'location':'Tag attribute (ALT, TITLE, etc.)'}]\"",
102+
"data-translate=\"[{'shown':'Password','translated':'Password','original':'Password',"
103+
. "'location':'Tag attribute (ALT, TITLE, etc.)'}]\""
104+
];
105+
$this->translateInlineMock->expects($this->any())->method('getAdditionalHtmlAttribute')->willReturn(null);
106+
107+
$processedContent = $this->model->processResponseBodyString($testContent);
108+
foreach ($processedAttributes as $attribute) {
109+
$this->assertContains($attribute, $processedContent, "data-translate attribute not processed correctly");
110+
}
111+
}
112+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<div class="login-container">
2+
<div class="block block-customer-login">
3+
<div class="block-content" aria-labelledby="block-customer-login-heading">
4+
<form class="form form-login"
5+
action=""
6+
method="post"
7+
id="login-form"
8+
data-mage-init='{"validation":{}}'>
9+
<input name="form_key" type="hidden" value="" />
10+
<fieldset class="fieldset login" data-hasrequired="{{{* Required Fields}}{{* Required Fields}}{{* Required Fields}}{{theme3}}}">
11+
<div class="field note">{{{If you have an account, sign in with your email address.}}{{If you have an account, sign in with your email address.}}{{If you have an account, sign in with your email address.}}{{theme3}}}</div>
12+
<div class="field email required">
13+
<label class="label" for="email"><span>{{{Email}}{{Email}}{{Email}}{{theme3}}}</span></label>
14+
<div class="control">
15+
<input name="login[username]" value="" autocomplete="off" id="email" type="email" class="input-text" title="{{{Email}}{{Email}}{{Email}}{{theme3}}}" data-validate="{required:true, 'validate-email':true}">
16+
</div>
17+
</div>
18+
<div class="field password required">
19+
<label for="pass" class="label"><span>{{{Password}}{{Password}}{{Password}}{{theme3}}}</span></label>
20+
<div class="control">
21+
<input name="login[password]" type="password" autocomplete="off" class="input-text" id="pass" title="{{{Password}}{{Password}}{{Password}}{{theme3}}}" data-validate="{required:true}">
22+
</div>
23+
</div>
24+
<div class="actions-toolbar">
25+
<div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span>{{{Sign In}}{{Sign In}}{{Sign In}}{{theme3}}}</span></button></div>
26+
<div class="secondary"><a class="action remind" href=""><span>{{{Forgot Your Password?}}{{Forgot Your Password?}}{{Forgot Your Password?}}{{theme3}}}</span></a></div>
27+
</div>
28+
</fieldset>
29+
</form>
30+
</div>
31+
</div>
32+
</div>

0 commit comments

Comments
 (0)