diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php
index 4576e3b033df8..15acb1859ec87 100644
--- a/app/code/Magento/Braintree/Controller/Paypal/Review.php
+++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php
@@ -11,6 +11,7 @@
use Magento\Braintree\Gateway\Config\PayPal\Config;
use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater;
use Magento\Framework\Exception\LocalizedException;
+use Magento\Payment\Model\Method\Logger;
/**
* Class Review
@@ -22,6 +23,11 @@ class Review extends AbstractAction
*/
private $quoteUpdater;
+ /**
+ * @var Logger
+ */
+ private $logger;
+
/**
* @var string
*/
@@ -34,15 +40,18 @@ class Review extends AbstractAction
* @param Config $config
* @param Session $checkoutSession
* @param QuoteUpdater $quoteUpdater
+ * @param Logger $logger
*/
public function __construct(
Context $context,
Config $config,
Session $checkoutSession,
- QuoteUpdater $quoteUpdater
+ QuoteUpdater $quoteUpdater,
+ Logger $logger
) {
parent::__construct($context, $config, $checkoutSession);
$this->quoteUpdater = $quoteUpdater;
+ $this->logger = $logger;
}
/**
@@ -54,6 +63,7 @@ public function execute()
$this->getRequest()->getPostValue('result', '{}'),
true
);
+ $this->logger->debug($requestData);
$quote = $this->checkoutSession->getQuote();
try {
diff --git a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php
index aa23fa767d1ed..ae2b1b1423640 100644
--- a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php
+++ b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php
@@ -123,8 +123,8 @@ private function updateShippingAddress(Quote $quote, array $details)
{
$shippingAddress = $quote->getShippingAddress();
- $shippingAddress->setLastname($details['lastName']);
- $shippingAddress->setFirstname($details['firstName']);
+ $shippingAddress->setLastname($this->getShippingRecipientLastName($details));
+ $shippingAddress->setFirstname($this->getShippingRecipientFirstName($details));
$shippingAddress->setEmail($details['email']);
$shippingAddress->setCollectShippingRates(true);
@@ -188,4 +188,30 @@ private function updateAddressData(Address $address, array $addressData)
$address->setSameAsBilling(false);
$address->setCustomerAddressId(null);
}
+
+ /**
+ * Returns shipping recipient first name.
+ *
+ * @param array $details
+ * @return string
+ */
+ private function getShippingRecipientFirstName(array $details)
+ {
+ return isset($details['shippingAddress']['recipientName'])
+ ? explode(' ', $details['shippingAddress']['recipientName'], 2)[0]
+ : $details['firstName'];
+ }
+
+ /**
+ * Returns shipping recipient last name.
+ *
+ * @param array $details
+ * @return string
+ */
+ private function getShippingRecipientLastName(array $details)
+ {
+ return isset($details['shippingAddress']['recipientName'])
+ ? explode(' ', $details['shippingAddress']['recipientName'], 2)[1]
+ : $details['lastName'];
+ }
}
diff --git a/app/code/Magento/Braintree/Test/Unit/Controller/Paypal/ReviewTest.php b/app/code/Magento/Braintree/Test/Unit/Controller/Paypal/ReviewTest.php
index cb911a8396b36..cc79b5b008e6e 100644
--- a/app/code/Magento/Braintree/Test/Unit/Controller/Paypal/ReviewTest.php
+++ b/app/code/Magento/Braintree/Test/Unit/Controller/Paypal/ReviewTest.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Braintree\Test\Unit\Controller\Paypal;
+use Magento\Payment\Model\Method\Logger;
use Magento\Quote\Model\Quote;
use Magento\Framework\View\Layout;
use Magento\Checkout\Model\Session;
@@ -63,6 +64,14 @@ class ReviewTest extends \PHPUnit\Framework\TestCase
* @var Review
*/
private $review;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+
+ /**
+ * @var Logger|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $loggerMock;
protected function setUp()
{
@@ -87,6 +96,9 @@ protected function setUp()
->getMock();
$this->messageManagerMock = $this->getMockBuilder(ManagerInterface::class)
->getMockForAbstractClass();
+ $this->loggerMock = $this->getMockBuilder(Logger::class)
+ ->disableOriginalConstructor()
+ ->getMock();
$contextMock->expects(self::once())
->method('getRequest')
@@ -102,7 +114,8 @@ protected function setUp()
$contextMock,
$this->configMock,
$this->checkoutSessionMock,
- $this->quoteUpdaterMock
+ $this->quoteUpdaterMock,
+ $this->loggerMock
);
}
diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php
index 7475d81a56142..b67f7d09941ca 100644
--- a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php
+++ b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php
@@ -165,7 +165,7 @@ private function getDetails(): array
'region' => 'IL',
'postalCode' => '60618',
'countryCodeAlpha2' => 'US',
- 'recipientName' => 'John Doe',
+ 'recipientName' => 'Jane Smith',
],
'billingAddress' => [
'streetAddress' => '123 Billing Street',
@@ -186,9 +186,9 @@ private function getDetails(): array
private function updateShippingAddressStep(array $details)
{
$this->shippingAddress->method('setLastname')
- ->with($details['lastName']);
+ ->with('Smith');
$this->shippingAddress->method('setFirstname')
- ->with($details['firstName']);
+ ->with('Jane');
$this->shippingAddress->method('setEmail')
->with($details['email']);
$this->shippingAddress->method('setCollectShippingRates')
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
index cc3dda6e2d7b1..e741070547163 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
@@ -155,38 +155,4 @@ public function modifyMetaLockedDataProvider()
{
return [[true], [false]];
}
-
- public function testModifyMetaWithCaching()
- {
- $this->arrayManagerMock->expects($this->exactly(2))
- ->method('findPath')
- ->willReturn(true);
- $cacheManager = $this->getMockBuilder(CacheInterface::class)
- ->getMockForAbstractClass();
- $cacheManager->expects($this->once())
- ->method('load')
- ->with(Categories::CATEGORY_TREE_ID . '_');
- $cacheManager->expects($this->once())
- ->method('save');
-
- $modifier = $this->createModel();
- $cacheContextProperty = new \ReflectionProperty(
- Categories::class,
- 'cacheManager'
- );
- $cacheContextProperty->setAccessible(true);
- $cacheContextProperty->setValue($modifier, $cacheManager);
-
- $groupCode = 'test_group_code';
- $meta = [
- $groupCode => [
- 'children' => [
- 'category_ids' => [
- 'sortOrder' => 10,
- ],
- ],
- ],
- ];
- $modifier->modifyMeta($meta);
- }
}
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
index 2dad7e8495b11..a3baf7b14a229 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
@@ -3,6 +3,8 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
@@ -11,6 +13,7 @@
use Magento\Framework\App\CacheInterface;
use Magento\Framework\DB\Helper as DbHelper;
use Magento\Catalog\Model\Category as CategoryModel;
+use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\UrlInterface;
use Magento\Framework\Stdlib\ArrayManager;
@@ -202,6 +205,7 @@ protected function createNewCategoryModal(array $meta)
*
* @param array $meta
* @return array
+ * @throws LocalizedException
* @since 101.0.0
*/
protected function customizeCategoriesField(array $meta)
@@ -306,20 +310,64 @@ protected function customizeCategoriesField(array $meta)
*
* @param string|null $filter
* @return array
+ * @throws LocalizedException
* @since 101.0.0
*/
protected function getCategoriesTree($filter = null)
{
- $categoryTree = $this->getCacheManager()->load(self::CATEGORY_TREE_ID . '_' . $filter);
- if ($categoryTree) {
- return $this->serializer->unserialize($categoryTree);
+ $storeId = (int) $this->locator->getStore()->getId();
+
+ $cachedCategoriesTree = $this->getCacheManager()
+ ->load($this->getCategoriesTreeCacheId($storeId, (string) $filter));
+ if (!empty($cachedCategoriesTree)) {
+ return $this->serializer->unserialize($cachedCategoriesTree);
}
- $storeId = $this->locator->getStore()->getId();
+ $categoriesTree = $this->retrieveCategoriesTree(
+ $storeId,
+ $this->retrieveShownCategoriesIds($storeId, (string) $filter)
+ );
+
+ $this->getCacheManager()->save(
+ $this->serializer->serialize($categoriesTree),
+ $this->getCategoriesTreeCacheId($storeId, (string) $filter),
+ [
+ \Magento\Catalog\Model\Category::CACHE_TAG,
+ \Magento\Framework\App\Cache\Type\Block::CACHE_TAG
+ ]
+ );
+
+ return $categoriesTree;
+ }
+
+ /**
+ * Get cache id for categories tree.
+ *
+ * @param int $storeId
+ * @param string $filter
+ * @return string
+ */
+ private function getCategoriesTreeCacheId(int $storeId, string $filter = '') : string
+ {
+ return self::CATEGORY_TREE_ID
+ . '_' . (string) $storeId
+ . '_' . $filter;
+ }
+
+ /**
+ * Retrieve filtered list of categories id.
+ *
+ * @param int $storeId
+ * @param string $filter
+ * @return array
+ * @throws LocalizedException
+ */
+ private function retrieveShownCategoriesIds(int $storeId, string $filter = '') : array
+ {
/* @var $matchingNamesCollection \Magento\Catalog\Model\ResourceModel\Category\Collection */
$matchingNamesCollection = $this->categoryCollectionFactory->create();
- if ($filter !== null) {
+ if (!empty($filter)) {
$matchingNamesCollection->addAttributeToFilter(
'name',
['like' => $this->dbHelper->addLikeEscape($filter, ['position' => 'any'])]
@@ -339,6 +387,19 @@ protected function getCategoriesTree($filter = null)
}
}
+ return $shownCategoriesIds;
+ }
+
+ /**
+ * Retrieve tree of categories with attributes.
+ *
+ * @param int $storeId
+ * @param array $shownCategoriesIds
+ * @return array|null
+ * @throws LocalizedException
+ */
+ private function retrieveCategoriesTree(int $storeId, array $shownCategoriesIds)
+ {
/* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
$collection = $this->categoryCollectionFactory->create();
@@ -365,15 +426,6 @@ protected function getCategoriesTree($filter = null)
$categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
}
- $this->getCacheManager()->save(
- $this->serializer->serialize($categoryById[CategoryModel::TREE_ROOT_ID]['optgroup']),
- self::CATEGORY_TREE_ID . '_' . $filter,
- [
- \Magento\Catalog\Model\Category::CACHE_TAG,
- \Magento\Framework\App\Cache\Type\Block::CACHE_TAG
- ]
- );
-
return $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
}
}
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 9cb6d4bd2390d..d37b755e8c57a 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -2838,7 +2838,8 @@ protected function getProductUrlSuffix($storeId = null)
protected function getUrlKey($rowData)
{
if (!empty($rowData[self::URL_KEY])) {
- return $this->productUrl->formatUrlKey($rowData[self::URL_KEY]);
+ $urlKey = (string) $rowData[self::URL_KEY];
+ return trim(strtolower($urlKey));
}
if (!empty($rowData[self::COL_NAME])) {
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php
index 64f032f2d16e9..3e858e96500c5 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php
@@ -3,9 +3,16 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\CatalogUrlRewrite\Model;
-use Magento\Store\Model\Store;
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
class ProductUrlPathGenerator
{
@@ -19,36 +26,36 @@ class ProductUrlPathGenerator
protected $productUrlSuffix = [];
/**
- * @var \Magento\Store\Model\StoreManagerInterface
+ * @var StoreManagerInterface
*/
protected $storeManager;
/**
- * @var \Magento\Framework\App\Config\ScopeConfigInterface
+ * @var ScopeConfigInterface
*/
protected $scopeConfig;
/**
- * @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator
+ * @var CategoryUrlPathGenerator
*/
protected $categoryUrlPathGenerator;
/**
- * @var \Magento\Catalog\Api\ProductRepositoryInterface
+ * @var ProductRepositoryInterface
*/
protected $productRepository;
/**
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+ * @param StoreManagerInterface $storeManager
+ * @param ScopeConfigInterface $scopeConfig
* @param CategoryUrlPathGenerator $categoryUrlPathGenerator
- * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
+ * @param ProductRepositoryInterface $productRepository
*/
public function __construct(
- \Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
- \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
- \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
+ StoreManagerInterface $storeManager,
+ ScopeConfigInterface $scopeConfig,
+ CategoryUrlPathGenerator $categoryUrlPathGenerator,
+ ProductRepositoryInterface $productRepository
) {
$this->storeManager = $storeManager;
$this->scopeConfig = $scopeConfig;
@@ -59,8 +66,8 @@ public function __construct(
/**
* Retrieve Product Url path (with category if exists)
*
- * @param \Magento\Catalog\Model\Product $product
- * @param \Magento\Catalog\Model\Category $category
+ * @param Product $product
+ * @param Category $category
*
* @return string
*/
@@ -80,10 +87,10 @@ public function getUrlPath($product, $category = null)
/**
* Prepare URL Key with stored product data (fallback for "Use Default Value" logic)
*
- * @param \Magento\Catalog\Model\Product $product
+ * @param Product $product
* @return string
*/
- protected function prepareProductDefaultUrlKey(\Magento\Catalog\Model\Product $product)
+ protected function prepareProductDefaultUrlKey(Product $product)
{
$storedProduct = $this->productRepository->getById($product->getId());
$storedUrlKey = $storedProduct->getUrlKey();
@@ -93,9 +100,9 @@ protected function prepareProductDefaultUrlKey(\Magento\Catalog\Model\Product $p
/**
* Retrieve Product Url path with suffix
*
- * @param \Magento\Catalog\Model\Product $product
+ * @param Product $product
* @param int $storeId
- * @param \Magento\Catalog\Model\Category $category
+ * @param Category $category
* @return string
*/
public function getUrlPathWithSuffix($product, $storeId, $category = null)
@@ -106,8 +113,8 @@ public function getUrlPathWithSuffix($product, $storeId, $category = null)
/**
* Get canonical product url path
*
- * @param \Magento\Catalog\Model\Product $product
- * @param \Magento\Catalog\Model\Category|null $category
+ * @param Product $product
+ * @param Category|null $category
* @return string
*/
public function getCanonicalUrlPath($product, $category = null)
@@ -119,7 +126,7 @@ public function getCanonicalUrlPath($product, $category = null)
/**
* Generate product url key based on url_key entered by merchant or product name
*
- * @param \Magento\Catalog\Model\Product $product
+ * @param Product $product
* @return string|null
*/
public function getUrlKey($product)
@@ -131,13 +138,15 @@ public function getUrlKey($product)
/**
* Prepare url key for product
*
- * @param \Magento\Catalog\Model\Product $product
+ * @param Product $product
* @return string
*/
- protected function prepareProductUrlKey(\Magento\Catalog\Model\Product $product)
+ protected function prepareProductUrlKey(Product $product)
{
- $urlKey = $product->getUrlKey();
- return $product->formatUrlKey($urlKey === '' || $urlKey === null ? $product->getName() : $urlKey);
+ $urlKey = (string)$product->getUrlKey();
+ $urlKey = trim(strtolower($urlKey));
+
+ return $urlKey ?: $product->formatUrlKey($product->getName());
}
/**
@@ -155,7 +164,7 @@ protected function getProductUrlSuffix($storeId = null)
if (!isset($this->productUrlSuffix[$storeId])) {
$this->productUrlSuffix[$storeId] = $this->scopeConfig->getValue(
self::XML_PATH_PRODUCT_URL_SUFFIX,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+ ScopeInterface::SCOPE_STORE,
$storeId
);
}
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlPathGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlPathGeneratorTest.php
index 956fe1b88e0ad..14f30eb7607d3 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlPathGeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlPathGeneratorTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
@@ -72,10 +73,11 @@ protected function setUp()
public function getUrlPathDataProvider()
{
return [
- 'path based on url key' => ['url-key', null, 'url-key'],
- 'path based on product name 1' => ['', 'product-name', 'product-name'],
- 'path based on product name 2' => [null, 'product-name', 'product-name'],
- 'path based on product name 3' => [false, 'product-name', 'product-name']
+ 'path based on url key uppercase' => ['Url Key', null, 0, 'url key'],
+ 'path based on url key' => ['url-key', null, 0, 'url-key'],
+ 'path based on product name 1' => ['', 'product-name', 1, 'product-name'],
+ 'path based on product name 2' => [null, 'product-name', 1, 'product-name'],
+ 'path based on product name 3' => [false, 'product-name', 1, 'product-name']
];
}
@@ -83,15 +85,17 @@ public function getUrlPathDataProvider()
* @dataProvider getUrlPathDataProvider
* @param string|null|bool $urlKey
* @param string|null|bool $productName
+ * @param int $formatterCalled
* @param string $result
*/
- public function testGetUrlPath($urlKey, $productName, $result)
+ public function testGetUrlPath($urlKey, $productName, $formatterCalled, $result)
{
$this->product->expects($this->once())->method('getData')->with('url_path')
->will($this->returnValue(null));
$this->product->expects($this->any())->method('getUrlKey')->will($this->returnValue($urlKey));
$this->product->expects($this->any())->method('getName')->will($this->returnValue($productName));
- $this->product->expects($this->once())->method('formatUrlKey')->will($this->returnArgument(0));
+ $this->product->expects($this->exactly($formatterCalled))
+ ->method('formatUrlKey')->will($this->returnArgument(0));
$this->assertEquals($result, $this->productUrlPathGenerator->getUrlPath($this->product, null));
}
diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php
index ce976d3f62c74..9c9f04185477e 100644
--- a/app/code/Magento/Customer/Model/Customer/DataProvider.php
+++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php
@@ -375,45 +375,17 @@ protected function getAttributesMeta(Type $entityType)
return $meta;
}
- /**
- * Check whether the specific attribute can be shown in form: customer registration, customer edit, etc...
- *
- * @param Attribute $customerAttribute
- * @return bool
- */
- private function canShowAttributeInForm(AbstractAttribute $customerAttribute)
- {
- $isRegistration = $this->context->getRequestParam($this->getRequestFieldName()) === null;
-
- if ($customerAttribute->getEntityType()->getEntityTypeCode() === 'customer') {
- return is_array($customerAttribute->getUsedInForms()) &&
- (
- (in_array('customer_account_create', $customerAttribute->getUsedInForms()) && $isRegistration) ||
- (in_array('customer_account_edit', $customerAttribute->getUsedInForms()) && !$isRegistration)
- );
- } else {
- return is_array($customerAttribute->getUsedInForms()) &&
- in_array('customer_address_edit', $customerAttribute->getUsedInForms());
- }
- }
-
/**
* Detect can we show attribute on specific form or not
*
* @param Attribute $customerAttribute
* @return bool
*/
- private function canShowAttribute(AbstractAttribute $customerAttribute)
+ private function canShowAttribute(AbstractAttribute $customerAttribute): bool
{
- $userDefined = (bool) $customerAttribute->getIsUserDefined();
- if (!$userDefined) {
- return $customerAttribute->getIsVisible();
- }
-
- $canShowOnForm = $this->canShowAttributeInForm($customerAttribute);
-
- return ($this->allowToShowHiddenAttributes && $canShowOnForm) ||
- (!$this->allowToShowHiddenAttributes && $canShowOnForm && $customerAttribute->getIsVisible());
+ return $this->allowToShowHiddenAttributes && (bool) $customerAttribute->getIsUserDefined()
+ ? true
+ : (bool) $customerAttribute->getIsVisible();
}
/**
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
index 50c21379054bf..f6a3ecb810aa5 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
@@ -1295,16 +1295,15 @@ public function testGetDataWithVisibleAttributesWithAccountEdit()
$meta = $dataProvider->getMeta();
$this->assertNotEmpty($meta);
- $this->assertEquals($this->getExpectationForVisibleAttributes(false), $meta);
+ $this->assertEquals($this->getExpectationForVisibleAttributes(), $meta);
}
/**
* Retrieve all customer variations of attributes with all variations of visibility
*
- * @param bool $isRegistration
* @return array
*/
- private function getCustomerAttributeExpectations($isRegistration)
+ private function getCustomerAttributeExpectations()
{
return [
self::ATTRIBUTE_CODE . "_1" => [
@@ -1314,7 +1313,7 @@ private function getCustomerAttributeExpectations($isRegistration)
'dataType' => 'frontend_input',
'formElement' => 'frontend_input',
'options' => 'test-options',
- 'visible' => !$isRegistration,
+ 'visible' => true,
'required' => 'is_required',
'label' => __('frontend_label'),
'sortOrder' => 'sort_order',
@@ -1351,7 +1350,7 @@ private function getCustomerAttributeExpectations($isRegistration)
'config' => [
'dataType' => 'frontend_input',
'formElement' => 'frontend_input',
- 'visible' => $isRegistration,
+ 'visible' => true,
'required' => 'is_required',
'label' => __('frontend_label'),
'sortOrder' => 'sort_order',
@@ -1374,7 +1373,7 @@ private function getCustomerAttributeExpectations($isRegistration)
'config' => [
'dataType' => 'frontend_input',
'formElement' => 'frontend_input',
- 'visible' => $isRegistration,
+ 'visible' => true,
'required' => 'is_required',
'label' => __('frontend_label'),
'sortOrder' => 'sort_order',
@@ -1397,14 +1396,13 @@ private function getCustomerAttributeExpectations($isRegistration)
/**
* Retrieve all variations of attributes with all variations of visibility
*
- * @param bool $isRegistration
* @return array
*/
- private function getExpectationForVisibleAttributes($isRegistration = true)
+ private function getExpectationForVisibleAttributes()
{
return [
'customer' => [
- 'children' => $this->getCustomerAttributeExpectations($isRegistration),
+ 'children' => $this->getCustomerAttributeExpectations(),
],
'address' => [
'children' => [
diff --git a/app/code/Magento/Downloadable/Observer/SaveDownloadableOrderItemObserver.php b/app/code/Magento/Downloadable/Observer/SaveDownloadableOrderItemObserver.php
index 64305cfce9b08..4aed7818b5095 100644
--- a/app/code/Magento/Downloadable/Observer/SaveDownloadableOrderItemObserver.php
+++ b/app/code/Magento/Downloadable/Observer/SaveDownloadableOrderItemObserver.php
@@ -92,9 +92,15 @@ public function execute(\Magento\Framework\Event\Observer $observer)
if ($purchasedLink->getId()) {
return $this;
}
+ $storeId = $orderItem->getOrder()->getStoreId();
+ $orderStatusToEnableItem = $this->_scopeConfig->getValue(
+ \Magento\Downloadable\Model\Link\Purchased\Item::XML_PATH_ORDER_ITEM_STATUS,
+ ScopeInterface::SCOPE_STORE,
+ $storeId
+ );
if (!$product) {
$product = $this->_createProductModel()->setStoreId(
- $orderItem->getOrder()->getStoreId()
+ $storeId
)->load(
$orderItem->getProductId()
);
@@ -150,6 +156,8 @@ public function execute(\Magento\Framework\Event\Observer $observer)
)->setNumberOfDownloadsBought(
$numberOfDownloads
)->setStatus(
+ \Magento\Sales\Model\Order\Item::STATUS_PENDING == $orderStatusToEnableItem ?
+ \Magento\Downloadable\Model\Link\Purchased\Item::LINK_STATUS_AVAILABLE :
\Magento\Downloadable\Model\Link\Purchased\Item::LINK_STATUS_PENDING
)->setCreatedAt(
$orderItem->getCreatedAt()
diff --git a/app/code/Magento/Paypal/Model/Payflow/Service/Response/Transaction.php b/app/code/Magento/Paypal/Model/Payflow/Service/Response/Transaction.php
index 06a8a5b680bf4..259f00ec5a9c5 100644
--- a/app/code/Magento/Paypal/Model/Payflow/Service/Response/Transaction.php
+++ b/app/code/Magento/Paypal/Model/Payflow/Service/Response/Transaction.php
@@ -3,9 +3,12 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Paypal\Model\Payflow\Service\Response;
use Magento\Framework\DataObject;
+use Magento\Framework\Intl\DateTimeFactory;
use Magento\Payment\Model\Method\Logger;
use Magento\Paypal\Model\Payflow\Service\Response\Handler\HandlerInterface;
use Magento\Framework\Session\Generic;
@@ -18,6 +21,8 @@
/**
* Class Transaction
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Transaction
{
@@ -51,6 +56,11 @@ class Transaction
*/
private $logger;
+ /**
+ * @var DateTimeFactory
+ */
+ private $dateTimeFactory;
+
/**
* @param Generic $sessionTransparent
* @param CartRepositoryInterface $quoteRepository
@@ -58,6 +68,7 @@ class Transaction
* @param PaymentMethodManagementInterface $paymentManagement
* @param HandlerInterface $errorHandler
* @param Logger $logger
+ * @param DateTimeFactory $dateTimeFactory
*/
public function __construct(
Generic $sessionTransparent,
@@ -65,7 +76,8 @@ public function __construct(
Transparent $transparent,
PaymentMethodManagementInterface $paymentManagement,
HandlerInterface $errorHandler,
- Logger $logger
+ Logger $logger,
+ DateTimeFactory $dateTimeFactory
) {
$this->sessionTransparent = $sessionTransparent;
$this->quoteRepository = $quoteRepository;
@@ -73,6 +85,7 @@ public function __construct(
$this->paymentManagement = $paymentManagement;
$this->errorHandler = $errorHandler;
$this->logger = $logger;
+ $this->dateTimeFactory = $dateTimeFactory;
}
/**
@@ -114,8 +127,45 @@ public function savePaymentInQuote($response)
$payment->setData(OrderPaymentInterface::CC_TYPE, $response->getData(OrderPaymentInterface::CC_TYPE));
$payment->setAdditionalInformation(Payflowpro::PNREF, $response->getData(Payflowpro::PNREF));
+ $expDate = $response->getData('expdate');
+ $expMonth = $this->getCcExpMonth($expDate);
+ $payment->setCcExpMonth($expMonth);
+ $expYear = $this->getCcExpYear($expDate);
+ $payment->setCcExpYear($expYear);
+
$this->errorHandler->handle($payment, $response);
$this->paymentManagement->set($quote->getId(), $payment);
}
+
+ /**
+ * Extracts expiration month from PayPal response expiration date.
+ *
+ * @param string $expDate format {MMYY}
+ * @return int
+ */
+ private function getCcExpMonth(string $expDate): int
+ {
+ return (int)substr($expDate, 0, 2);
+ }
+
+ /**
+ * Extracts expiration year from PayPal response expiration date.
+ *
+ * @param string $expDate format {MMYY}
+ * @return int
+ */
+ private function getCcExpYear(string $expDate): int
+ {
+ $last2YearDigits = (int)substr($expDate, 2, 2);
+ $currentDate = $this->dateTimeFactory->create('now', new \DateTimeZone('UTC'));
+ $first2YearDigits = (int)substr($currentDate->format('Y'), 0, 2);
+
+ // case when credit card expires at next century
+ if ((int)$currentDate->format('y') > $last2YearDigits) {
+ $first2YearDigits++;
+ }
+
+ return 100 * $first2YearDigits + $last2YearDigits;
+ }
}
diff --git a/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php b/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php
index b3d761b378d94..e0468f17e587a 100644
--- a/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php
+++ b/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php
@@ -83,11 +83,21 @@ public function addWebsiteFilter($websiteId)
if ($website instanceof \Magento\Store\Model\Website) {
$websiteIds[$index] = $website->getId();
}
+ $websiteIds[$index] = (int) $websiteIds[$index];
}
+
+ $websiteSelect = $this->getConnection()->select();
+ $websiteSelect->from(
+ $this->getTable($entityInfo['associations_table']),
+ [$entityInfo['rule_id_field']]
+ )->distinct(
+ true
+ )->where(
+ $this->getConnection()->quoteInto($entityInfo['entity_id_field'] . ' IN (?)', $websiteIds)
+ );
$this->getSelect()->join(
- ['website' => $this->getTable($entityInfo['associations_table'])],
- $this->getConnection()->quoteInto('website.' . $entityInfo['entity_id_field'] . ' IN (?)', $websiteIds)
- . ' AND main_table.' . $entityInfo['rule_id_field'] . ' = website.' . $entityInfo['rule_id_field'],
+ ['website' => $websiteSelect],
+ 'main_table.' . $entityInfo['rule_id_field'] . ' = website.' . $entityInfo['rule_id_field'],
[]
);
}
diff --git a/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php b/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php
deleted file mode 100644
index c4e7a591212c5..0000000000000
--- a/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php
+++ /dev/null
@@ -1,200 +0,0 @@
-_entityFactoryMock = $this->createMock(\Magento\Framework\Data\Collection\EntityFactoryInterface::class);
- $this->_loggerMock = $this->createMock(\Psr\Log\LoggerInterface::class);
- $this->_fetchStrategyMock = $this->createMock(
- \Magento\Framework\Data\Collection\Db\FetchStrategyInterface::class
- );
- $this->_managerMock = $this->createMock(\Magento\Framework\Event\ManagerInterface::class);
- $this->_db = $this->getMockForAbstractClass(
- \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
- [],
- '',
- false,
- false,
- true,
- ['__sleep', '__wakeup', 'getTable']
- );
- $this->objectManagerHelper = new ObjectManagerHelper($this);
- $this->abstractCollection = $this->getMockForAbstractClass(
- \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection::class,
- [
- 'entityFactory' => $this->_entityFactoryMock,
- 'logger' => $this->_loggerMock,
- 'fetchStrategy' => $this->_fetchStrategyMock,
- 'eventManager' => $this->_managerMock,
- null,
- $this->_db
- ],
- '',
- false,
- false,
- true,
- ['__sleep', '__wakeup', '_getAssociatedEntityInfo', 'getConnection', 'getSelect', 'getTable']
- );
- }
-
- /**
- * @return array
- */
- public function addWebsitesToResultDataProvider()
- {
- return [
- [null, true],
- [true, true],
- [false, false]
- ];
- }
-
- /**
- * @dataProvider addWebsitesToResultDataProvider
- */
- public function testAddWebsitesToResult($flag, $expectedResult)
- {
- $this->abstractCollection->addWebsitesToResult($flag);
- $this->assertEquals($expectedResult, $this->abstractCollection->getFlag('add_websites_to_result'));
- }
-
- protected function _prepareAddFilterStubs()
- {
- $entityInfo = [];
- $entityInfo['entity_id_field'] = 'entity_id';
- $entityInfo['rule_id_field'] = 'rule_id';
- $entityInfo['associations_table'] = 'assoc_table';
-
- $connection = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
- $select = $this->createMock(\Magento\Framework\DB\Select::class);
- $collectionSelect = $this->createMock(\Magento\Framework\DB\Select::class);
-
- $connection->expects($this->any())
- ->method('select')
- ->will($this->returnValue($select));
-
- $select->expects($this->any())
- ->method('from')
- ->will($this->returnSelf());
-
- $select->expects($this->any())
- ->method('where')
- ->will($this->returnSelf());
-
- $this->abstractCollection->expects($this->any())
- ->method('getConnection')
- ->will($this->returnValue($connection));
-
- $this->_db->expects($this->any())
- ->method('getTable')
- ->will($this->returnArgument(0));
-
- $this->abstractCollection->expects($this->any())
- ->method('getSelect')
- ->will($this->returnValue($collectionSelect));
-
- $this->abstractCollection->expects($this->any())
- ->method('_getAssociatedEntityInfo')
- ->will($this->returnValue($entityInfo));
- }
-
- public function testAddWebsiteFilter()
- {
- $this->_prepareAddFilterStubs();
- $website = $this->createPartialMock(\Magento\Store\Model\Website::class, ['getId', '__sleep', '__wakeup']);
-
- $website->expects($this->any())
- ->method('getId')
- ->will($this->returnValue(1));
-
- $this->assertInstanceOf(
- \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection::class,
- $this->abstractCollection->addWebsiteFilter($website)
- );
- }
-
- public function testAddWebsiteFilterArray()
- {
- $this->selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
- ->disableOriginalConstructor()
- ->getMockForAbstractClass();
- $this->connectionMock->expects($this->atLeastOnce())
- ->method('quoteInto')
- ->with($this->equalTo('website. IN (?)'), $this->equalTo(['2', '3']))
- ->willReturn(true);
-
- $this->abstractCollection->expects($this->atLeastOnce())->method('getSelect')->willReturn($this->selectMock);
- $this->abstractCollection->expects($this->atLeastOnce())->method('getConnection')
- ->willReturn($this->connectionMock);
-
- $this->assertInstanceOf(
- \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection::class,
- $this->abstractCollection->addWebsiteFilter(['2', '3'])
- );
- }
-
- public function testAddFieldToFilter()
- {
- $this->_prepareAddFilterStubs();
- $result = $this->abstractCollection->addFieldToFilter('website_ids', []);
- $this->assertNotNull($result);
- }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php
new file mode 100644
index 0000000000000..23fd8d7fe324e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php
@@ -0,0 +1,63 @@
+ 1,
+ 'qty' => 100,
+ 'is_qty_decimal' => 0,
+ 'is_in_stock' => 1
+];
+
+/** @var ObjectManagerInterface $objectManager */
+$objectManager = Bootstrap::getObjectManager();
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->create(ProductRepositoryInterface::class);
+
+/** @var ProductInterface $product */
+$product = $objectManager->create(ProductInterface::class);
+$product->setTypeId(Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Чудовий продукт без Url Key')
+ ->setSku('ukrainian-without-url-key')
+ ->setPrice(10)
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setCategoryIds([2])
+ ->setStockData($stockDataConfig);
+try {
+ $productRepository->save($product);
+} catch (\Exception $e) {
+ // problems during save
+};
+
+/** @var ProductInterface $product */
+$product = $objectManager->create(ProductInterface::class);
+$product->setTypeId(Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Надзвичайний продукт з Url Key')
+ ->setSku('ukrainian-with-url-key')
+ ->setPrice(10)
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setCategoryIds([2])
+ ->setStockData($stockDataConfig)
+ ->setUrlKey('надзвичайний продукт на кожен день');
+try {
+ $productRepository->save($product);
+} catch (\Exception $e) {
+ // problems during save
+};
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key_rollback.php
new file mode 100644
index 0000000000000..d4592430c0e94
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key_rollback.php
@@ -0,0 +1,37 @@
+getInstance()->reinitialize();
+
+/** @var Registry $registry */
+$registry = Bootstrap::getObjectManager()->get(Registry::class);
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = Bootstrap::getObjectManager()
+ ->get(ProductRepositoryInterface::class);
+
+$productSkus = [
+ 'ukrainian-with-url-key',
+ 'ukrainian-without-url-key',
+];
+try {
+ foreach ($productSkus as $sku) {
+ $product = $productRepository->get($sku, false, null, true);
+ $productRepository->delete($product);
+ }
+} catch (NoSuchEntityException $e) {
+ // nothing to delete
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index 6e361dfb05de0..cb96910ec86e1 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -28,11 +28,13 @@
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
use Magento\Store\Model\Store;
use Psr\Log\LoggerInterface;
+use Magento\Framework\Exception\NoSuchEntityException;
/**
* Class ProductTest
* @magentoAppIsolation enabled
* @magentoDbIsolation enabled
+ * @magentoAppArea adminhtml
* @magentoDataFixtureBeforeTransaction Magento/Catalog/_files/enable_reindex_schedule.php
* @magentoDataFixtureBeforeTransaction Magento/Catalog/_files/enable_catalog_product_reindex_schedule.php
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -71,6 +73,11 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
*/
private $logger;
+ /**
+ * @var array
+ */
+ private $importedProducts;
+
/**
* @inheritdoc
*/
@@ -84,10 +91,27 @@ protected function setUp()
\Magento\CatalogImportExport\Model\Import\Product::class,
['logger' => $this->logger]
);
+ $this->importedProducts = [];
parent::setUp();
}
+ protected function tearDown()
+ {
+ /* We rollback here the products created during the Import because they were
+ created during test execution and we do not have the rollback for them */
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
+ foreach ($this->importedProducts as $productSku) {
+ try {
+ $product = $productRepository->get($productSku, false, null, true);
+ $productRepository->delete($product);
+ } catch (NoSuchEntityException $e) {
+ // nothing to delete
+ }
+ }
+ }
+
/**
* Options for assertion
*
@@ -271,6 +295,8 @@ public function testStockState()
* @param string $importFile
* @param string $sku
* @param int $expectedOptionsQty
+ * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
* @magentoAppIsolation enabled
*/
public function testSaveCustomOptions($importFile, $sku, $expectedOptionsQty)
@@ -1244,6 +1270,8 @@ public function testProductPositionInCategory()
* @magentoAppIsolation enabled
* @magentoDataFixture Magento/Catalog/_files/category_product.php
* @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testNewProductPositionInCategory()
{
@@ -1369,6 +1397,7 @@ protected function loadCategoryByName($categoryName)
* @dataProvider validateUrlKeysDataProvider
* @param $importFile string
* @param $expectedErrors array
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function testValidateUrlKeys($importFile, $expectedErrors)
{
@@ -1597,12 +1626,13 @@ public function testImportWithoutUrlKeys()
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
* @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function testImportWithUrlKeysWithSpaces()
{
$products = [
- 'simple1' => 'url-key-with-spaces1',
- 'simple2' => 'url-key-with-spaces2',
+ 'simple1' => 'url key with spaces1',
+ 'simple2' => 'url key with spaces2',
];
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
@@ -1629,6 +1659,52 @@ public function testImportWithUrlKeysWithSpaces()
}
}
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_simple_with_non_latin_url_key.php
+ * @magentoDbIsolation disabled
+ * @magentoAppIsolation enabled
+ * @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function testImportWithNonLatinUrlKeys()
+ {
+ $productsCreatedByFixture = [
+ 'ukrainian-with-url-key' => 'nove-im-ja-pislja-importu-scho-stane-url-key',
+ 'ukrainian-without-url-key' => 'новий url key після імпорту',
+ ];
+ $productsImportedByCsv = [
+ 'imported-ukrainian-with-url-key' => 'імпортований продукт',
+ 'imported-ukrainian-without-url-key' => 'importovanij-produkt-bez-url-key',
+ ];
+ $productSkuMap = array_merge($productsCreatedByFixture, $productsImportedByCsv);
+ $this->importedProducts = array_keys($productsImportedByCsv);
+
+ $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
+ $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+ $source = $this->objectManager->create(
+ \Magento\ImportExport\Model\Import\Source\Csv::class,
+ [
+ 'file' => __DIR__ . '/_files/products_to_import_with_non_latin_url_keys.csv',
+ 'directory' => $directory,
+ ]
+ );
+
+ $errors = $this->_model->setParameters(
+ ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
+ )
+ ->setSource($source)
+ ->validateData();
+
+ $this->assertEquals($errors->getErrorsCount(), 0);
+ $this->_model->importData();
+
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
+ foreach ($productSkuMap as $productSku => $productUrlKey) {
+ $this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
+ }
+ }
+
/**
* Make sure the absence of a url_key column in the csv file won't erase the url key of the existing products.
* To reach the goal we need to not send the name column, as the url key is generated from it.
@@ -1844,6 +1920,7 @@ public function testProductWithWrappedAdditionalAttributes()
*
* @param string $fileName
* @param int $expectedErrors
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
private function importDataForMediaTest(string $fileName, int $expectedErrors = 0)
{
@@ -2266,6 +2343,7 @@ public function testImportWithBackordersDisabled()
* Import file by providing import filename in parameters
*
* @param string $fileName
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
private function importFile(string $fileName)
{
@@ -2297,6 +2375,7 @@ private function importFile(string $fileName)
* Import file with non-existing images and skip-errors strategy.
*
* @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function testImportWithSkipErrorsAndNonExistingImage()
{
@@ -2382,6 +2461,7 @@ public function testImportProductWithUpdateUrlKey()
* @magentoDataFixture mediaImportImageFixture
* @magentoAppIsolation enabled
* @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function testSaveProductOnImportNonExistingImage()
{
@@ -2414,6 +2494,8 @@ public function testSaveProductOnImportNonExistingImage()
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
* @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testImportProductWithContinueOnError()
{
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_latin_url_keys.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_latin_url_keys.csv
new file mode 100644
index 0000000000000..8b324a5330779
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_latin_url_keys.csv
@@ -0,0 +1,5 @@
+sku,product_type,store_view_code,name,price,attribute_set_code,url_key
+imported-ukrainian-with-url-key,simple,,"Імпортований продукт з Url Key",50,Default,"імпортований продукт"
+imported-ukrainian-without-url-key,simple,,"Імпортований продукт без Url Key",55,Default,
+ukrainian-without-url-key,simple,,"Чудовий продукт без Url Key",55,Default,"новий url key після імпорту"
+ukrainian-with-url-key,simple,,"Нове ім'я після імпорту що стане url key",55,Default,
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Transparent/ResponseTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Transparent/ResponseTest.php
new file mode 100644
index 0000000000000..e2bb1d7b8f7c6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Transparent/ResponseTest.php
@@ -0,0 +1,135 @@
+ $paypalExpDate,
+ 'AMT' => '0.00',
+ 'RESPMSG' => 'Verified',
+ 'CVV2MATCH' => 'Y',
+ 'PNREF' => 'A10AAD866C87',
+ 'SECURETOKEN' => '3HYEHfG06skydAdBXbpIl8QJZ',
+ 'AVSDATA' => 'YNY',
+ 'RESULT' => '0',
+ 'IAVS' => 'N',
+ 'AVSADDR' => 'Y',
+ 'SECURETOKENID' => 'yqanLisRZbI0HAG8q3SbbKbhiwjNZAGf',
+ ];
+
+ $quote = $this->getQuote($reservedOrderId);
+ $this->getRequest()->setPostValue($postData);
+
+ /** @var Session $checkoutSession */
+ $checkoutSession = $this->_objectManager->get(GenericSession::class);
+ $checkoutSession->setQuoteId($quote->getId());
+ $this->setCurrentDateTime($currentDateTime);
+
+ $this->dispatch('paypal/transparent/response');
+
+ /** @var PaymentMethodManagementInterface $paymentManagment */
+ $paymentManagment = $this->_objectManager->get(PaymentMethodManagementInterface::class);
+ $payment = $paymentManagment->get($quote->getId());
+
+ $this->assertEquals($expectedCcMonth, $payment->getCcExpMonth());
+ $this->assertEquals($expectedCcYear, $payment->getCcExpYear());
+ }
+
+ /**
+ * @return array
+ */
+ public function paymentCcExpirationDateDataProvider(): array
+ {
+ return [
+ 'Expiration year in current century' => [
+ 'currentDateTime' => '2019-07-05 00:00:00',
+ 'paypalExpDate' => '0321',
+ 'expectedCcMonth' => 3,
+ 'expectedCcYear' => 2021
+ ],
+ 'Expiration year in next century' => [
+ 'currentDateTime' => '2099-01-01 00:00:00',
+ 'paypalExpDate' => '1002',
+ 'expectedCcMonth' => 10,
+ 'expectedCcYear' => 2102
+ ]
+ ];
+ }
+
+ /**
+ * Sets current date and time.
+ *
+ * @param string $date
+ */
+ private function setCurrentDateTime(string $dateTime)
+ {
+ $dateTime = new \DateTime($dateTime, new \DateTimeZone('UTC'));
+ $dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dateTimeFactory->method('create')
+ ->willReturn($dateTime);
+
+ $this->_objectManager->addSharedInstance($dateTimeFactory, DateTimeFactory::class);
+ }
+
+ /**
+ * Gets quote by reserved order ID.
+ *
+ * @param string $reservedOrderId
+ * @return CartInterface
+ */
+ private function getQuote(string $reservedOrderId): CartInterface
+ {
+ $searchCriteria = $this->_objectManager->get(SearchCriteriaBuilder::class)
+ ->addFilter('reserved_order_id', $reservedOrderId)
+ ->create();
+
+ /** @var CartRepositoryInterface $quoteRepository */
+ $quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class);
+ $items = $quoteRepository->getList($searchCriteria)
+ ->getItems();
+
+ return array_pop($items);
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php
index f619193d4921f..9ea97b6e939cc 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php
@@ -5,12 +5,39 @@
*/
namespace Magento\SalesRule\Model\ResourceModel\Rule;
+use Magento\Config\Model\Config\Backend\Admin\Custom as AdminBackendConfig;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Store\Api\WebsiteRepositoryInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+use PHPUnit\Framework\TestCase;
+
/**
* @magentoDbIsolation enabled
* @magentoAppIsolation enabled
*/
-class CollectionTest extends \PHPUnit\Framework\TestCase
+class CollectionTest extends TestCase
{
+ /**
+ * @var Collection
+ */
+ private $collection;
+
+ /**
+ * @var string
+ */
+ private $defaultTimezone;
+
+ /**
+ * @inheritDoc
+ */
+ protected function setUp()
+ {
+ $scopeConfig = Bootstrap::getObjectManager()->get(ScopeConfigInterface::class);
+ $this->defaultTimezone = $scopeConfig->getValue(AdminBackendConfig::XML_PATH_GENERAL_LOCALE_TIMEZONE);
+
+ $this->collection = Bootstrap::getObjectManager()->create(Collection::class);
+ }
+
/**
* @magentoDataFixture Magento/SalesRule/_files/rules.php
* @magentoDataFixture Magento/SalesRule/_files/coupons.php
@@ -21,12 +48,8 @@ class CollectionTest extends \PHPUnit\Framework\TestCase
*/
public function testSetValidationFilter($couponCode, $expectedItems)
{
- $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
- $items = array_values($collection->setValidationFilter(1, 0, $couponCode)->getItems());
-
- $ids = [];
+ /** @var \Magento\SalesRule\Model\Rule[] $items */
+ $items = array_values($this->collection->setValidationFilter(1, 0, $couponCode)->getItems());
$this->assertEquals(
count($expectedItems),
@@ -34,6 +57,7 @@ public function testSetValidationFilter($couponCode, $expectedItems)
'Invalid number of items in the result collection'
);
+ $ids = [];
foreach ($items as $key => $item) {
$this->assertEquals($expectedItems[$key], $item->getName());
$this->assertFalse(
@@ -71,7 +95,7 @@ public function setValidationFilterDataProvider()
*/
public function testSetValidationFilterWithGroup()
{
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $objectManager = Bootstrap::getObjectManager();
/** @var \Magento\SalesRule\Model\Rule $rule */
$rule = $objectManager->get(\Magento\Framework\Registry::class)
@@ -82,13 +106,8 @@ public function testSetValidationFilterWithGroup()
$quote->load('test_order_item_with_items', 'reserved_order_id');
//gather only the existing rules that obey the validation filter
- /** @var \Magento\SalesRule\Model\ResourceModel\Rule\Collection $ruleCollection */
- $ruleCollection = $objectManager->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
-
$appliedRulesArray = array_keys(
- $ruleCollection->setValidationFilter(
+ $this->collection->setValidationFilter(
$quote->getStore()->getWebsiteId(),
0,
'',
@@ -108,7 +127,7 @@ public function testSetValidationFilterWithGroup()
*/
public function testSetValidationFilterAnyCategory()
{
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $objectManager = Bootstrap::getObjectManager();
/** @var \Magento\SalesRule\Model\Rule $rule */
$rule = $objectManager->get(\Magento\Framework\Registry::class)
@@ -119,13 +138,8 @@ public function testSetValidationFilterAnyCategory()
$quote->load('test_order_item_with_items', 'reserved_order_id');
//gather only the existing rules that obey the validation filter
- /** @var \Magento\SalesRule\Model\ResourceModel\Rule\Collection $ruleCollection */
- $ruleCollection = $objectManager->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
-
$appliedRulesArray = array_keys(
- $ruleCollection->setValidationFilter(
+ $this->collection->setValidationFilter(
$quote->getStore()->getWebsiteId(),
0,
'',
@@ -146,20 +160,15 @@ public function testSetValidationFilterAnyCategory()
*/
public function testSetValidationFilterOther()
{
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $objectManager = Bootstrap::getObjectManager();
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $objectManager->create(\Magento\Quote\Model\Quote::class);
$quote->load('test_order_item_with_items', 'reserved_order_id');
//gather only the existing rules that obey the validation filter
- /** @var \Magento\SalesRule\Model\ResourceModel\Rule\Collection $ruleCollection */
- $ruleCollection = $objectManager->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
-
$appliedRulesArray = array_keys(
- $ruleCollection->setValidationFilter(
+ $this->collection->setValidationFilter(
$quote->getStore()->getWebsiteId(),
0,
'',
@@ -181,11 +190,8 @@ public function testSetValidationFilterOther()
public function testMultiRulesWithTimezone()
{
$this->setSpecificTimezone('Europe/Kiev');
- $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
- $collection->addWebsiteGroupDateFilter(1, 0);
- $items = array_values($collection->getItems());
+ $this->collection->addWebsiteGroupDateFilter(1, 0);
+ $items = array_values($this->collection->getItems());
$this->assertNotEmpty($items);
}
@@ -200,11 +206,8 @@ public function testMultiRulesWithTimezone()
public function testMultiRulesWithDifferentTimezone()
{
$this->setSpecificTimezone('Australia/Sydney');
- $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
- $collection->addWebsiteGroupDateFilter(1, 0);
- $items = array_values($collection->getItems());
+ $this->collection->addWebsiteGroupDateFilter(1, 0);
+ $items = array_values($this->collection->getItems());
$this->assertNotEmpty($items);
}
@@ -224,7 +227,7 @@ protected function setSpecificTimezone($timezone)
]
]
];
- \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Config\Model\Config\Factory::class)
+ Bootstrap::getObjectManager()->get(\Magento\Config\Model\Config\Factory::class)
->create()
->addData($localeData)
->save();
@@ -239,11 +242,9 @@ protected function setSpecificTimezone($timezone)
*/
public function testAddAttributeInConditionFilterPositive()
{
- $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
- $collection->addAttributeInConditionFilter('attribute_for_sales_rule_1');
- $item = $collection->getFirstItem();
+ $this->collection->addAttributeInConditionFilter('attribute_for_sales_rule_1');
+ /** @var \Magento\SalesRule\Model\Rule $item */
+ $item = $this->collection->getFirstItem();
$this->assertEquals('50% Off on some attribute', $item->getName());
}
@@ -256,16 +257,57 @@ public function testAddAttributeInConditionFilterPositive()
*/
public function testAddAttributeInConditionFilterNegative()
{
- $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
- );
- $collection->addAttributeInConditionFilter('attribute_for_sales_rule_2');
- $this->assertEquals(0, $collection->count());
+ $this->collection->addAttributeInConditionFilter('attribute_for_sales_rule_2');
+ $this->assertEquals(0, $this->collection->count());
+ }
+
+ /**
+ * @magentoAppIsolation disabled
+ * @magentoDataFixture Magento/SalesRule/_files/multi_websites_rules.php
+ * @dataProvider addWebsiteFilterDataProvider
+ * @param string[] $websiteCodes
+ * @param int $count
+ */
+ public function testAddWebsiteFilter(array $websiteCodes, int $count)
+ {
+ $websiteRepository = Bootstrap::getObjectManager()->get(WebsiteRepositoryInterface::class);
+ $websiteIds = [];
+ foreach ($websiteCodes as $websiteCode) {
+ $websiteIds[] = (int) $websiteRepository->get($websiteCode)->getId();
+ }
+
+ $this->collection->addWebsiteFilter($websiteIds);
+ $this->assertEquals($count, $this->collection->getSize());
+ $this->assertCount($count, $this->collection->getItems());
}
- public function tearDown()
+ /**
+ * @return array
+ */
+ public function addWebsiteFilterDataProvider(): array
+ {
+ return [
+ [
+ ['base'],
+ 4,
+ ],
+ [
+ ['test'],
+ 2,
+ ],
+ [
+ ['base', 'test'],
+ 5,
+ ],
+ ];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function tearDown()
{
// restore default timezone
- $this->setSpecificTimezone('America/Los_Angeles');
+ $this->setSpecificTimezone($this->defaultTimezone);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules.php
new file mode 100644
index 0000000000000..a43df3d67c077
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules.php
@@ -0,0 +1,16 @@
+setWebsiteIds($website->getId())
+ ->save();
+
+/** @var \Magento\SalesRule\Model\Rule $rule3 */
+$rule3->setWebsiteIds(implode(',', [1, $website->getId()]))
+ ->save();
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules_rollback.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules_rollback.php
new file mode 100644
index 0000000000000..9e0e01b9fc51c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/multi_websites_rules_rollback.php
@@ -0,0 +1,8 @@
+create(\Magento\SalesRule\Model\Rule::class);
-$rule->setName(
+/** @var \Magento\SalesRule\Model\Rule $rule1 */
+$rule1 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
+$rule1->setName(
'#1'
)->setIsActive(
1
@@ -27,9 +27,9 @@
)->setSortOrder(1)
->save();
-/** @var \Magento\SalesRule\Model\Rule $rule */
-$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
-$rule->setName(
+/** @var \Magento\SalesRule\Model\Rule $rule2 */
+$rule2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
+$rule2->setName(
'#2'
)->setIsActive(
1
@@ -50,9 +50,9 @@
)->setSortOrder(2)
->save();
-/** @var \Magento\SalesRule\Model\Rule $rule */
-$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
-$rule->setName(
+/** @var \Magento\SalesRule\Model\Rule $rule3 */
+$rule3 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
+$rule3->setName(
'#3'
)->setIsActive(
1
@@ -73,9 +73,9 @@
)->setSortOrder(3)
->save();
-/** @var \Magento\SalesRule\Model\Rule $rule */
-$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
-$rule->setName(
+/** @var \Magento\SalesRule\Model\Rule $rule4 */
+$rule4 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
+$rule4->setName(
'#4'
)->setIsActive(
1
@@ -96,9 +96,9 @@
)->setSortOrder(4)
->save();
-/** @var \Magento\SalesRule\Model\Rule $rule */
-$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
-$rule->setName(
+/** @var \Magento\SalesRule\Model\Rule $rule5 */
+$rule5 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class);
+$rule5->setName(
'#5'
)->setIsActive(
1
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml
index 4790ce24fd87f..62406b6cbd30a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml
@@ -69,5 +69,8 @@
-
dev/build/publication/sanity/ce.xml
+ -
+ dev/composer.lock
+
diff --git a/lib/internal/Magento/Framework/App/DocRootLocator.php b/lib/internal/Magento/Framework/App/DocRootLocator.php
index 6fb35c42f1330..d73baf8e4e742 100644
--- a/lib/internal/Magento/Framework/App/DocRootLocator.php
+++ b/lib/internal/Magento/Framework/App/DocRootLocator.php
@@ -3,10 +3,12 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Framework\App;
use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadFactory;
/**
@@ -20,18 +22,26 @@ class DocRootLocator
private $request;
/**
+ * @deprecated
* @var ReadFactory
*/
private $readFactory;
+ /**
+ * @var Filesystem
+ */
+ private $filesystem;
+
/**
* @param RequestInterface $request
* @param ReadFactory $readFactory
+ * @param Filesystem|null $filesystem
*/
- public function __construct(RequestInterface $request, ReadFactory $readFactory)
+ public function __construct(RequestInterface $request, ReadFactory $readFactory, Filesystem $filesystem = null)
{
$this->request = $request;
$this->readFactory = $readFactory;
+ $this->filesystem = $filesystem ?: ObjectManager::getInstance()->get(Filesystem::class);
}
/**
@@ -42,7 +52,8 @@ public function __construct(RequestInterface $request, ReadFactory $readFactory)
public function isPub()
{
$rootBasePath = $this->request->getServer('DOCUMENT_ROOT');
- $readDirectory = $this->readFactory->create(DirectoryList::ROOT);
- return (substr($rootBasePath, -strlen('/pub')) === '/pub') && !$readDirectory->isExist($rootBasePath . 'setup');
+ $readDirectory = $this->filesystem->getDirectoryRead(DirectoryList::ROOT);
+
+ return (substr($rootBasePath, -\strlen('/pub')) === '/pub') && ! $readDirectory->isExist('setup');
}
}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/DocRootLocatorTest.php b/lib/internal/Magento/Framework/App/Test/Unit/DocRootLocatorTest.php
index 23afbbc73d2b9..ef4152ba2e49e 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/DocRootLocatorTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/DocRootLocatorTest.php
@@ -8,6 +8,9 @@
use Magento\Framework\App\DocRootLocator;
+/**
+ * Test for Magento\Framework\App\DocRootLocator class.
+ */
class DocRootLocatorTest extends \PHPUnit\Framework\TestCase
{
/**
@@ -21,11 +24,15 @@ public function testIsPub($path, $isExist, $result)
{
$request = $this->createMock(\Magento\Framework\App\Request\Http::class);
$request->expects($this->once())->method('getServer')->willReturn($path);
+
+ $readFactory = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadFactory::class);
+
$reader = $this->createMock(\Magento\Framework\Filesystem\Directory\Read::class);
+ $filesystem = $this->createMock(\Magento\Framework\Filesystem::class);
+ $filesystem->expects($this->once())->method('getDirectoryRead')->willReturn($reader);
$reader->expects($this->any())->method('isExist')->willReturn($isExist);
- $readFactory = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadFactory::class);
- $readFactory->expects($this->once())->method('create')->willReturn($reader);
- $model = new DocRootLocator($request, $readFactory);
+
+ $model = new DocRootLocator($request, $readFactory, $filesystem);
$this->assertSame($result, $model->isPub());
}