Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 6c69054

Browse files
author
Alexander Akimov
authored
Merge pull request #2762 from magento-tsg/2.3-develop-pr25
[TSG] Upporting for 2.3 (pr25) (2.3.0)
2 parents 26bac6f + 03f1c9c commit 6c69054

File tree

11 files changed

+514
-24
lines changed

11 files changed

+514
-24
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Attribute.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,19 +141,17 @@ public function deleteEntity(\Magento\Framework\Model\AbstractModel $object)
141141
->getMetadata(ProductInterface::class)
142142
->getLinkField();
143143

144-
$select = $this->getConnection()->select()->from(
145-
$attribute->getEntity()->getEntityTable(),
146-
$linkField
147-
)->where(
148-
'attribute_set_id = ?',
149-
$result['attribute_set_id']
150-
);
144+
$backendLinkField = $attribute->getBackend()->getEntityIdField();
151145

152-
$clearCondition = [
153-
'attribute_id =?' => $attribute->getId(),
154-
$linkField . ' IN (?)' => $select,
155-
];
156-
$this->getConnection()->delete($backendTable, $clearCondition);
146+
$select = $this->getConnection()->select()
147+
->from(['b' => $backendTable])
148+
->join(
149+
['e' => $attribute->getEntity()->getEntityTable()],
150+
"b.$backendLinkField = e.$linkField"
151+
)->where('b.attribute_id = ?', $attribute->getId())
152+
->where('e.attribute_set_id = ?', $result['attribute_set_id']);
153+
154+
$this->getConnection()->query($select->deleteFromSelect('b'));
157155
}
158156
}
159157

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;
10+
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Model\ResourceModel\Attribute;
13+
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
14+
use Magento\Eav\Model\ResourceModel\Entity\Type;
15+
use Magento\Framework\App\ResourceConnection;
16+
use Magento\Framework\EntityManager\EntityMetadataInterface;
17+
use Magento\Framework\Model\ResourceModel\Db\Context;
18+
use Magento\Framework\DB\Adapter\AdapterInterface as Adapter;
19+
use Magento\ResourceConnections\DB\Select;
20+
use Magento\Store\Model\StoreManagerInterface;
21+
use Magento\Catalog\Model\Attribute\LockValidatorInterface;
22+
use Magento\Framework\Model\AbstractModel;
23+
use Magento\Framework\EntityManager\MetadataPool;
24+
25+
/**
26+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
27+
*/
28+
class AttributeTest extends \PHPUnit\Framework\TestCase
29+
{
30+
/**
31+
* @var Select|\PHPUnit_Framework_MockObject_MockObject
32+
*/
33+
private $selectMock;
34+
35+
/**
36+
* @var Adapter|\PHPUnit_Framework_MockObject_MockObject
37+
*/
38+
private $connectionMock;
39+
40+
/**
41+
* @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
42+
*/
43+
private $resourceMock;
44+
45+
/**
46+
* @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
47+
*/
48+
private $storeManagerMock;
49+
50+
/**
51+
* @var Context|\PHPUnit_Framework_MockObject_MockObject
52+
*/
53+
private $contextMock;
54+
55+
/**
56+
* @var \Magento\Eav\Model\ResourceModel\Entity\Type|\PHPUnit_Framework_MockObject_MockObject
57+
*/
58+
private $eavEntityTypeMock;
59+
60+
/**
61+
* @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
62+
*/
63+
private $eavConfigMock;
64+
65+
/**
66+
* @var LockValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
67+
*/
68+
private $lockValidatorMock;
69+
70+
/**
71+
* @var EntityMetadataInterface|\PHPUnit_Framework_MockObject_MockObject
72+
*/
73+
private $entityMetaDataInterfaceMock;
74+
75+
/**
76+
* @inheritDoc
77+
*/
78+
protected function setUp()
79+
{
80+
$this->selectMock = $this->getMockBuilder(Select::class)
81+
->disableOriginalConstructor()
82+
->setMethods(['from', 'where', 'join', 'deleteFromSelect'])
83+
->getMock();
84+
85+
$this->connectionMock = $this->getMockBuilder(Adapter::class)->getMockForAbstractClass();
86+
$this->connectionMock->expects($this->once())->method('select')->willReturn($this->selectMock);
87+
$this->connectionMock->expects($this->once())->method('query')->willReturn($this->selectMock);
88+
$this->connectionMock->expects($this->once())->method('delete')->willReturn($this->selectMock);
89+
$this->selectMock->expects($this->once())->method('from')->willReturnSelf();
90+
$this->selectMock->expects($this->once())->method('join')->willReturnSelf();
91+
$this->selectMock->expects($this->any())->method('where')->willReturnSelf();
92+
$this->selectMock->expects($this->any())->method('deleteFromSelect')->willReturnSelf();
93+
94+
$this->resourceMock = $this->getMockBuilder(ResourceConnection::class)
95+
->disableOriginalConstructor()
96+
->setMethods(['delete', 'getConnection'])
97+
->getMock();
98+
99+
$this->contextMock = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock();
100+
$this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)->getMock();
101+
$this->eavEntityTypeMock = $this->getMockBuilder(Type::class)
102+
->disableOriginalConstructor()
103+
->getMock();
104+
$this->eavConfigMock = $this->getMockBuilder(\Magento\Eav\Model\Config::class)
105+
->disableOriginalConstructor()
106+
->setMethods(['getAttribute'])
107+
->getMock();
108+
$this->lockValidatorMock = $this->getMockBuilder(LockValidatorInterface::class)
109+
->disableOriginalConstructor()
110+
->setMethods(['validate'])
111+
->getMock();
112+
$this->entityMetaDataInterfaceMock = $this->getMockBuilder(EntityMetadataInterface::class)
113+
->disableOriginalConstructor()
114+
->getMock();
115+
}
116+
117+
/**
118+
* Sets object non-public property.
119+
*
120+
* @param mixed $object
121+
* @param string $propertyName
122+
* @param mixed $value
123+
*
124+
* @return void
125+
*/
126+
private function setObjectProperty($object, string $propertyName, $value) : void
127+
{
128+
$reflectionClass = new \ReflectionClass($object);
129+
$reflectionProperty = $reflectionClass->getProperty($propertyName);
130+
$reflectionProperty->setAccessible(true);
131+
$reflectionProperty->setValue($object, $value);
132+
}
133+
134+
/**
135+
* @return void
136+
*/
137+
public function testDeleteEntity() : void
138+
{
139+
$entityAttributeId = 196;
140+
$entityTypeId = 4;
141+
$result = [
142+
'entity_attribute_id' => 196,
143+
'entity_type_id' => 4,
144+
'attribute_set_id'=> 4,
145+
'attribute_group_id' => 7,
146+
'attribute_id' => 177,
147+
'sort_order' => 3,
148+
];
149+
150+
$backendTableName = 'weee_tax';
151+
$backendFieldName = 'value_id';
152+
153+
$attributeModel = $this->getMockBuilder(Attribute::class)
154+
->setMethods(['getEntityAttribute', 'getMetadataPool', 'getConnection', 'getTable'])
155+
->setConstructorArgs([
156+
$this->contextMock,
157+
$this->storeManagerMock,
158+
$this->eavEntityTypeMock,
159+
$this->eavConfigMock,
160+
$this->lockValidatorMock,
161+
null,
162+
])->getMock();
163+
$attributeModel->expects($this->any())
164+
->method('getEntityAttribute')
165+
->with($entityAttributeId)
166+
->willReturn($result);
167+
$metadataPoolMock = $this->getMockBuilder(MetadataPool::class)
168+
->disableOriginalConstructor()
169+
->setMethods(['getMetadata'])
170+
->getMock();
171+
172+
$this->setObjectProperty($attributeModel, 'metadataPool', $metadataPoolMock);
173+
174+
$eavAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
175+
->disableOriginalConstructor()
176+
->getMock();
177+
178+
$eavAttributeMock->expects($this->any())->method('getId')->willReturn($result['attribute_id']);
179+
180+
$this->eavConfigMock->expects($this->any())
181+
->method('getAttribute')
182+
->with($entityTypeId, $result['attribute_id'])
183+
->willReturn($eavAttributeMock);
184+
185+
$abstractModelMock = $this->getMockBuilder(AbstractModel::class)
186+
->disableOriginalConstructor()
187+
->setMethods(['getEntityAttributeId','getEntityTypeId'])
188+
->getMockForAbstractClass();
189+
$abstractModelMock->expects($this->any())->method('getEntityAttributeId')->willReturn($entityAttributeId);
190+
$abstractModelMock->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId);
191+
192+
$this->lockValidatorMock->expects($this->any())
193+
->method('validate')
194+
->with($eavAttributeMock, $result['attribute_set_id'])
195+
->willReturn(true);
196+
197+
$backendModelMock = $this->getMockBuilder(AbstractBackend::class)
198+
->disableOriginalConstructor()
199+
->setMethods(['getBackend', 'getTable', 'getEntityIdField'])
200+
->getMock();
201+
202+
$abstractAttributeMock = $this->getMockBuilder(AbstractAttribute::class)
203+
->disableOriginalConstructor()
204+
->setMethods(['getEntity'])
205+
->getMockForAbstractClass();
206+
207+
$eavAttributeMock->expects($this->any())->method('getBackend')->willReturn($backendModelMock);
208+
$eavAttributeMock->expects($this->any())->method('getEntity')->willReturn($abstractAttributeMock);
209+
210+
$backendModelMock->expects($this->any())->method('getTable')->willReturn($backendTableName);
211+
$backendModelMock->expects($this->once())->method('getEntityIdField')->willReturn($backendFieldName);
212+
213+
$metadataPoolMock->expects($this->any())
214+
->method('getMetadata')
215+
->with(ProductInterface::class)
216+
->willReturn($this->entityMetaDataInterfaceMock);
217+
218+
$this->entityMetaDataInterfaceMock->expects($this->any())
219+
->method('getLinkField')
220+
->willReturn('row_id');
221+
222+
$attributeModel->expects($this->any())->method('getConnection')->willReturn($this->connectionMock);
223+
$attributeModel->expects($this->any())
224+
->method('getTable')
225+
->with('eav_entity_attribute')
226+
->willReturn('eav_entity_attribute');
227+
228+
$attributeModel->deleteEntity($abstractModelMock);
229+
}
230+
}

