Skip to content

Commit d66e664

Browse files
committed
Merge pull request #142 from magento-south/BUGS
[SOUTH] Bugfixes
2 parents 180ca97 + 506a60c commit d66e664

File tree

7 files changed

+247
-4
lines changed

7 files changed

+247
-4
lines changed

app/code/Magento/Customer/Model/Checkout/ConfigProvider.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use Magento\Customer\Model\Url;
1010
use Magento\Framework\UrlInterface;
1111
use Magento\Store\Model\StoreManagerInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Customer\Model\Form;
14+
use Magento\Store\Model\ScopeInterface;
1215

1316
class ConfigProvider implements ConfigProviderInterface
1417
{
@@ -22,16 +25,24 @@ class ConfigProvider implements ConfigProviderInterface
2225
*/
2326
protected $urlBuilder;
2427

28+
/**
29+
* @var ScopeConfigInterface
30+
*/
31+
protected $scopeConfig;
32+
2533
/**
2634
* @param UrlInterface $urlBuilder
2735
* @param StoreManagerInterface $storeManager
36+
* @param ScopeConfigInterface $scopeConfig
2837
*/
2938
public function __construct(
3039
UrlInterface $urlBuilder,
31-
StoreManagerInterface $storeManager
40+
StoreManagerInterface $storeManager,
41+
ScopeConfigInterface $scopeConfig
3242
) {
3343
$this->urlBuilder = $urlBuilder;
3444
$this->storeManager = $storeManager;
45+
$this->scopeConfig = $scopeConfig;
3546
}
3647

3748
/**
@@ -42,9 +53,24 @@ public function getConfig()
4253
return [
4354
'customerLoginUrl' => $this->getLoginUrl(),
4455
'isRedirectRequired' => $this->isRedirectRequired(),
56+
'autocomplete' => $this->isAutocompleteEnabled(),
4557
];
4658
}
4759

60+
/**
61+
* Is autocomplete enabled for storefront
62+
*
63+
* @return string
64+
* @codeCoverageIgnore
65+
*/
66+
protected function isAutocompleteEnabled()
67+
{
68+
return $this->scopeConfig->getValue(
69+
Form::XML_PATH_ENABLE_AUTOCOMPLETE,
70+
ScopeInterface::SCOPE_STORE
71+
) ? 'on' : 'off';
72+
}
73+
4874
/**
4975
* Returns URL to login controller action
5076
*
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Customer\Test\Unit\Model\Checkout;
7+
8+
use Magento\Customer\Model\Checkout\ConfigProvider;
9+
use Magento\Framework\UrlInterface;
10+
use Magento\Store\Model\StoreManagerInterface;
11+
use Magento\Store\Api\Data\StoreInterface;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Customer\Model\Url;
14+
use Magento\Customer\Model\Form;
15+
use Magento\Store\Model\ScopeInterface;
16+
17+
class ConfigProviderTest extends \PHPUnit_Framework_TestCase
18+
{
19+
/**
20+
* @var ConfigProvider
21+
*/
22+
protected $provider;
23+
24+
/**
25+
* @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
protected $storeManager;
28+
29+
/**
30+
* @var UrlInterface|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
protected $urlBuilder;
33+
34+
/**
35+
* @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
protected $scopeConfig;
38+
39+
/**
40+
* @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject
41+
*/
42+
protected $store;
43+
44+
public function setUp()
45+
{
46+
$this->storeManager = $this->getMockForAbstractClass(
47+
'Magento\Store\Model\StoreManagerInterface',
48+
[],
49+
'',
50+
false
51+
);
52+
$this->urlBuilder = $this->getMockForAbstractClass(
53+
'Magento\Framework\UrlInterface',
54+
[],
55+
'',
56+
false
57+
);
58+
$this->scopeConfig = $this->getMockForAbstractClass(
59+
'Magento\Framework\App\Config\ScopeConfigInterface',
60+
[],
61+
'',
62+
false
63+
);
64+
$this->store = $this->getMockForAbstractClass(
65+
'Magento\Store\Api\Data\StoreInterface',
66+
[],
67+
'',
68+
false,
69+
false,
70+
true,
71+
['getBaseUrl']
72+
);
73+
74+
$this->provider = new ConfigProvider(
75+
$this->urlBuilder,
76+
$this->storeManager,
77+
$this->scopeConfig
78+
);
79+
}
80+
81+
public function testGetConfigWithoutRedirect()
82+
{
83+
$loginUrl = 'http://url.test/customer/login';
84+
$baseUrl = 'http://base-url.test';
85+
86+
$this->urlBuilder->expects($this->exactly(2))
87+
->method('getUrl')
88+
->with(Url::ROUTE_ACCOUNT_LOGIN)
89+
->willReturn($loginUrl);
90+
$this->storeManager->expects($this->once())
91+
->method('getStore')
92+
->willReturn($this->store);
93+
$this->store->expects($this->once())
94+
->method('getBaseUrl')
95+
->willReturn($baseUrl);
96+
$this->scopeConfig->expects($this->once())
97+
->method('getValue')
98+
->with(Form::XML_PATH_ENABLE_AUTOCOMPLETE, ScopeInterface::SCOPE_STORE)
99+
->willReturn(1);
100+
$this->assertEquals(
101+
[
102+
'customerLoginUrl' => $loginUrl,
103+
'isRedirectRequired' => true,
104+
'autocomplete' => 'on',
105+
],
106+
$this->provider->getConfig()
107+
);
108+
}
109+
110+
public function testGetConfig()
111+
{
112+
$loginUrl = 'http://base-url.test/customer/login';
113+
$baseUrl = 'http://base-url.test';
114+
115+
$this->urlBuilder->expects($this->exactly(2))
116+
->method('getUrl')
117+
->with(Url::ROUTE_ACCOUNT_LOGIN)
118+
->willReturn($loginUrl);
119+
$this->storeManager->expects($this->once())
120+
->method('getStore')
121+
->willReturn($this->store);
122+
$this->store->expects($this->once())
123+
->method('getBaseUrl')
124+
->willReturn($baseUrl);
125+
$this->scopeConfig->expects($this->once())
126+
->method('getValue')
127+
->with(Form::XML_PATH_ENABLE_AUTOCOMPLETE, ScopeInterface::SCOPE_STORE)
128+
->willReturn(0);
129+
$this->assertEquals(
130+
[
131+
'customerLoginUrl' => $loginUrl,
132+
'isRedirectRequired' => false,
133+
'autocomplete' => 'off',
134+
],
135+
$this->provider->getConfig()
136+
);
137+
}
138+
}

