*/
-namespace Magento\Eav\Model\Validator\Attribute;
-
-use Magento\Eav\Model\Attribute;
-
class Data extends \Magento\Framework\Validator\AbstractValidator
{
/**
@@ -126,7 +126,7 @@ public function isValid($entity)
$dataModel = $this->_attrDataFactory->create($attribute, $entity);
$dataModel->setExtractedData($data);
if (!isset($data[$attributeCode])) {
- $data[$attributeCode] = null;
+ $data[$attributeCode] = '';
}
$result = $dataModel->validateValue($data[$attributeCode]);
if (true !== $result) {
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php
index 07ce6fbfc6a4..acba37cc4578 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php
@@ -4,13 +4,54 @@
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
+namespace Magento\Eav\Test\Unit\Model\Validator\Attribute;
+
/**
* Test for \Magento\Eav\Model\Validator\Attribute\Data
*/
-namespace Magento\Eav\Test\Unit\Model\Validator\Attribute;
-
class DataTest extends \PHPUnit\Framework\TestCase
{
+ /**
+ * @var \Magento\Eav\Model\AttributeDataFactory|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $attrDataFactory;
+
+ /**
+ * @var \Magento\Eav\Model\Validator\Attribute\Data
+ */
+ private $model;
+
+ /**
+ * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+ */
+ private $objectManager;
+
+ /**
+ * @inheritdoc
+ */
+ protected function setUp()
+ {
+ $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->attrDataFactory = $this->getMockBuilder(\Magento\Eav\Model\AttributeDataFactory::class)
+ ->setMethods(['create'])
+ ->setConstructorArgs(
+ [
+ 'objectManager' => $this->createMock(\Magento\Framework\ObjectManagerInterface::class),
+ 'string' => $this->createMock(\Magento\Framework\Stdlib\StringUtils::class)
+ ]
+ )
+ ->getMock();
+
+ $this->model = $this->objectManager->getObject(
+ \Magento\Eav\Model\Validator\Attribute\Data::class,
+ [
+ '_attrDataFactory' => $this->attrDataFactory
+ ]
+ );
+ }
+
/**
* Testing \Magento\Eav\Model\Validator\Attribute\Data::isValid
*
@@ -381,13 +422,15 @@ public function testAddErrorMessages()
protected function _getAttributeMock($attributeData)
{
$attribute = $this->getMockBuilder(\Magento\Eav\Model\Attribute::class)
- ->setMethods([
- 'getAttributeCode',
- 'getDataModel',
- 'getFrontendInput',
- '__wakeup',
- 'getIsVisible',
- ])
+ ->setMethods(
+ [
+ 'getAttributeCode',
+ 'getDataModel',
+ 'getFrontendInput',
+ '__wakeup',
+ 'getIsVisible',
+ ]
+ )
->disableOriginalConstructor()
->getMock();
@@ -436,7 +479,7 @@ protected function _getDataModelMock($returnValue, $argument = null)
$dataModel = $this->getMockBuilder(
\Magento\Eav\Model\Attribute\Data\AbstractData::class
)->disableOriginalConstructor()->setMethods(
- ['validateValue']
+ ['setExtractedData', 'validateValue']
)->getMockForAbstractClass();
if ($argument) {
$dataModel->expects(
@@ -466,4 +509,24 @@ protected function _getEntityMock()
)->disableOriginalConstructor()->getMock();
return $entity;
}
+
+ /**
+ * Test for isValid() without data for attribute.
+ *
+ * @return void
+ */
+ public function testIsValidWithoutData() : void
+ {
+ $attributeData = ['attribute_code' => 'attribute', 'frontend_input' => 'text', 'is_visible' => true];
+ $entity = $this->_getEntityMock();
+ $attribute = $this->_getAttributeMock($attributeData);
+ $dataModel = $this->_getDataModelMock(true, $this->logicalAnd($this->isEmpty(), $this->isType('string')));
+ $dataModel->expects($this->once())->method('setExtractedData')->with([])->willReturnSelf();
+ $this->attrDataFactory->expects($this->once())
+ ->method('create')
+ ->with($attribute, $entity)
+ ->willReturn($dataModel);
+ $this->model->setAttributes([$attribute])->setData([]);
+ $this->assertTrue($this->model->isValid($entity));
+ }
}
diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
index 6729fe722de5..d58af06da94c 100644
--- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
+++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Rule\Model\Condition;
@@ -17,6 +18,7 @@
* @method setFormName()
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * phpcs:disable Magento2.Classes.AbstractApi
* @api
* @since 100.0.2
*/
@@ -390,7 +392,7 @@ public function getValueParsed()
$value = reset($value);
}
if (!is_array($value) && $this->isArrayOperatorType() && $value) {
- $value = preg_split('#\s*[,;]\s*#', $value, null, PREG_SPLIT_NO_EMPTY);
+ $value = preg_split('#\s*[,;]\s*#', (string) $value, -1, PREG_SPLIT_NO_EMPTY);
}
$this->setValueParsed($value);
}
@@ -419,8 +421,11 @@ public function getValue()
{
if ($this->getInputType() == 'date' && !$this->getIsValueParsed()) {
// date format intentionally hard-coded
+ $date = $this->getData('value');
+ $date = (\is_numeric($date) ? '@' : '') . $date;
$this->setValue(
- (new \DateTime($this->getData('value')))->format('Y-m-d H:i:s')
+ (new \DateTime($date, new \DateTimeZone((string) $this->_localeDate->getConfigTimezone())))
+ ->format('Y-m-d H:i:s')
);
$this->setIsValueParsed(true);
}
@@ -432,6 +437,7 @@ public function getValue()
*
* @return array|string
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * phpcs:disable Generic.Metrics.NestingLevel
*/
public function getValueName()
{
@@ -469,6 +475,7 @@ public function getValueName()
}
return $value;
}
+ //phpcs:enable Generic.Metrics.NestingLevel
/**
* Get inherited conditions selectors
@@ -674,6 +681,9 @@ public function getValueElement()
$elementParams['placeholder'] = \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT;
$elementParams['autocomplete'] = 'off';
$elementParams['readonly'] = 'true';
+ $elementParams['value_name'] =
+ (new \DateTime($elementParams['value'], new \DateTimeZone($this->_localeDate->getConfigTimezone())))
+ ->format('Y-m-d');
}
return $this->getForm()->addField(
$this->getPrefix() . '__' . $this->getId() . '__value',
@@ -879,7 +889,7 @@ protected function _compareValues($validatedValue, $value, $strict = true)
return $validatedValue == $value;
}
- $validatePattern = preg_quote($validatedValue, '~');
+ $validatePattern = preg_quote((string) $validatedValue, '~');
if ($strict) {
$validatePattern = '^' . $validatePattern . '$';
}
diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php
index 52653197e398..0ba41af04a1b 100644
--- a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php
+++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php
@@ -55,14 +55,14 @@ public function validateAttributeDataProvider()
['0', '==', 1, false],
['1', '==', 1, true],
['x', '==', 'x', true],
- ['x', '==', 0, false],
+ ['x', '==', '0', false],
[1, '!=', 1, false],
[0, '!=', 1, true],
['0', '!=', 1, true],
['1', '!=', 1, false],
['x', '!=', 'x', false],
- ['x', '!=', 0, true],
+ ['x', '!=', '0', true],
[1, '==', [1], true],
[1, '!=', [1], false],
@@ -164,15 +164,15 @@ public function validateAttributeArrayInputTypeDataProvider()
[[1, 2, 3], '{}', '1', true, 'grid'],
[[1, 2, 3], '{}', '8', false, 'grid'],
- [[1, 2, 3], '{}', 5, false, 'grid'],
+ [[1, 2, 3], '{}', '5', false, 'grid'],
[[1, 2, 3], '{}', [2, 3, 4], true, 'grid'],
[[1, 2, 3], '{}', [4], false, 'grid'],
[[3], '{}', [], false, 'grid'],
[1, '{}', 1, false, 'grid'],
[1, '!{}', [1, 2, 3], false, 'grid'],
[[1], '{}', null, false, 'grid'],
- [null, '{}', null, true, 'input'],
- [null, '!{}', null, false, 'input'],
+ ['null', '{}', 'null', true, 'input'],
+ ['null', '!{}', 'null', false, 'input'],
[null, '{}', [1], false, 'input'],
[[1, 2, 3], '()', 1, true, 'select'],
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml
index 71a96dc10938..653b1d48686e 100644
--- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml
@@ -13,6 +13,8 @@
+
+
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
index ab5cd49449ec..825ac8205772 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
@@ -9,6 +9,10 @@
*/
$order = $block->getOrder();
+$baseCurrencyCode = (string)$order->getBaseCurrencyCode();
+$globalCurrencyCode = (string)$order->getGlobalCurrencyCode();
+$orderCurrencyCode = (string)$order->getOrderCurrencyCode();
+
$orderAdminDate = $block->formatDate(
$block->getOrderAdminDate($order->getCreatedAt()),
\IntlDateFormatter::MEDIUM,
@@ -23,6 +27,7 @@ $orderStoreDate = $block->formatDate(
);
$customerUrl = $block->getCustomerViewUrl();
+
$allowedAddressHtmlTags = ['b', 'br', 'em', 'i', 'li', 'ol', 'p', 'strong', 'sub', 'sup', 'ul'];
?>
@@ -93,15 +98,15 @@ $allowedAddressHtmlTags = ['b', 'br', 'em', 'i', 'li', 'ol', 'p', 'strong', 'sub
= $block->escapeHtml($order->getRemoteIp()); ?>= $order->getXForwardedFor() ? ' (' . $block->escapeHtml($order->getXForwardedFor()) . ')' : ''; ?> |
- getGlobalCurrencyCode() != $order->getBaseCurrencyCode()) : ?>
+
- = $block->escapeHtml(__('%1 / %2 rate:', $order->getGlobalCurrencyCode(), $order->getBaseCurrencyCode())) ?> |
+ = $block->escapeHtml(__('%1 / %2 rate:', $globalCurrencyCode, $baseCurrencyCode)) ?> |
= $block->escapeHtml($order->getBaseToGlobalRate()) ?> |
- getBaseCurrencyCode() != $order->getOrderCurrencyCode()) : ?>
+
- = $block->escapeHtml(__('%1 / %2 rate:', $order->getOrderCurrencyCode(), $order->getBaseCurrencyCode())) ?> |
+ = $block->escapeHtml(__('%1 / %2 rate:', $orderCurrencyCode, $baseCurrencyCode)) ?> |
= $block->escapeHtml($order->getBaseToOrderRate()) ?> |
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml
index 9a74ced2a2c1..89398051fcf6 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml
@@ -11,6 +11,7 @@
+
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
index 8ca6b20db3b5..da358372e089 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
@@ -247,10 +247,10 @@ public function testValidateCategoriesIgnoresVisibility(): void
* @param boolean $isValid
* @param string $conditionValue
* @param string $operator
- * @param double $productPrice
+ * @param string $productPrice
* @dataProvider localisationProvider
*/
- public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = 2000.00)
+ public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = '2000.00')
{
$attr = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class)
->disableOriginalConstructor()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
index 5e91d8b2092d..b324bb6f6295 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
@@ -3,17 +3,18 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
declare(strict_types=1);
namespace Magento\Catalog\Controller\Adminhtml;
-use Magento\Catalog\Api\CategoryRepositoryInterface;
+use Magento\Backend\App\Area\FrontNameResolver;
+use Magento\Catalog\Model\ResourceModel\Product;
use Magento\Framework\App\Request\Http as HttpRequest;
+use Magento\Framework\Message\MessageInterface;
+use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\Store\Model\Store;
-use Magento\Catalog\Model\ResourceModel\Product;
/**
* Test for category backend actions
@@ -43,7 +44,7 @@ protected function setUp()
}
/**
- * Test save action
+ * Test save action.
*
* @magentoDataFixture Magento/Store/_files/core_fixturestore.php
* @magentoDbIsolation enabled
@@ -57,7 +58,7 @@ protected function setUp()
public function testSaveAction($inputData, $defaultAttributes, $attributesSaved = [], $isSuccess = true)
{
/** @var $store \Magento\Store\Model\Store */
- $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class);
+ $store = Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class);
$store->load('fixturestore', 'code');
$storeId = $store->getId();
@@ -70,14 +71,12 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved
if ($isSuccess) {
$this->assertSessionMessages(
$this->equalTo(['You saved the category.']),
- \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+ MessageInterface::TYPE_SUCCESS
);
}
/** @var $category \Magento\Catalog\Model\Category */
- $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\Catalog\Model\Category::class
- );
+ $category = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class);
$category->setStoreId($storeId);
$category->load(2);
@@ -428,12 +427,12 @@ public function testSaveActionCategoryWithDangerRequest()
$this->dispatch('backend/catalog/category/save');
$this->assertSessionMessages(
$this->equalTo(['The "Name" attribute value is empty. Set the attribute and try again.']),
- \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+ MessageInterface::TYPE_ERROR
);
}
/**
- * Test move Action
+ * Test move action.
*
* @magentoDataFixture Magento/Catalog/_files/category_tree.php
* @dataProvider moveActionDataProvider
@@ -488,7 +487,7 @@ public function moveActionDataProvider()
}
/**
- * Test save action
+ * Test save category with product position.
*
* @magentoDataFixture Magento/Catalog/_files/products_in_different_stores.php
* @magentoDbIsolation disabled
@@ -600,7 +599,7 @@ public function saveActionWithDifferentWebsitesDataProvider()
}
/**
- * Get items count from catalog_category_product
+ * Get items count from catalog_category_product.
*
* @return int
*/
@@ -614,4 +613,36 @@ private function getCategoryProductsCount(): int
$this->productResource->getConnection()->fetchAll($oldCategoryProducts)
);
}
+
+ /**
+ * Verify that the category cannot be saved if the category url matches the admin url.
+ *
+ * @magentoConfigFixture admin/url/use_custom_path 1
+ * @magentoConfigFixture admin/url/custom_path backend
+ */
+ public function testSaveWithCustomBackendNameAction()
+ {
+ $frontNameResolver = Bootstrap::getObjectManager()->create(FrontNameResolver::class);
+ $urlKey = $frontNameResolver->getFrontName();
+ $inputData = [
+ 'id' => '2',
+ 'url_key' => $urlKey,
+ 'use_config' => [
+ 'available_sort_by' => 1,
+ 'default_sort_by' => 1
+ ]
+ ];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
+ $this->getRequest()->setPostValue($inputData);
+ $this->dispatch('backend/catalog/category/save');
+ $this->assertSessionMessages(
+ $this->equalTo(
+ [
+ 'URL key "backend" matches a reserved endpoint name '
+ . '(admin, soap, rest, graphql, standard, backend). Use another URL key.'
+ ]
+ ),
+ MessageInterface::TYPE_ERROR
+ );
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php
index b916fc024041..3c4c164f0a01 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php
@@ -5,6 +5,7 @@
*/
declare(strict_types=1);
+use Magento\Store\Model\StoreRepository;
use Magento\Quote\Model\QuoteFactory;
use Magento\Quote\Model\QuoteRepository;
use Magento\TestFramework\Helper\Bootstrap;
@@ -18,13 +19,18 @@
$quoteFactory = $objectManager->get(QuoteFactory::class);
/** @var QuoteRepository $quoteRepository */
$quoteRepository = $objectManager->get(QuoteRepository::class);
+/** @var StoreRepository $storeRepository */
+$storeRepository = $objectManager->get(StoreRepository::class);
+
+$defaultStore = $storeRepository->getActiveStoreByCode('default');
+$secondStore = $storeRepository->getActiveStoreByCode('fixture_second_store');
$quotes = [
'quote for first store' => [
- 'store' => 1,
+ 'store' => $defaultStore->getId(),
],
'quote for second store' => [
- 'store' => 2,
+ 'store' => $secondStore->getId(),
],
];