app/code/Magento/Customer/Model/Address/Validator/Country.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
use Magento\Customer\Model\Address\AbstractAddress;
99
use Magento\Customer\Model\Address\ValidatorInterface;
10+
use Magento\Framework\App\ObjectManager;
11+
use Magento\Store\Model\ScopeInterface;
1012

1113
/**
1214
* Address country and region validator.
@@ -18,13 +20,31 @@ class Country implements ValidatorInterface
1820
*/
1921
private $directoryData;
2022

23+
/**
24+
* @var \Magento\Directory\Model\AllowedCountries
25+
*/
26+
private $allowedCountriesReader;
27+
28+
/**
29+
* @var \Magento\Customer\Model\Config\Share
30+
*/
31+
private $shareConfig;
32+
2133
/**
2234
* @param \Magento\Directory\Helper\Data $directoryData
35+
* @param \Magento\Directory\Model\AllowedCountries|null $allowedCountriesReader
36+
* @param \Magento\Customer\Model\Config\Share|null $shareConfig
2337
*/
2438
public function __construct(
25-
\Magento\Directory\Helper\Data $directoryData
39+
\Magento\Directory\Helper\Data $directoryData,
40+
\Magento\Directory\Model\AllowedCountries $allowedCountriesReader = null,
41+
\Magento\Customer\Model\Config\Share $shareConfig = null
2642
) {
2743
$this->directoryData = $directoryData;
44+
$this->allowedCountriesReader = $allowedCountriesReader
45+
?: ObjectManager::getInstance()->get(\Magento\Directory\Model\AllowedCountries::class);
46+
$this->shareConfig = $shareConfig
47+
?: ObjectManager::getInstance()->get(\Magento\Customer\Model\Config\Share::class);
2848
}
2949