app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ define(
2222
return Component.extend({
2323
registerUrl: window.authenticationPopup.customerRegisterUrl,
2424
forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,
25+
autocomplete: window.checkout.autocomplete,
2526
modalWindow: null,
2627
isLoading: ko.observable(false),
2728

app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
id="email"
6161
type="email"
6262
class="input-text"
63+
data-bind="attr: {autocomplete: autocomplete}"
6364
data-validate="{required:true, 'validate-email':true}">
6465
</div>
6566
</div>
@@ -70,6 +71,7 @@
7071
type="password"
7172
class="input-text"
7273
id="pass"
74+
data-bind="attr: {autocomplete: autocomplete}"
7375
data-validate="{required:true, 'validate-password':true}">
7476
</div>
7577
</div>

app/code/Magento/Swatches/Model/Plugin/EavAttribute.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
99
use Magento\Swatches\Model\Swatch;
10+
use Magento\Framework\Exception\InputException;
1011

1112
/**
1213
* Plugin model for Catalog Resource Attribute
@@ -72,13 +73,29 @@ public function __construct(
7273
*/
7374
public function beforeSave(Attribute $attribute)
7475
{
75-
if ($this->swatchHelper->isSwatchAttribute($attribute)) {
76+
if ($this->swatchHelper->isSwatchAttribute($attribute) && $this->validateOptions($attribute)) {
7677
$this->setProperOptionsArray($attribute);
7778
$this->swatchHelper->assembleAdditionalDataEavAttribute($attribute);
7879
}
7980
$this->convertSwatchToDropdown($attribute);
8081
}
8182

83+
/**
84+
* Validate that attribute options exist
85+
*
86+
* @param Attribute $attribute
87+
* @return bool
88+
* @throws InputException
89+
*/
90+
protected function validateOptions(Attribute $attribute)
91+
{
92+
$attributeSavedOptions = $attribute->getSource()->getAllOptions(false);
93+
if (!count($attributeSavedOptions)) {
94+
throw new InputException(__('Admin is a required field in the each row'));
95+
}
96+
return true;
97+
}
98+
8299
/**
83100
* Swatch save operations
84101
*

app/code/Magento/Swatches/Test/Unit/Model/Plugin/EavAttributeTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class EavAttributeTest extends \PHPUnit_Framework_TestCase
5454
/** @var array */
5555
private $dependencyArray = [];
5656

57+
/** @var \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource|\PHPUnit_Framework_MockObject_MockObject */
58+
protected $source;
59+
5760
public function setUp()
5861
{
5962
$this->attribute = $this->getMock('\Magento\Catalog\Model\ResourceModel\Eav\Attribute', [], [], '', false);
@@ -87,6 +90,13 @@ public function setUp()
8790
'swatchHelper' => $this->swatchHelper,
8891
]
8992
);
93+
$this->source = $this->getMockForAbstractClass(
94+
'Magento\Eav\Model\Entity\Attribute\Source\AbstractSource',
95+
[],
96+
'',
97+
false
98+
);
99+
90100

91101
$this->optionIds = [
92102
'value' => ['option 89' => 'test 1', 'option 114' => 'test 2', 'option 170' => 'test 3'],
@@ -117,6 +127,19 @@ public function testBeforeSaveVisualSwatch()
117127
['swatch', self::ATTRIBUTE_SWATCH_VALUE]
118128
);
119129

130+
$this->attribute->expects($this->once())
131+
->method('getSource')
132+
->willReturn($this->source);
133+
$this->source->expects($this->once())
134+
->method('getAllOptions')
135+
->with(false)
136+
->willReturn([
137+
[
138+
'value' => 'value',
139+
'label' => 'label'
140+
]
141+
]);
142+
120143
$this->swatchHelper->expects($this->once())->method('assembleAdditionalDataEavAttribute')
121144
->with($this->attribute);
122145
$this->swatchHelper->expects($this->once())->method('isVisualSwatch')
@@ -153,6 +176,19 @@ public function testBeforeSaveTextSwatch()
153176
['swatch', self::ATTRIBUTE_SWATCH_VALUE]
154177
);
155178

179+
$this->attribute->expects($this->once())
180+
->method('getSource')
181+
->willReturn($this->source);
182+
$this->source->expects($this->once())
183+
->method('getAllOptions')
184+
->with(false)
185+
->willReturn([
186+
[
187+
'value' => 'value',
188+
'label' => 'label'
189+
]
190+
]);
191+
156192
$this->swatchHelper->expects($this->once())->method('assembleAdditionalDataEavAttribute')
157193
->with($this->attribute);
158194
$this->swatchHelper->expects($this->once())->method('isVisualSwatch')
@@ -168,6 +204,27 @@ public function testBeforeSaveTextSwatch()
168204
$this->eavAttribute->beforeSave($this->attribute);
169205
}
170206

207+
/**
208+
* @expectedException \Magento\Framework\Exception\InputException
209+
* @expectedExceptionMessage Admin is a required field in the each row
210+
*/
211+
public function testBeforeSaveWithFailedValidation()
212+
{
213+
$this->swatchHelper->expects($this->once())->method('isSwatchAttribute')
214+
->with($this->attribute)
215+
->willReturn(true);
216+
217+
$this->attribute->expects($this->once())
218+
->method('getSource')
219+
->willReturn($this->source);
220+
$this->source->expects($this->once())
221+
->method('getAllOptions')
222+
->with(false)
223+
->willReturn([]);
224+
225+
$this->eavAttribute->beforeSave($this->attribute);
226+
}
227+
171228
public function testBeforeSaveNotSwatch()
172229
{
173230
$additionalData = [

app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ define([
1111

1212
$.widget('mage.addToWishlist', {
1313
options: {
14-
bundleInfo: 'div.control [name^=bundle_option]:not([name*=qty])',
14+
bundleInfo: 'div.control [name^=bundle_option]',
1515
configurableInfo: '.super-attribute-select',
1616
groupedInfo: '#super-product-table input',
1717
downloadableInfo: '#downloadable-links-list input',
@@ -43,10 +43,12 @@ define([
4343
$(event.handleObj.selector).each(function(index, element){
4444
if ($(element).is('input[type=text]')
4545
|| $(element).is('input[type=email]')
46+
|| $(element).is('input[type=number]')
47+
|| $(element).is('input[type=hidden]')
4648
|| $(element).is('input[type=checkbox]:checked')
4749
|| $(element).is('input[type=radio]:checked')
48-
|| $('#' + element.id + ' option:selected').length
4950
|| $(element).is('textarea')
51+
|| $('#' + element.id + ' option:selected').length
5052
) {
5153
dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));
5254
return;

0 commit comments

Comments
 (0)