diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 89aea7299855c..37b7bc2ca8c3a 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -31,7 +31,7 @@ If you are a new GitHub user, we recommend that you create your own [free github
This will allow you to collaborate with the Magento 2 development team, fork the Magento 2 project and send pull requests.
1. Search current [listed issues](https://github.com/magento/magento2/issues) (open or closed) for similar proposals of intended contribution before starting work on a new contribution.
-2. Review the [Contributor License Agreement](https://magento.com/legaldocuments/mca) if this is your first time contributing.
+2. Review the [Contributor License Agreement](https://opensource.adobe.com/cla.html) if this is your first time contributing.
3. Create and test your work.
4. Fork the Magento 2 repository according to the [Fork A Repository instructions](https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#fork) and when you are ready to send us a pull request – follow the [Create A Pull Request instructions](https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#pull_request).
5. Once your contribution is received the Magento 2 development team will review the contribution and collaborate with you as needed.
diff --git a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php
index 81a47d72602b7..e6522054d9f94 100644
--- a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php
+++ b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php
@@ -6,35 +6,31 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\BundleImportExport\Model\Import\Product\Type;
-use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
-use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory as AttributeSetCollectionFactory;
-use Magento\Framework\App\ObjectManager;
use Magento\Bundle\Model\Product\Price as BundlePrice;
use Magento\Catalog\Model\Product\Type\AbstractType;
+use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
use Magento\CatalogImportExport\Model\Import\Product;
+use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory as AttributeSetCollectionFactory;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\StoreManagerInterface;
/**
- * Class Bundle
+ * Import entity Bundle product type.
*
- * @package Magento\BundleImportExport\Model\Import\Product\Type
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
*/
class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType
{
-
/**
* Delimiter before product option value.
*/
const BEFORE_OPTION_VALUE_DELIMITER = ';';
- /**
- * Pair value separator.
- */
const PAIR_VALUE_SEPARATOR = '=';
/**
@@ -47,19 +43,10 @@ class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\Abst
*/
const VALUE_FIXED = 'fixed';
- /**
- * Not fixed dynamic attribute.
- */
const NOT_FIXED_DYNAMIC_ATTRIBUTE = 'price_view';
- /**
- * Selection price type fixed.
- */
const SELECTION_PRICE_TYPE_FIXED = 0;
- /**
- * Selection price type percent.
- */
const SELECTION_PRICE_TYPE_PERCENT = 1;
/**
@@ -133,7 +120,7 @@ class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\Abst
protected $_optionTypeMapping = [
'dropdown' => 'select',
'radiobutton' => 'radio',
- 'checkbox' => 'checkbox',
+ 'checkbox' => 'checkbox',
'multiselect' => 'multi',
];
@@ -543,7 +530,7 @@ protected function populateExistingSelections($existingOptions)
? $this->_bundleFieldMapping[$origKey]
: $origKey;
if (
- !isset($this->_cachedOptions[$existingSelection['parent_product_id']][$optionTitle]['selections'][$selectIndex][$key])
+ !isset($this->_cachedOptions[$existingSelection['parent_product_id']][$optionTitle]['selections'][$selectIndex][$key])
) {
$this->_cachedOptions[$existingSelection['parent_product_id']][$optionTitle]['selections'][$selectIndex][$key] =
$existingSelection[$origKey];
@@ -616,6 +603,7 @@ protected function populateInsertOptionValues(array $optionIds): array
if ($assoc['position'] == $this->_cachedOptions[$entityId][$key]['index']
&& $assoc['parent_id'] == $entityId) {
$option['parent_id'] = $entityId;
+ //phpcs:ignore Magento2.Performance.ForeachArrayMerge
$optionValues = array_merge(
$optionValues,
$this->populateOptionValueTemplate($option, $optionId)
@@ -675,10 +663,7 @@ private function insertParentChildRelations()
$childIds = [];
foreach ($options as $option) {
foreach ($option['selections'] as $selection) {
- if (!isset($selection['parent_product_id'])) {
- if (!isset($this->_cachedSkuToProducts[$selection['sku']])) {
- continue;
- }
+ if (isset($this->_cachedSkuToProducts[$selection['sku']])) {
$childIds[] = $this->_cachedSkuToProducts[$selection['sku']];
}
}
@@ -717,6 +702,8 @@ protected function _initAttributes()
}
}
}
+
+ return $this;
}
/**
@@ -735,17 +722,19 @@ protected function deleteOptionsAndSelections($productIds)
$optionTable = $this->_resource->getTableName('catalog_product_bundle_option');
$optionValueTable = $this->_resource->getTableName('catalog_product_bundle_option_value');
$selectionTable = $this->_resource->getTableName('catalog_product_bundle_selection');
- $valuesIds = $this->connection->fetchAssoc($this->connection->select()->from(
- ['bov' => $optionValueTable],
- ['value_id']
- )->joinLeft(
- ['bo' => $optionTable],
- 'bo.option_id = bov.option_id',
- ['option_id']
- )->where(
- 'parent_id IN (?)',
- $productIds
- ));
+ $valuesIds = $this->connection->fetchAssoc(
+ $this->connection->select()->from(
+ ['bov' => $optionValueTable],
+ ['value_id']
+ )->joinLeft(
+ ['bo' => $optionTable],
+ 'bo.option_id = bov.option_id',
+ ['option_id']
+ )->where(
+ 'parent_id IN (?)',
+ $productIds
+ )
+ );
$this->connection->delete(
$optionValueTable,
$this->connection->quoteInto('value_id IN (?)', array_keys($valuesIds))
diff --git a/app/code/Magento/BundleImportExport/Test/Mftf/Test/UpdateBundleProductViaImportTest.xml b/app/code/Magento/BundleImportExport/Test/Mftf/Test/UpdateBundleProductViaImportTest.xml
new file mode 100644
index 0000000000000..45b4c4f5ededd
--- /dev/null
+++ b/app/code/Magento/BundleImportExport/Test/Mftf/Test/UpdateBundleProductViaImportTest.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Plugin/Model/ResourceModel/Config.php b/app/code/Magento/Catalog/Plugin/Model/ResourceModel/Config.php
index b942f5570f57d..a3e7a417e6e47 100644
--- a/app/code/Magento/Catalog/Plugin/Model/ResourceModel/Config.php
+++ b/app/code/Magento/Catalog/Plugin/Model/ResourceModel/Config.php
@@ -3,9 +3,14 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Catalog\Plugin\Model\ResourceModel;
-use Magento\Framework\App\ObjectManager;
+use Magento\Eav\Model\Cache\Type;
+use Magento\Eav\Model\Entity\Attribute;
+use Magento\Framework\App\Cache\StateInterface;
+use Magento\Framework\App\CacheInterface;
use Magento\Framework\Serialize\SerializerInterface;
/**
@@ -21,12 +26,12 @@ class Config
/**#@-*/
/**#@-*/
- protected $cache;
+ private $cache;
/**
- * @var bool|null
+ * @var bool
*/
- protected $isCacheEnabled = null;
+ private $isCacheEnabled;
/**
* @var SerializerInterface
@@ -34,30 +39,30 @@ class Config
private $serializer;
/**
- * @param \Magento\Framework\App\CacheInterface $cache
- * @param \Magento\Framework\App\Cache\StateInterface $cacheState
+ * @param CacheInterface $cache
+ * @param StateInterface $cacheState
* @param SerializerInterface $serializer
*/
public function __construct(
- \Magento\Framework\App\CacheInterface $cache,
- \Magento\Framework\App\Cache\StateInterface $cacheState,
- SerializerInterface $serializer = null
+ CacheInterface $cache,
+ StateInterface $cacheState,
+ SerializerInterface $serializer
) {
$this->cache = $cache;
- $this->isCacheEnabled = $cacheState->isEnabled(\Magento\Eav\Model\Cache\Type::TYPE_IDENTIFIER);
- $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
+ $this->isCacheEnabled = $cacheState->isEnabled(Type::TYPE_IDENTIFIER);
+ $this->serializer = $serializer;
}
/**
* Cache attribute used in listing.
*
* @param \Magento\Catalog\Model\ResourceModel\Config $config
- * @param \Closure $proceed
+ * @param callable $proceed
* @return array
*/
public function aroundGetAttributesUsedInListing(
\Magento\Catalog\Model\ResourceModel\Config $config,
- \Closure $proceed
+ callable $proceed
) {
$cacheId = self::PRODUCT_LISTING_ATTRIBUTES_CACHE_ID . $config->getEntityTypeId() . '_' . $config->getStoreId();
if ($this->isCacheEnabled && ($attributes = $this->cache->load($cacheId))) {
@@ -69,8 +74,8 @@ public function aroundGetAttributesUsedInListing(
$this->serializer->serialize($attributes),
$cacheId,
[
- \Magento\Eav\Model\Cache\Type::CACHE_TAG,
- \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+ Type::CACHE_TAG,
+ Attribute::CACHE_TAG
]
);
}
@@ -81,12 +86,12 @@ public function aroundGetAttributesUsedInListing(
* Cache attributes used for sorting.
*
* @param \Magento\Catalog\Model\ResourceModel\Config $config
- * @param \Closure $proceed
+ * @param callable $proceed
* @return array
*/
public function aroundGetAttributesUsedForSortBy(
\Magento\Catalog\Model\ResourceModel\Config $config,
- \Closure $proceed
+ callable $proceed
) {
$cacheId = self::PRODUCT_LISTING_SORT_BY_ATTRIBUTES_CACHE_ID . $config->getEntityTypeId() . '_'
. $config->getStoreId();
@@ -99,8 +104,8 @@ public function aroundGetAttributesUsedForSortBy(
$this->serializer->serialize($attributes),
$cacheId,
[
- \Magento\Eav\Model\Cache\Type::CACHE_TAG,
- \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+ Type::CACHE_TAG,
+ Attribute::CACHE_TAG
]
);
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Plugin/Model/ResourceModel/ConfigTest.php b/app/code/Magento/Catalog/Test/Unit/Plugin/Model/ResourceModel/ConfigTest.php
index f36c934ca9acf..142de8fd1c5df 100644
--- a/app/code/Magento/Catalog/Test/Unit/Plugin/Model/ResourceModel/ConfigTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Plugin/Model/ResourceModel/ConfigTest.php
@@ -3,43 +3,59 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Plugin\Model\ResourceModel;
+use Magento\Catalog\Model\ResourceModel\Config as ConfigResourceModel;
use Magento\Catalog\Plugin\Model\ResourceModel\Config;
+use Magento\Eav\Model\Cache\Type;
+use Magento\Eav\Model\Entity\Attribute;
+use Magento\Framework\App\Cache\StateInterface;
+use Magento\Framework\App\CacheInterface;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
-class ConfigTest extends \PHPUnit\Framework\TestCase
+class ConfigTest extends TestCase
{
- /** @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject */
- private $cache;
+ /**
+ * @var CacheInterface|MockObject
+ */
+ private $cacheMock;
- /** @var \Magento\Framework\App\Cache\StateInterface|\PHPUnit_Framework_MockObject_MockObject */
- private $cacheState;
+ /**
+ * @var StateInterface|MockObject
+ */
+ private $cacheStateMock;
- /** @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */
- private $serializer;
+ /**
+ * @var SerializerInterface|MockObject
+ */
+ private $serializerMock;
- /** @var \Magento\Catalog\Model\ResourceModel\Config|\PHPUnit_Framework_MockObject_MockObject */
- private $subject;
+ /**
+ * @var ConfigResourceModel|MockObject
+ */
+ private $configResourceModelMock;
protected function setUp()
{
- $this->cache = $this->createMock(\Magento\Framework\App\CacheInterface::class);
- $this->cacheState = $this->createMock(\Magento\Framework\App\Cache\StateInterface::class);
- $this->serializer = $this->createMock(SerializerInterface::class);
- $this->subject = $this->createMock(\Magento\Catalog\Model\ResourceModel\Config::class);
+ $this->cacheMock = $this->createMock(CacheInterface::class);
+ $this->cacheStateMock = $this->createMock(StateInterface::class);
+ $this->serializerMock = $this->createMock(SerializerInterface::class);
+ $this->configResourceModelMock = $this->createMock(ConfigResourceModel::class);
}
public function testGetAttributesUsedInListingOnCacheDisabled()
{
- $this->cache->expects($this->never())->method('load');
+ $this->cacheMock->expects($this->never())->method('load');
$this->assertEquals(
['attributes'],
$this->getConfig(false)->aroundGetAttributesUsedInListing(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed(['attributes'])
)
);
@@ -51,13 +67,13 @@ public function testGetAttributesUsedInListingFromCache()
$storeId = 'store';
$attributes = ['attributes'];
$serializedAttributes = '["attributes"]';
- $this->subject->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId);
- $this->subject->expects($this->any())->method('getStoreId')->willReturn($storeId);
- $cacheId = \Magento\Catalog\Plugin\Model\ResourceModel\Config::PRODUCT_LISTING_ATTRIBUTES_CACHE_ID
+ $this->configResourceModelMock->method('getEntityTypeId')->willReturn($entityTypeId);
+ $this->configResourceModelMock->method('getStoreId')->willReturn($storeId);
+ $cacheId = Config::PRODUCT_LISTING_ATTRIBUTES_CACHE_ID
. $entityTypeId
. '_' . $storeId;
- $this->cache->expects($this->any())->method('load')->with($cacheId)->willReturn($serializedAttributes);
- $this->serializer->expects($this->once())
+ $this->cacheMock->method('load')->with($cacheId)->willReturn($serializedAttributes);
+ $this->serializerMock->expects($this->once())
->method('unserialize')
->with($serializedAttributes)
->willReturn($attributes);
@@ -65,7 +81,7 @@ public function testGetAttributesUsedInListingFromCache()
$this->assertEquals(
$attributes,
$this->getConfig(true)->aroundGetAttributesUsedInListing(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed()
)
);
@@ -77,31 +93,31 @@ public function testGetAttributesUsedInListingWithCacheSave()
$storeId = 'store';
$attributes = ['attributes'];
$serializedAttributes = '["attributes"]';
- $this->subject->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId);
- $this->subject->expects($this->any())->method('getStoreId')->willReturn($storeId);
- $cacheId = \Magento\Catalog\Plugin\Model\ResourceModel\Config::PRODUCT_LISTING_ATTRIBUTES_CACHE_ID
+ $this->configResourceModelMock->method('getEntityTypeId')->willReturn($entityTypeId);
+ $this->configResourceModelMock->method('getStoreId')->willReturn($storeId);
+ $cacheId = Config::PRODUCT_LISTING_ATTRIBUTES_CACHE_ID
. $entityTypeId
. '_' . $storeId;
- $this->cache->expects($this->any())->method('load')->with($cacheId)->willReturn(false);
- $this->serializer->expects($this->never())
+ $this->cacheMock->method('load')->with($cacheId)->willReturn(false);
+ $this->serializerMock->expects($this->never())
->method('unserialize');
- $this->serializer->expects($this->once())
+ $this->serializerMock->expects($this->once())
->method('serialize')
->with($attributes)
->willReturn($serializedAttributes);
- $this->cache->expects($this->any())->method('save')->with(
+ $this->cacheMock->method('save')->with(
$serializedAttributes,
$cacheId,
[
- \Magento\Eav\Model\Cache\Type::CACHE_TAG,
- \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+ Type::CACHE_TAG,
+ Attribute::CACHE_TAG
]
);
$this->assertEquals(
$attributes,
$this->getConfig(true)->aroundGetAttributesUsedInListing(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed($attributes)
)
);
@@ -109,12 +125,12 @@ public function testGetAttributesUsedInListingWithCacheSave()
public function testGetAttributesUsedForSortByOnCacheDisabled()
{
- $this->cache->expects($this->never())->method('load');
+ $this->cacheMock->expects($this->never())->method('load');
$this->assertEquals(
['attributes'],
$this->getConfig(false)->aroundGetAttributesUsedForSortBy(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed(['attributes'])
)
);
@@ -126,12 +142,12 @@ public function testGetAttributesUsedForSortByFromCache()
$storeId = 'store';
$attributes = ['attributes'];
$serializedAttributes = '["attributes"]';
- $this->subject->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId);
- $this->subject->expects($this->any())->method('getStoreId')->willReturn($storeId);
- $cacheId = \Magento\Catalog\Plugin\Model\ResourceModel\Config::PRODUCT_LISTING_SORT_BY_ATTRIBUTES_CACHE_ID
+ $this->configResourceModelMock->method('getEntityTypeId')->willReturn($entityTypeId);
+ $this->configResourceModelMock->method('getStoreId')->willReturn($storeId);
+ $cacheId = Config::PRODUCT_LISTING_SORT_BY_ATTRIBUTES_CACHE_ID
. $entityTypeId . '_' . $storeId;
- $this->cache->expects($this->any())->method('load')->with($cacheId)->willReturn($serializedAttributes);
- $this->serializer->expects($this->once())
+ $this->cacheMock->method('load')->with($cacheId)->willReturn($serializedAttributes);
+ $this->serializerMock->expects($this->once())
->method('unserialize')
->with($serializedAttributes)
->willReturn($attributes);
@@ -139,7 +155,7 @@ public function testGetAttributesUsedForSortByFromCache()
$this->assertEquals(
$attributes,
$this->getConfig(true)->aroundGetAttributesUsedForSortBy(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed()
)
);
@@ -151,30 +167,30 @@ public function testGetAttributesUsedForSortByWithCacheSave()
$storeId = 'store';
$attributes = ['attributes'];
$serializedAttributes = '["attributes"]';
- $this->subject->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId);
- $this->subject->expects($this->any())->method('getStoreId')->willReturn($storeId);
- $cacheId = \Magento\Catalog\Plugin\Model\ResourceModel\Config::PRODUCT_LISTING_SORT_BY_ATTRIBUTES_CACHE_ID
+ $this->configResourceModelMock->method('getEntityTypeId')->willReturn($entityTypeId);
+ $this->configResourceModelMock->method('getStoreId')->willReturn($storeId);
+ $cacheId = Config::PRODUCT_LISTING_SORT_BY_ATTRIBUTES_CACHE_ID
. $entityTypeId . '_' . $storeId;
- $this->cache->expects($this->any())->method('load')->with($cacheId)->willReturn(false);
- $this->serializer->expects($this->never())
+ $this->cacheMock->method('load')->with($cacheId)->willReturn(false);
+ $this->serializerMock->expects($this->never())
->method('unserialize');
- $this->serializer->expects($this->once())
+ $this->serializerMock->expects($this->once())
->method('serialize')
->with($attributes)
->willReturn($serializedAttributes);
- $this->cache->expects($this->any())->method('save')->with(
+ $this->cacheMock->method('save')->with(
$serializedAttributes,
$cacheId,
[
- \Magento\Eav\Model\Cache\Type::CACHE_TAG,
- \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+ Type::CACHE_TAG,
+ Attribute::CACHE_TAG
]
);
$this->assertEquals(
$attributes,
$this->getConfig(true)->aroundGetAttributesUsedForSortBy(
- $this->subject,
+ $this->configResourceModelMock,
$this->mockPluginProceed($attributes)
)
);
@@ -182,29 +198,33 @@ public function testGetAttributesUsedForSortByWithCacheSave()
/**
* @param bool $cacheEnabledFlag
- * @return \Magento\Catalog\Plugin\Model\ResourceModel\Config
+ *
+ * @return Config
*/
protected function getConfig($cacheEnabledFlag)
{
- $this->cacheState->expects($this->any())->method('isEnabled')
- ->with(\Magento\Eav\Model\Cache\Type::TYPE_IDENTIFIER)->willReturn($cacheEnabledFlag);
+ $this->cacheStateMock->method('isEnabled')
+ ->with(Type::TYPE_IDENTIFIER)
+ ->willReturn($cacheEnabledFlag);
+
return (new ObjectManager($this))->getObject(
- \Magento\Catalog\Plugin\Model\ResourceModel\Config::class,
+ Config::class,
[
- 'cache' => $this->cache,
- 'cacheState' => $this->cacheState,
- 'serializer' => $this->serializer,
+ 'cache' => $this->cacheMock,
+ 'cacheState' => $this->cacheStateMock,
+ 'serializer' => $this->serializerMock,
]
);
}
/**
* @param mixed $returnValue
+ *
* @return callable
*/
protected function mockPluginProceed($returnValue = null)
{
- return function () use ($returnValue) {
+ return static function () use ($returnValue) {
return $returnValue;
};
}
diff --git a/app/code/Magento/Catalog/Test/Unit/ViewModel/Product/BreadcrumbsTest.php b/app/code/Magento/Catalog/Test/Unit/ViewModel/Product/BreadcrumbsTest.php
index a442041660893..91bb534fff627 100644
--- a/app/code/Magento/Catalog/Test/Unit/ViewModel/Product/BreadcrumbsTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/ViewModel/Product/BreadcrumbsTest.php
@@ -11,65 +11,72 @@
use Magento\Catalog\Model\Product;
use Magento\Catalog\ViewModel\Product\Breadcrumbs;
use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Escaper;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\Serialize\Serializer\JsonHexTag;
+use Magento\Store\Model\ScopeInterface;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
/**
* Unit test for Magento\Catalog\ViewModel\Product\Breadcrumbs.
*/
-class BreadcrumbsTest extends \PHPUnit\Framework\TestCase
+class BreadcrumbsTest extends TestCase
{
+ private const XML_PATH_CATEGORY_URL_SUFFIX = 'catalog/seo/category_url_suffix';
+ private const XML_PATH_PRODUCT_USE_CATEGORIES = 'catalog/seo/product_use_categories';
+
/**
* @var Breadcrumbs
*/
private $viewModel;
/**
- * @var CatalogHelper|\PHPUnit_Framework_MockObject_MockObject
+ * @var ObjectManager
*/
- private $catalogHelper;
+ private $objectManager;
/**
- * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var CatalogHelper|MockObject
*/
- private $scopeConfig;
+ private $catalogHelperMock;
/**
- * @var ObjectManager
+ * @var ScopeConfigInterface|MockObject
*/
- private $objectManager;
+ private $scopeConfigMock;
/**
- * @var JsonHexTag|\PHPUnit_Framework_MockObject_MockObject
+ * @var JsonHexTag|MockObject
*/
- private $serializer;
+ private $serializerMock;
/**
* @inheritdoc
*/
protected function setUp() : void
{
- $this->catalogHelper = $this->getMockBuilder(CatalogHelper::class)
+ $this->catalogHelperMock = $this->getMockBuilder(CatalogHelper::class)
->setMethods(['getProduct'])
->disableOriginalConstructor()
->getMock();
- $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class)
+ $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
->setMethods(['getValue', 'isSetFlag'])
->disableOriginalConstructor()
->getMockForAbstractClass();
- $escaper = $this->getObjectManager()->getObject(\Magento\Framework\Escaper::class);
+ $escaper = $this->getObjectManager()->getObject(Escaper::class);
- $this->serializer = $this->createMock(JsonHexTag::class);
+ $this->serializerMock = $this->createMock(JsonHexTag::class);
$this->viewModel = $this->getObjectManager()->getObject(
Breadcrumbs::class,
[
- 'catalogData' => $this->catalogHelper,
- 'scopeConfig' => $this->scopeConfig,
+ 'catalogData' => $this->catalogHelperMock,
+ 'scopeConfig' => $this->scopeConfigMock,
'escaper' => $escaper,
- 'jsonSerializer' => $this->serializer
+ 'jsonSerializer' => $this->serializerMock
]
);
}
@@ -79,9 +86,9 @@ protected function setUp() : void
*/
public function testGetCategoryUrlSuffix() : void
{
- $this->scopeConfig->expects($this->once())
+ $this->scopeConfigMock->expects($this->once())
->method('getValue')
- ->with('catalog/seo/category_url_suffix', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+ ->with(static::XML_PATH_CATEGORY_URL_SUFFIX, ScopeInterface::SCOPE_STORE)
->willReturn('.html');
$this->assertEquals('.html', $this->viewModel->getCategoryUrlSuffix());
@@ -92,9 +99,9 @@ public function testGetCategoryUrlSuffix() : void
*/
public function testIsCategoryUsedInProductUrl() : void
{
- $this->scopeConfig->expects($this->once())
+ $this->scopeConfigMock->expects($this->once())
->method('isSetFlag')
- ->with('catalog/seo/product_use_categories', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+ ->with(static::XML_PATH_PRODUCT_USE_CATEGORIES, ScopeInterface::SCOPE_STORE)
->willReturn(false);
$this->assertFalse($this->viewModel->isCategoryUsedInProductUrl());
@@ -105,11 +112,12 @@ public function testIsCategoryUsedInProductUrl() : void
*
* @param Product|null $product
* @param string $expectedName
+ *
* @return void
*/
public function testGetProductName($product, string $expectedName) : void
{
- $this->catalogHelper->expects($this->atLeastOnce())
+ $this->catalogHelperMock->expects($this->atLeastOnce())
->method('getProduct')
->willReturn($product);
@@ -132,27 +140,26 @@ public function productDataProvider() : array
*
* @param Product|null $product
* @param string $expectedJson
+ *
* @return void
*/
- public function testGetJsonConfiguration($product, string $expectedJson) : void
+ public function testGetJsonConfigurationHtmlEscaped($product, string $expectedJson) : void
{
- $this->catalogHelper->expects($this->atLeastOnce())
+ $this->catalogHelperMock->expects($this->atLeastOnce())
->method('getProduct')
->willReturn($product);
- $this->scopeConfig->expects($this->any())
- ->method('isSetFlag')
- ->with('catalog/seo/product_use_categories', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+ $this->scopeConfigMock->method('isSetFlag')
+ ->with(static::XML_PATH_PRODUCT_USE_CATEGORIES, ScopeInterface::SCOPE_STORE)
->willReturn(false);
- $this->scopeConfig->expects($this->any())
- ->method('getValue')
- ->with('catalog/seo/category_url_suffix', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+ $this->scopeConfigMock->method('getValue')
+ ->with(static::XML_PATH_CATEGORY_URL_SUFFIX, ScopeInterface::SCOPE_STORE)
->willReturn('."html');
- $this->serializer->expects($this->once())->method('serialize')->willReturn($expectedJson);
+ $this->serializerMock->expects($this->once())->method('serialize')->willReturn($expectedJson);
- $this->assertEquals($expectedJson, $this->viewModel->getJsonConfiguration());
+ $this->assertEquals($expectedJson, $this->viewModel->getJsonConfigurationHtmlEscaped());
}
/**
diff --git a/app/code/Magento/Catalog/ViewModel/Product/Breadcrumbs.php b/app/code/Magento/Catalog/ViewModel/Product/Breadcrumbs.php
index 1aad46fc1e2f5..d3c8c406ee34d 100644
--- a/app/code/Magento/Catalog/ViewModel/Product/Breadcrumbs.php
+++ b/app/code/Magento/Catalog/ViewModel/Product/Breadcrumbs.php
@@ -3,26 +3,27 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Catalog\ViewModel\Product;
use Magento\Catalog\Helper\Data;
use Magento\Framework\App\Config\ScopeConfigInterface;
-use Magento\Framework\App\ObjectManager;
use Magento\Framework\DataObject;
-use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Serialize\Serializer\JsonHexTag;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Magento\Framework\Escaper;
+use Magento\Store\Model\ScopeInterface;
/**
* Product breadcrumbs view model.
*/
class Breadcrumbs extends DataObject implements ArgumentInterface
{
+ private const XML_PATH_CATEGORY_URL_SUFFIX = 'catalog/seo/category_url_suffix';
+ private const XML_PATH_PRODUCT_USE_CATEGORIES = 'catalog/seo/product_use_categories';
+
/**
- * Catalog data.
- *
* @var Data
*/
private $catalogData;
@@ -45,24 +46,21 @@ class Breadcrumbs extends DataObject implements ArgumentInterface
/**
* @param Data $catalogData
* @param ScopeConfigInterface $scopeConfig
- * @param Json|null $json
- * @param Escaper|null $escaper
- * @param JsonHexTag|null $jsonSerializer
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @param Escaper $escaper
+ * @param JsonHexTag $jsonSerializer
*/
public function __construct(
Data $catalogData,
ScopeConfigInterface $scopeConfig,
- Json $json = null,
- Escaper $escaper = null,
- JsonHexTag $jsonSerializer = null
+ Escaper $escaper,
+ JsonHexTag $jsonSerializer
) {
parent::__construct();
$this->catalogData = $catalogData;
$this->scopeConfig = $scopeConfig;
- $this->escaper = $escaper ?: ObjectManager::getInstance()->get(Escaper::class);
- $this->jsonSerializer = $jsonSerializer ?: ObjectManager::getInstance()->get(JsonHexTag::class);
+ $this->escaper = $escaper;
+ $this->jsonSerializer = $jsonSerializer;
}
/**
@@ -73,8 +71,8 @@ public function __construct(
public function getCategoryUrlSuffix()
{
return $this->scopeConfig->getValue(
- 'catalog/seo/category_url_suffix',
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ static::XML_PATH_CATEGORY_URL_SUFFIX,
+ ScopeInterface::SCOPE_STORE
);
}
@@ -86,8 +84,8 @@ public function getCategoryUrlSuffix()
public function isCategoryUsedInProductUrl(): bool
{
return $this->scopeConfig->isSetFlag(
- 'catalog/seo/product_use_categories',
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ static::XML_PATH_PRODUCT_USE_CATEGORIES,
+ ScopeInterface::SCOPE_STORE
);
}
@@ -108,7 +106,7 @@ public function getProductName(): string
*
* @return string
*/
- public function getJsonConfigurationHtmlEscaped() : string
+ public function getJsonConfigurationHtmlEscaped(): string
{
return $this->jsonSerializer->serialize(
[
@@ -120,15 +118,4 @@ public function getJsonConfigurationHtmlEscaped() : string
]
);
}
-
- /**
- * Returns breadcrumb json.
- *
- * @return string
- * @deprecated in favor of new method with name {suffix}Html{postfix}()
- */
- public function getJsonConfiguration()
- {
- return $this->getJsonConfigurationHtmlEscaped();
- }
}
diff --git a/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml b/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml
index db44d8b62dc1a..4fe7af7f34683 100644
--- a/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml
+++ b/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml
@@ -1,17 +1,14 @@
+
-
-
-
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
-
\ No newline at end of file
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml
index ebbd9ce469587..87c612db08698 100644
--- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml
@@ -15,9 +15,13 @@
-
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminGridCustomerGroupEditByCodeActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminGridCustomerGroupEditByCodeActionGroup.xml
new file mode 100644
index 0000000000000..68620931393c4
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminGridCustomerGroupEditByCodeActionGroup.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/NavigateCustomerGroupActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminNavigateToCustomerGroupPageActionGroup.xml
similarity index 89%
rename from app/code/Magento/Customer/Test/Mftf/ActionGroup/NavigateCustomerGroupActionGroup.xml
rename to app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminNavigateToCustomerGroupPageActionGroup.xml
index 78e9a2f18da95..b782436a20949 100644
--- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/NavigateCustomerGroupActionGroup.xml
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminNavigateToCustomerGroupPageActionGroup.xml
@@ -8,7 +8,7 @@
-
+
Goes to the Admin Customer Groups page.
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontCustomerMessagesActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontCustomerMessagesActionGroup.xml
new file mode 100644
index 0000000000000..50e052207bd9e
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontCustomerMessagesActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerNavigateToNewsletterPageActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerNavigateToNewsletterPageActionGroup.xml
new file mode 100644
index 0000000000000..559dee27b551d
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerNavigateToNewsletterPageActionGroup.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerUpdateGeneralSubscriptionActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerUpdateGeneralSubscriptionActionGroup.xml
new file mode 100644
index 0000000000000..16f8b5d17d7e1
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerUpdateGeneralSubscriptionActionGroup.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml
index 5efcfc0e79b0d..46f45ce3802f1 100644
--- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml
@@ -12,6 +12,7 @@ NOTICE: Action Groups in this file are DEPRECATED and SHOULD NOT BE USED anymore
-->
+
Goes to the Customer grid page. Click on 'Add New Customer'. Fills provided Customer Data. Fill provided Customer Address data. Assigns Product to Website and Store View. Clicks on Save.
diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerNewsletterManagePage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerNewsletterManagePage.xml
new file mode 100644
index 0000000000000..62fa49f7b4b38
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerNewsletterManagePage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerNewsletterSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerNewsletterSection.xml
new file mode 100644
index 0000000000000..0275603b26227
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerNewsletterSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminVerifyDisabledCustomerGroupFieldTest.xml
similarity index 56%
rename from app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml
rename to app/code/Magento/Customer/Test/Mftf/Test/AdminVerifyDisabledCustomerGroupFieldTest.xml
index 0f98184aafb4f..e1342f26809ee 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminVerifyDisabledCustomerGroupFieldTest.xml
@@ -8,7 +8,7 @@
-
+
@@ -19,20 +19,20 @@
-
-
-
-
+
-
-
-
+
+
+
+
-
-
+
+
+
-
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml
new file mode 100644
index 0000000000000..4658b162dcc55
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test.xml b/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test.xml
index d3474ff7859d6..424622ef2d735 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test.xml
@@ -7,6 +7,7 @@
-->
+
diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Sold/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Sold/Collection.php
index bca9b8662715a..bc8a67c2addff 100644
--- a/app/code/Magento/Reports/Model/ResourceModel/Product/Sold/Collection.php
+++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Sold/Collection.php
@@ -12,6 +12,7 @@
namespace Magento\Reports\Model\ResourceModel\Product\Sold;
use Magento\Framework\DB\Select;
+use Zend_Db_Select_Exception;
/**
* Data collection.
@@ -25,9 +26,10 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Order\Collection
/**
* Set Date range to collection.
*
- * @param int $from
- * @param int $to
+ * @param string $from
+ * @param string $to
* @return $this
+ * @throws Zend_Db_Select_Exception
*/
public function setDateRange($from, $to)
{
@@ -49,6 +51,7 @@ public function setDateRange($from, $to)
* @param string $from
* @param string $to
* @return $this
+ * @throws Zend_Db_Select_Exception
*/
public function addOrderedQty($from = '', $to = '')
{
diff --git a/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml b/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml
index ce31f588c6c8c..571155185693a 100644
--- a/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml
+++ b/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml
@@ -1,8 +1,10 @@
+
-
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
diff --git a/dev/tests/acceptance/tests/_data/catalog_product_import_bundle.csv b/dev/tests/acceptance/tests/_data/catalog_product_import_bundle.csv
new file mode 100644
index 0000000000000..6804675940a02
--- /dev/null
+++ b/dev/tests/acceptance/tests/_data/catalog_product_import_bundle.csv
@@ -0,0 +1,3 @@
+sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,related_position,crosssell_skus,crosssell_position,upsell_skus,upsell_position,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,bundle_shipment_type,associated_skus,downloadable_links,downloadable_samples,configurable_variations,configurable_variation_labels
+Simple,,Default,simple,"Default Category/New",base,Simple,,,1.000000,1,"Taxable Goods","Catalog, Search",100.000000,,,,simple,Simple,Simple,"Simple ",,,,,,,,,"3/18/20, 6:56 AM","3/18/20, 6:56 AM",,,"Block after Info Column",,,,"Use config",,,,,,,"Use config",,,1000.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,1,1,1.0000,1,0,0,0,,,,,,,,,,,,,,,,,,,,,
+Bundle,,Default,bundle,"Default Category/New",base,Bundle,,,,1,"Taxable Goods","Catalog, Search",,,,,bundle,Bundle,Bundle,"Bundle ",,,,,,,,,"3/18/20, 6:57 AM","3/18/20, 6:57 AM",,,"Block after Info Column",,,,"Use config",,,,,,,"Use config",,,0.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,1,1,1.0000,1,0,0,0,,,,,,,,,,,dynamic,dynamic,"Price range",dynamic,"name=Test Option,type=select,required=1,sku=Simple,price=0.0000,default=1,default_qty=1.0000,price_type=fixed,can_change_qty=0",together,,,,,
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/ConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/ConfigTest.php
new file mode 100644
index 0000000000000..2d4a1dc0c2ce3
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/ConfigTest.php
@@ -0,0 +1,89 @@
+markTestSkipped('Skipped on HHVM. Will be fixed in MAGETWO-45033');
+ }
+ $this->urnResolver = new UrnResolver();
+ $this->xsdSchema = $this->urnResolver->getRealPath(
+ 'urn:magento:framework:Cache/etc/cache.xsd'
+ );
+ $this->xsdValidator = new XsdValidator();
+ }
+
+ /**
+ * Tests invalid configurations
+ *
+ * @param string $xmlString
+ * @param array $expectedError
+ * @dataProvider schemaCorrectlyIdentifiesInvalidXmlDataProvider
+ */
+ public function testSchemaCorrectlyIdentifiesInvalidXml(
+ string $xmlString,
+ array $expectedError
+ ): void {
+ $actualError = $this->xsdValidator->validate(
+ $this->xsdSchema,
+ $xmlString
+ );
+ $this->assertEquals($expectedError, $actualError);
+ }
+
+ /**
+ * Tests valid configurations
+ */
+ public function testSchemaCorrectlyIdentifiesValidXml(): void
+ {
+ $xmlString = file_get_contents(__DIR__ . '/_files/valid_cache_config.xml');
+ $actualResult = $this->xsdValidator->validate(
+ $this->xsdSchema,
+ $xmlString
+ );
+
+ $this->assertEmpty($actualResult);
+ }
+
+ /**
+ * Data provider with invalid xml array according to cache.xsd
+ */
+ public function schemaCorrectlyIdentifiesInvalidXmlDataProvider(): array
+ {
+ return include __DIR__ . '/_files/invalidCacheConfigXmlArray.php';
+ }
+}
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/invalidCacheConfigXmlArray.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/invalidCacheConfigXmlArray.php
new file mode 100644
index 0000000000000..8d2d631334a9b
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/invalidCacheConfigXmlArray.php
@@ -0,0 +1,52 @@
+ [
+ '',
+ ["Element 'config': Missing child element(s). Expected is ( type ).\nLine: 1\n"],
+ ],
+ 'cache_config_with_notallowed_attribute' => [
+ '' .
+ '' .
+ 'Test',
+ ["Element 'type', attribute 'notallowed': The attribute 'notallowed' is not allowed.\nLine: 1\n"],
+ ],
+ 'cache_config_without_name_attribute' => [
+ '' .
+ 'Test',
+ ["Element 'type': The attribute 'name' is required but missing.\nLine: 1\n"],
+ ],
+ 'cache_config_without_instance_attribute' => [
+ '' .
+ 'Test',
+ ["Element 'type': The attribute 'instance' is required but missing.\nLine: 1\n"],
+ ],
+ 'cache_config_without_label_element' => [
+ '' .
+ 'Test',
+ ["Element 'type': Missing child element(s). Expected is ( label ).\nLine: 1\n"],
+ ],
+ 'cache_config_without_description_element' => [
+ '' .
+ '',
+ ["Element 'type': Missing child element(s). Expected is ( description ).\nLine: 1\n"],
+ ],
+ 'cache_config_without_child_elements' => [
+ '' .
+ '',
+ ["Element 'type': Missing child element(s). Expected is one of ( label, description ).\nLine: 1\n"],
+ ],
+ 'cache_config_cache_name_not_unique' => [
+ '' .
+ 'Test1' .
+ '' .
+ 'Test2',
+ [
+ "Element 'type': Duplicate key-sequence ['test'] in unique identity-constraint"
+ . " 'uniqueCacheName'.\nLine: 1\n"
+ ],
+ ],
+];
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/valid_cache_config.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/valid_cache_config.xml
new file mode 100644
index 0000000000000..ef45c083daf0d
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Cache/_files/valid_cache_config.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ Type1
+
+
+
+ Type2
+
+
diff --git a/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php b/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
index 97c24167d47e1..902709bbedcd3 100644
--- a/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
+++ b/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
@@ -11,7 +11,10 @@
* Base Class for extensible data Objects
*
* @SuppressWarnings(PHPMD.NumberOfChildren)
+ * phpcs:disable Magento2.Classes.AbstractApi
* @api
+ * @deprecated
+ * @see \Magento\Framework\Model\AbstractExtensibleModel
*/
abstract class AbstractExtensibleObject extends AbstractSimpleObject implements CustomAttributesDataInterface
{
diff --git a/lib/internal/Magento/Framework/App/Cache/TypeList.php b/lib/internal/Magento/Framework/App/Cache/TypeList.php
index b695ee3a37fa8..c0790c4d40ad4 100644
--- a/lib/internal/Magento/Framework/App/Cache/TypeList.php
+++ b/lib/internal/Magento/Framework/App/Cache/TypeList.php
@@ -8,6 +8,9 @@
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Serialize\SerializerInterface;
+/**
+ * Application cache type list
+ */
class TypeList implements TypeListInterface
{
const INVALIDATED_TYPES = 'core_cache_invalidate';
@@ -68,9 +71,7 @@ public function __construct(
protected function _getTypeInstance($type)
{
$config = $this->_config->getType($type);
- if (!isset($config['instance'])) {
- return null;
- }
+
return $this->_factory->get($config['instance']);
}
@@ -132,7 +133,7 @@ public function getTypes()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getTypeLabels()
{
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/TypeListTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/TypeListTest.php
index 8d9b297d7dded..02c9a872fe97f 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/TypeListTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/TypeListTest.php
@@ -6,21 +6,30 @@
namespace Magento\Framework\App\Test\Unit\Cache;
-use \Magento\Framework\App\Cache\TypeList;
+use Magento\Framework\App\Cache\InstanceFactory;
+use Magento\Framework\App\Cache\StateInterface;
+use Magento\Framework\App\Cache\TypeList;
+use Magento\Framework\App\CacheInterface;
+use Magento\Framework\Cache\Frontend\Decorator\TagScope;
+use Magento\Framework\Cache\ConfigInterface;
+use Magento\Framework\DataObject;
use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
/**
* Test class for \Magento\Framework\App\Cache\TypeList
*/
-class TypeListTest extends \PHPUnit\Framework\TestCase
+class TypeListTest extends TestCase
{
/**
- * @var \Magento\Framework\App\Cache\TypeList
+ * @var TypeList
*/
protected $_typeList;
/**
- * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var CacheInterface|MockObject
*/
protected $_cache;
@@ -30,7 +39,7 @@ class TypeListTest extends \PHPUnit\Framework\TestCase
protected $_typesArray;
/**
- * @var \Magento\Framework\Cache\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var ConfigInterface|MockObject
*/
protected $_config;
@@ -47,10 +56,10 @@ class TypeListTest extends \PHPUnit\Framework\TestCase
/**
* Expected cache type
*/
- const CACHE_TYPE = \Magento\Framework\Cache\FrontendInterface::class;
+ const CACHE_TYPE = TagScope::class;
/**
- * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var SerializerInterface|MockObject
*/
private $serializerMock;
@@ -58,33 +67,44 @@ protected function setUp()
{
$this->_typesArray = [
self::TYPE_KEY => [
+ 'name' => self::TYPE_KEY,
+ 'instance' => self::CACHE_TYPE,
'label' => 'Type Label',
'description' => 'Type Description',
],
];
- $this->_config =
- $this->createPartialMock(\Magento\Framework\Cache\ConfigInterface::class, ['getTypes', 'getType']);
- $this->_config->expects($this->any())->method('getTypes')->will($this->returnValue($this->_typesArray));
+ $this->_config = $this->createPartialMock(
+ ConfigInterface::class,
+ ['getTypes', 'getType']
+ );
+ $this->_config->expects($this->any())->method('getTypes')
+ ->will($this->returnValue($this->_typesArray));
+ $this->_config->expects($this->any())->method('getType')
+ ->with(self::TYPE_KEY)
+ ->will($this->returnValue($this->_typesArray[self::TYPE_KEY]));
$cacheState = $this->createPartialMock(
- \Magento\Framework\App\Cache\StateInterface::class,
+ StateInterface::class,
['isEnabled', 'setEnabled', 'persist']
);
- $cacheState->expects($this->any())->method('isEnabled')->will($this->returnValue(self::IS_CACHE_ENABLED));
- $cacheBlockMock = $this->createMock(self::CACHE_TYPE);
- $factory = $this->createPartialMock(\Magento\Framework\App\Cache\InstanceFactory::class, ['get']);
- $factory->expects($this->any())->method('get')->with(self::CACHE_TYPE)->will(
- $this->returnValue($cacheBlockMock)
- );
+ $cacheState->expects($this->any())->method('isEnabled')
+ ->will($this->returnValue(self::IS_CACHE_ENABLED));
+ $cacheTypeMock = $this->createMock(self::CACHE_TYPE);
+ $cacheTypeMock->expects($this->any())->method('getTag')
+ ->will($this->returnValue('TEST'));
+ $factory = $this->createPartialMock(InstanceFactory::class, ['get']);
+ $factory->expects($this->any())->method('get')
+ ->with(self::CACHE_TYPE)
+ ->will($this->returnValue($cacheTypeMock));
$this->_cache = $this->createPartialMock(
- \Magento\Framework\App\CacheInterface::class,
+ CacheInterface::class,
['load', 'getFrontend', 'save', 'remove', 'clean']
);
$this->serializerMock = $this->createMock(SerializerInterface::class);
- $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $objectHelper = new ObjectManager($this);
$this->_typeList = $objectHelper->getObject(
- \Magento\Framework\App\Cache\TypeList::class,
+ TypeList::class,
[
'config' => $this->_config,
'cacheState' => $cacheState,
@@ -114,9 +134,9 @@ public function testGetTypeLabels()
public function testGetInvalidated()
{
$expectation = [self::TYPE_KEY => $this->_getPreparedType()];
- $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
- $this->returnValue('serializedData')
- );
+ $this->_cache->expects($this->once())->method('load')
+ ->with(TypeList::INVALIDATED_TYPES)
+ ->will($this->returnValue('serializedData'));
$this->serializerMock->expects($this->once())
->method('unserialize')
->with('serializedData')
@@ -127,9 +147,9 @@ public function testGetInvalidated()
public function testInvalidate()
{
// there are no invalidated types
- $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
- $this->returnValue([])
- );
+ $this->_cache->expects($this->once())->method('load')
+ ->with(TypeList::INVALIDATED_TYPES)
+ ->will($this->returnValue([]));
$expectedInvalidated = [
self::TYPE_KEY => 1,
];
@@ -137,18 +157,16 @@ public function testInvalidate()
->method('serialize')
->with($expectedInvalidated)
->willReturn('serializedData');
- $this->_cache->expects($this->once())->method('save')->with(
- 'serializedData',
- TypeList::INVALIDATED_TYPES
- );
+ $this->_cache->expects($this->once())->method('save')
+ ->with('serializedData', TypeList::INVALIDATED_TYPES);
$this->_typeList->invalidate(self::TYPE_KEY);
}
public function testInvalidateList()
{
- $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
- $this->returnValue([])
- );
+ $this->_cache->expects($this->once())->method('load')
+ ->with(TypeList::INVALIDATED_TYPES)
+ ->will($this->returnValue([]));
$expectedInvalidated = [
self::TYPE_KEY => 1,
];
@@ -156,10 +174,8 @@ public function testInvalidateList()
->method('serialize')
->with($expectedInvalidated)
->willReturn('serializedData');
- $this->_cache->expects($this->once())->method('save')->with(
- 'serializedData',
- TypeList::INVALIDATED_TYPES
- );
+ $this->_cache->expects($this->once())->method('save')
+ ->with('serializedData', TypeList::INVALIDATED_TYPES);
$this->_typeList->invalidate([self::TYPE_KEY]);
}
@@ -169,38 +185,36 @@ public function testCleanType()
->method('unserialize')
->with('serializedData')
->willReturn($this->_typesArray);
- $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
- $this->returnValue('serializedData')
- );
- $this->_config->expects($this->once())->method('getType')->with(self::TYPE_KEY)->will(
- $this->returnValue(['instance' => self::CACHE_TYPE])
- );
+ $this->_cache->expects($this->once())->method('load')
+ ->with(TypeList::INVALIDATED_TYPES)
+ ->will($this->returnValue('serializedData'));
+ $this->_config->expects($this->once())->method('getType')
+ ->with(self::TYPE_KEY)
+ ->will($this->returnValue(['instance' => self::CACHE_TYPE]));
unset($this->_typesArray[self::TYPE_KEY]);
$this->serializerMock->expects($this->once())
->method('serialize')
->with($this->_typesArray)
->willReturn('serializedData');
- $this->_cache->expects($this->once())->method('save')->with(
- 'serializedData',
- TypeList::INVALIDATED_TYPES
- );
+ $this->_cache->expects($this->once())->method('save')
+ ->with('serializedData', TypeList::INVALIDATED_TYPES);
$this->_typeList->cleanType(self::TYPE_KEY);
}
/**
* Returns prepared type
*
- * @return \Magento\Framework\DataObject
+ * @return DataObject
*/
private function _getPreparedType()
{
- return new \Magento\Framework\DataObject(
+ return new DataObject(
[
'id' => self::TYPE_KEY,
'cache_type' => $this->_typesArray[self::TYPE_KEY]['label'],
'description' => $this->_typesArray[self::TYPE_KEY]['description'],
- 'tags' => '',
- 'status' => self::IS_CACHE_ENABLED,
+ 'tags' => 'TEST',
+ 'status' => (int)self::IS_CACHE_ENABLED,
]
);
}
diff --git a/lib/internal/Magento/Framework/Cache/Config/Reader.php b/lib/internal/Magento/Framework/Cache/Config/Reader.php
index 445e91240e7e5..942a3931e0173 100644
--- a/lib/internal/Magento/Framework/Cache/Config/Reader.php
+++ b/lib/internal/Magento/Framework/Cache/Config/Reader.php
@@ -3,9 +3,19 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Framework\Cache\Config;
-class Reader extends \Magento\Framework\Config\Reader\Filesystem
+use Magento\Framework\App\Area;
+use Magento\Framework\Config\Dom;
+use Magento\Framework\Config\FileResolverInterface;
+use Magento\Framework\Config\Reader\Filesystem;
+use Magento\Framework\Config\ValidationStateInterface;
+
+/**
+ * Cache configuration reader
+ */
+class Reader extends Filesystem
{
/**
* List of id attributes for merge
@@ -15,24 +25,27 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem
protected $_idAttributes = ['/config/type' => 'name'];
/**
- * @param \Magento\Framework\Config\FileResolverInterface $fileResolver
+ * Initialize dependencies.
+ *
+ * @param FileResolverInterface $fileResolver
* @param Converter $converter
* @param SchemaLocator $schemaLocator
- * @param \Magento\Framework\Config\ValidationStateInterface $validationState
+ * @param ValidationStateInterface $validationState
* @param string $fileName
* @param array $idAttributes
* @param string $domDocumentClass
* @param string $defaultScope
+ * phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod
*/
public function __construct(
- \Magento\Framework\Config\FileResolverInterface $fileResolver,
- \Magento\Framework\Cache\Config\Converter $converter,
- \Magento\Framework\Cache\Config\SchemaLocator $schemaLocator,
- \Magento\Framework\Config\ValidationStateInterface $validationState,
+ FileResolverInterface $fileResolver,
+ Converter $converter,
+ SchemaLocator $schemaLocator,
+ ValidationStateInterface $validationState,
$fileName = 'cache.xml',
$idAttributes = [],
- $domDocumentClass = \Magento\Framework\Config\Dom::class,
- $defaultScope = 'global'
+ $domDocumentClass = Dom::class,
+ $defaultScope = Area::AREA_GLOBAL
) {
parent::__construct(
$fileResolver,
diff --git a/lib/internal/Magento/Framework/Cache/Config/SchemaLocator.php b/lib/internal/Magento/Framework/Cache/Config/SchemaLocator.php
index 5471dbcfb6c62..2d3be1b1a4067 100644
--- a/lib/internal/Magento/Framework/Cache/Config/SchemaLocator.php
+++ b/lib/internal/Magento/Framework/Cache/Config/SchemaLocator.php
@@ -7,6 +7,9 @@
*/
namespace Magento\Framework\Cache\Config;
+/**
+ * Cache configuration schema locator
+ */
class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
{
/**
@@ -15,6 +18,9 @@ class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
protected $urnResolver;
/**
+ * Initialize dependencies.
+ *
+ * @param \Magento\Framework\Config\Dom\UrnResolver $urnResolver
*/
public function __construct(\Magento\Framework\Config\Dom\UrnResolver $urnResolver)
{
@@ -25,6 +31,7 @@ public function __construct(\Magento\Framework\Config\Dom\UrnResolver $urnResolv
* Get path to merged config schema
*
* @return string|null
+ * @throws \Magento\Framework\Exception\NotFoundException
*/
public function getSchema()
{
@@ -34,10 +41,11 @@ public function getSchema()
/**
* Get path to pre file validation schema
*
- * @return null
+ * @return string|null
+ * @throws \Magento\Framework\Exception\NotFoundException
*/
public function getPerFileSchema()
{
- return null;
+ return $this->urnResolver->getRealPath('urn:magento:framework:Cache/etc/cache.xsd');
}
}
diff --git a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/ConverterTest.php b/lib/internal/Magento/Framework/Cache/Test/Unit/Config/ConverterTest.php
deleted file mode 100644
index 7f86e162311c8..0000000000000
--- a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/ConverterTest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-_model = new \Magento\Framework\Cache\Config\Converter();
- }
-
- public function testConvert()
- {
- $dom = new \DOMDocument();
- $xmlFile = __DIR__ . '/_files/cache_config.xml';
- $dom->loadXML(file_get_contents($xmlFile));
-
- $convertedFile = __DIR__ . '/_files/cache_config.php';
- $expectedResult = include $convertedFile;
- $this->assertEquals($expectedResult, $this->_model->convert($dom));
- }
-}
diff --git a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.php b/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.php
deleted file mode 100644
index 0a45e50bbe198..0000000000000
--- a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.php
+++ /dev/null
@@ -1,23 +0,0 @@
- [
- 'config' => [
- 'name' => 'config',
- 'translate' => 'label,description',
- 'instance' => \Magento\Framework\App\Cache\Type\Config::class,
- 'label' => 'Configuration',
- 'description' => 'Cache Description',
- ],
- 'layout' => [
- 'name' => 'layout',
- 'translate' => 'label,description',
- 'instance' => \Magento\Framework\App\Cache\Type\Layout::class,
- 'label' => 'Layouts',
- 'description' => 'Layout building instructions',
- ],
- ]
-];
diff --git a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.xml b/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.xml
deleted file mode 100644
index 315ddd9cec67c..0000000000000
--- a/lib/internal/Magento/Framework/Cache/Test/Unit/Config/_files/cache_config.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
- Cache Description
-
-
-
- Layout building instructions
-
-
diff --git a/lib/internal/Magento/Framework/Cache/etc/cache.xsd b/lib/internal/Magento/Framework/Cache/etc/cache.xsd
index 74b831bb6ac03..d997e295140f5 100644
--- a/lib/internal/Magento/Framework/Cache/etc/cache.xsd
+++ b/lib/internal/Magento/Framework/Cache/etc/cache.xsd
@@ -6,24 +6,36 @@
*/
-->
-
-
-
-
-
-
-
-
- Cache type declaration
+
+ Cache type declaration
+
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+ Cache name must be unique.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
index c1f44da5b2f19..5484103cc27ef 100644
--- a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
@@ -15,6 +15,8 @@
* This class defines basic data structure of how custom attributes are stored in an ExtensibleModel.
* Implementations may choose to process custom attributes as their persistence requires them to.
* @SuppressWarnings(PHPMD.NumberOfChildren)
+ * phpcs:disable Magento2.Classes.AbstractApi
+ * @api
*/
abstract class AbstractExtensibleModel extends AbstractModel implements
\Magento\Framework\Api\CustomAttributesDataInterface
diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
index 7ac93c7b94305..646908f99693c 100644
--- a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
+++ b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
@@ -13,13 +13,6 @@
*/
class DateTime
{
- /**
- * Current config offset in seconds
- *
- * @var int
- */
- private $_offset = 0;
-
/**
* @var TimezoneInterface
*/
@@ -31,7 +24,6 @@ class DateTime
public function __construct(TimezoneInterface $localeDate)
{
$this->_localeDate = $localeDate;
- $this->_offset = $this->calculateOffset($this->_localeDate->getConfigTimezone());
}
/**
@@ -78,8 +70,7 @@ public function gmtDate($format = null, $input = null)
}
/**
- * Converts input date into date with timezone offset
- * Input date must be in GMT timezone
+ * Converts input date into date with timezone offset. Input date must be in GMT timezone.
*
* @param string $format
* @param int|string $input date in GMT timezone
@@ -122,8 +113,7 @@ public function gmtTimestamp($input = null)
}
/**
- * Converts input date into timestamp with timezone offset
- * Input date must be in GMT timezone
+ * Converts input date into timestamp with timezone offset. Input date must be in GMT timezone.
*
* @param int|string $input date in GMT timezone
* @return int
@@ -157,18 +147,18 @@ public function timestamp($input = null)
*/
public function getGmtOffset($type = 'seconds')
{
- $result = $this->_offset;
+ $offset = $this->calculateOffset($this->_localeDate->getConfigTimezone());
switch ($type) {
case 'seconds':
default:
break;
case 'minutes':
- $result = $result / 60;
+ $offset = $offset / 60;
break;
case 'hours':
- $result = $result / 60 / 60;
+ $offset = $offset / 60 / 60;
break;
}
- return $result;
+ return $offset;
}
}
diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/DateTimeTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/DateTimeTest.php
index f86269b1647b2..3c7f49671d74a 100644
--- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/DateTimeTest.php
+++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/DateTimeTest.php
@@ -46,6 +46,21 @@ public function testTimestamp($input)
$this->assertEquals($expected, (new DateTime($timezone))->timestamp($input));
}
+ public function testGtmOffset()
+ {
+ /** @var TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject $timezone */
+ $timezone = $this->getMockBuilder(TimezoneInterface::class)->getMock();
+ $timezone->method('getConfigTimezone')->willReturn('Europe/Amsterdam');
+
+ /** @var DateTime|\PHPUnit_Framework_MockObject_MockObject $dateTime */
+ $dateTime = $this->getMockBuilder(DateTime::class)
+ ->setConstructorArgs([$timezone])
+ ->setMethods(null)
+ ->getMock();
+
+ $this->assertEquals(3600, $dateTime->getGmtOffset());
+ }
+
/**
* @return array
*/