3050
/**
@@ -52,7 +72,7 @@ private function validateCountry(AbstractAddress $address)
5272
$errors = [];
5373
if (!\Zend_Validate::is($countryId, 'NotEmpty')) {
5474
$errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'countryId']);
55-
} elseif (!in_array($countryId, $this->directoryData->getCountryCollection()->getAllIds(), true)) {
75+
} elseif (!in_array($countryId, $this->getWebsiteAllowedCountries($address), true)) {
5676
//Checking if such country exists.
5777
$errors[] = __(
5878
'Invalid value of "%value" provided for the %fieldName field.',
@@ -97,4 +117,21 @@ private function validateRegion(AbstractAddress $address)
97117

98118
return $errors;
99119
}
120+
121+
/**
122+
* Return allowed counties per website.
123+
*
124+
* @param AbstractAddress $address
125+
* @return array
126+
*/
127+
private function getWebsiteAllowedCountries(AbstractAddress $address): array
128+
{
129+
$websiteId = null;
130+
131+
if (!$this->shareConfig->isGlobalScope()) {
132+
$websiteId = $address->getCustomer() ? $address->getCustomer()->getWebsiteId() : null;
133+
}
134+
135+
return $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_WEBSITE, $websiteId);
136+
}
100137
}

app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\Customer\Test\Unit\Model\Address\Validator;
88

9+
use Magento\Store\Model\ScopeInterface;
10+
911
/**
1012
* Magento\Customer\Model\Address\Validator\Country tests.
1113
*/
@@ -20,14 +22,34 @@ class CountryTest extends \PHPUnit\Framework\TestCase
2022
/** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
2123
private $objectManager;
2224

25+
/**
26+
* @var \Magento\Directory\Model\AllowedCountries|\PHPUnit_Framework_MockObject_MockObject
27+
*/
28+
private $allowedCountriesReaderMock;
29+
30+
/**
31+
* @var \Magento\Customer\Model\Config\Share|\PHPUnit_Framework_MockObject_MockObject
32+
*/
33+
private $shareConfigMock;
34+
2335
protected function setUp()
2436
{
2537
$this->directoryDataMock = $this->createMock(\Magento\Directory\Helper\Data::class);
2638
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
39+
$this->allowedCountriesReaderMock = $this->createPartialMock(
40+
\Magento\Directory\Model\AllowedCountries::class,
41+
['getAllowedCountries']
42+
);
43+
$this->shareConfigMock = $this->createPartialMock(
44+
\Magento\Customer\Model\Config\Share::class,
45+
['isGlobalScope']
46+
);
2747
$this->model = $this->objectManager->getObject(
2848
\Magento\Customer\Model\Address\Validator\Country::class,
2949
[
3050
'directoryData' => $this->directoryDataMock,
51+
'allowedCountriesReader' => $this->allowedCountriesReaderMock,
52+
'shareConfig' => $this->shareConfigMock,
3153
]
3254
);
3355
}
@@ -59,16 +81,11 @@ public function testValidate(array $data, array $countryIds, array $allowedRegio
5981
->method('isRegionRequired')
6082
->willReturn($data['regionRequired']);
6183

62-
$countryCollectionMock = $this->getMockBuilder(\Magento\Directory\Model\ResourceModel\Country\Collection::class)
63-
->disableOriginalConstructor()
64-
->setMethods(['getAllIds'])
65-
->getMock();
66-
67-
$this->directoryDataMock->expects($this->any())
68-
->method('getCountryCollection')
69-
->willReturn($countryCollectionMock);
70-
71-
$countryCollectionMock->expects($this->any())->method('getAllIds')->willReturn($countryIds);
84+
$this->shareConfigMock->method('isGlobalScope')->willReturn(false);
85+
$this->allowedCountriesReaderMock
86+
->method('getAllowedCountries')
87+
->with(ScopeInterface::SCOPE_WEBSITE, null)
88+
->willReturn($countryIds);
7289

7390
$addressMock->method('getCountryId')->willReturn($data['country_id']);
7491

0 commit comments

Comments
 (0)