diff --git a/app/code/Magento/Bundle/Model/Product/LinksList.php b/app/code/Magento/Bundle/Model/Product/LinksList.php index aeb71d0e434ab..c35d475e04d84 100644 --- a/app/code/Magento/Bundle/Model/Product/LinksList.php +++ b/app/code/Magento/Bundle/Model/Product/LinksList.php @@ -39,6 +39,8 @@ public function __construct( } /** + * Bundle Product Items Data + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param int $optionId * @return \Magento\Bundle\Api\Data\LinkInterface[] @@ -50,8 +52,12 @@ public function getItems(\Magento\Catalog\Api\Data\ProductInterface $product, $o $productLinks = []; /** @var \Magento\Catalog\Model\Product $selection */ foreach ($selectionCollection as $selection) { + $bundledProductPrice = $selection->getSelectionPriceValue(); + if ($bundledProductPrice <= 0) { + $bundledProductPrice = $selection->getPrice(); + } $selectionPriceType = $product->getPriceType() ? $selection->getSelectionPriceType() : null; - $selectionPrice = $product->getPriceType() ? $selection->getSelectionPriceValue() : null; + $selectionPrice = $bundledProductPrice ? $bundledProductPrice : null; /** @var \Magento\Bundle\Api\Data\LinkInterface $productLink */ $productLink = $this->linkFactory->create(); diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/LinksListTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/LinksListTest.php index fbc3b5e87ac97..27531682b1de2 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/LinksListTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/LinksListTest.php @@ -91,7 +91,7 @@ public function testLinksList() ->method('getSelectionsCollection') ->with([$optionId], $this->productMock) ->willReturn([$this->selectionMock]); - $this->productMock->expects($this->exactly(2))->method('getPriceType')->willReturn('price_type'); + $this->productMock->expects($this->once())->method('getPriceType')->willReturn('price_type'); $this->selectionMock->expects($this->once()) ->method('getSelectionPriceType') ->willReturn('selection_price_type'); diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml index c805941fa0272..6a47978f1e5c6 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml @@ -98,7 +98,8 @@ $_helper = $block->getData('outputHelper'); getBlockHtml('formkey') ?> diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js index 7d3e4b3280473..fbce6691fd66a 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js @@ -34,6 +34,7 @@ define([ if (this.options.bindSubmit) { this._bindSubmit(); } + $(this.options.addToCartButtonSelector).attr('disabled', false); }, /** diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml index eee9f742a59a4..e9d0c065fd8bf 100644 --- a/app/code/Magento/Contact/view/frontend/templates/form.phtml +++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml @@ -69,8 +69,8 @@ $viewModel = $block->getViewModel(); class="input-text" cols="5" rows="3" - data-validate="{required:true}">escapeHtml($viewModel->getUserComment()) ?> - + data-validate="{required:true}" + >escapeHtml($viewModel->getUserComment()) ?> getChildHtml('form.additional.info') ?> diff --git a/app/code/Magento/CurrencySymbol/Block/Adminhtml/System/Currency.php b/app/code/Magento/CurrencySymbol/Block/Adminhtml/System/Currency.php index ec73ac0cf7aa5..9e7a2b69f20a5 100644 --- a/app/code/Magento/CurrencySymbol/Block/Adminhtml/System/Currency.php +++ b/app/code/Magento/CurrencySymbol/Block/Adminhtml/System/Currency.php @@ -41,7 +41,14 @@ protected function _prepareLayout() ] ); - $onClick = "setLocation('" . $this->getUrl('adminhtml/system_config/edit/section/currency') . "')"; + $currencyOptionPath = $this->getUrl( + 'adminhtml/system_config/edit', + [ + 'section' => 'currency', + '_fragment' => 'currency_options-link' + ] + ); + $onClick = "setLocation('$currencyOptionPath')"; $this->getToolbar()->addChild( 'options_button', diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminNavigateToCurrencyRatesOptionActionGroup.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminNavigateToCurrencyRatesOptionActionGroup.xml new file mode 100644 index 0000000000000..39f37c745998e --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminNavigateToCurrencyRatesOptionActionGroup.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml index bc80a51c41c47..10f345ec69369 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml @@ -11,6 +11,7 @@
+ diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyOptionsSystemConfigExpandedTabTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyOptionsSystemConfigExpandedTabTest.xml new file mode 100644 index 0000000000000..4e0eb72df3aa5 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyOptionsSystemConfigExpandedTabTest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + <description value="Check auto open the collapse on Currency Option page."/> + <severity value="MINOR"/> + <testCaseId value="MC-37425"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToStoresCurrencyRatesPage"> + <argument name="menuUiId" value="{{AdminMenuStores.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuStoresCurrencyCurrencyRates.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminNavigateToCurrencyRatesOptionActionGroup" stepKey="navigateToOptions" /> + <grabAttributeFrom selector="{{CurrencySetupSection.currencyOptions}}" userInput="class" stepKey="grabClass"/> + <assertStringContainsString stepKey="assertClass"> + <actualResult type="string">{$grabClass}</actualResult> + <expectedResult type="string">open</expectedResult> + </assertStringContainsString> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/CurrencySymbol/Test/Unit/Block/Adminhtml/System/CurrencyTest.php b/app/code/Magento/CurrencySymbol/Test/Unit/Block/Adminhtml/System/CurrencyTest.php index aa7cd06666121..4b86df94b4556 100644 --- a/app/code/Magento/CurrencySymbol/Test/Unit/Block/Adminhtml/System/CurrencyTest.php +++ b/app/code/Magento/CurrencySymbol/Test/Unit/Block/Adminhtml/System/CurrencyTest.php @@ -7,15 +7,22 @@ namespace Magento\CurrencySymbol\Test\Unit\Block\Adminhtml\System; +use Magento\Backend\Block\Template\Context; use Magento\Backend\Block\Widget\Button; use Magento\CurrencySymbol\Block\Adminhtml\System\Currency; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\BlockInterface; use Magento\Framework\View\LayoutInterface; use PHPUnit\Framework\TestCase; +use Magento\Framework\UrlInterface; class CurrencyTest extends TestCase { + /** + * Stub currency option link url + */ + const STUB_OPTION_LINK_URL = 'https://localhost/admin/system_config/edit/section/currency#currency_options-link'; + /** * Object manager helper * @@ -70,12 +77,25 @@ public function testPrepareLayout() ] ); + $contextMock = $this->createMock(Context::class); + $urlBuilderMock = $this->createMock(UrlInterface::class); + + $contextMock->expects($this->once())->method('getUrlBuilder')->willReturn($urlBuilderMock); + + $urlBuilderMock->expects($this->once())->method('getUrl')->with( + 'adminhtml/system_config/edit', + [ + 'section' => 'currency', + '_fragment' => 'currency_options-link' + ] + )->willReturn(self::STUB_OPTION_LINK_URL); + $childBlockMock->expects($this->at(1)) ->method('addChild') ->with( 'options_button', Button::class, - ['label' => __('Options'), 'onclick' => 'setLocation(\'\')'] + ['label' => __('Options'), 'onclick' => 'setLocation(\''.self::STUB_OPTION_LINK_URL.'\')'] ); $childBlockMock->expects($this->at(2)) @@ -90,7 +110,8 @@ public function testPrepareLayout() $block = $this->objectManagerHelper->getObject( Currency::class, [ - 'layout' => $layoutMock + 'layout' => $layoutMock, + 'context' => $contextMock ] ); $block->setLayout($layoutMock); diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index f2f767b4e41fa..b3737f67705d1 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -626,6 +626,8 @@ protected function _isApplicableAttribute($object, $attribute) public function walkAttributes($partMethod, array $args = [], $collectExceptionMessages = null) { $methodArr = explode('/', $partMethod); + $part = ''; + $method = ''; switch (count($methodArr)) { case 1: $part = 'attribute'; @@ -642,6 +644,7 @@ public function walkAttributes($partMethod, array $args = [], $collectExceptionM } $results = []; $suffix = $this->getAttributesCacheSuffix($args[0]); + $instance = null; foreach ($this->getAttributesByScope($suffix) as $attrCode => $attribute) { if (isset($args[0]) && is_object($args[0]) && !$this->_isApplicableAttribute($args[0], $attribute)) { continue; @@ -1337,7 +1340,9 @@ protected function _collectSaveData($newObject) if ($this->_canUpdateAttribute($attribute, $v, $origData)) { if ($this->_isAttributeValueEmpty($attribute, $v)) { $this->_aggregateDeleteData($delete, $attribute, $newObject); - } elseif (!is_numeric($v) && $v !== $origData[$k] || is_numeric($v) && $v != $origData[$k]) { + } elseif (!is_numeric($v) && $v !== $origData[$k] + || is_numeric($v) && ($v != $origData[$k] || strlen($v) !== strlen($origData[$k])) + ) { $update[$attrId] = [ 'value_id' => $attribute->getBackend()->getEntityValueId($newObject), 'value' => is_array($v) ? array_shift($v) : $v,//@TODO: MAGETWO-44182, @@ -1739,6 +1744,7 @@ public function delete($object) { try { $connection = $this->transactionManager->start($this->getConnection()); + $id = 0; if (is_numeric($object)) { $id = (int) $object; } elseif ($object instanceof \Magento\Framework\Model\AbstractModel) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 25e691972d81d..261f8d84b5baa 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -497,6 +497,12 @@ protected function prepareIndex($storeId, $indexName, $mappedIndexerId) */ private function getMappingTotalFieldsLimit(array $allAttributeTypes): int { - return count($allAttributeTypes) + self::MAPPING_TOTAL_FIELDS_BUFFER_LIMIT; + $count = count($allAttributeTypes); + foreach ($allAttributeTypes as $attributeType) { + if (isset($attributeType['fields'])) { + $count += count($attributeType['fields']); + } + } + return $count + self::MAPPING_TOTAL_FIELDS_BUFFER_LIMIT; } } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/ElasticsearchTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/ElasticsearchTest.php index 5abe800884ced..b070e3324ed78 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/ElasticsearchTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/ElasticsearchTest.php @@ -174,7 +174,14 @@ protected function setUp(): void ->method('getAllAttributesTypes') ->willReturn( [ - 'name' => 'string', + 'name' => [ + 'type' => 'string', + 'fields' => [ + 'keyword' => [ + 'type' => "keyword", + ], + ], + ], ] ); $this->clientConfig->expects($this->any()) @@ -564,6 +571,28 @@ public function testUpdateIndexMappingWithAliasDefinition(): void $this->model->updateIndexMapping($storeId, $mappedIndexerId, $attributeCode); } + /** + * Test for get mapping total fields limit + * + * @return void + */ + public function testGetMappingTotalFieldsLimit(): void + { + $settings = [ + 'index' => [ + 'mapping' => [ + 'total_fields' => [ + 'limit' => 1002 + ] + ] + ] + ]; + $this->client->expects($this->at(1)) + ->method('createIndex') + ->with(null, ['settings' => $settings]); + $this->model->cleanIndex(1, 'product'); + } + /** * Get elasticsearch client options * diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order.php b/app/code/Magento/Sales/Model/ResourceModel/Order.php index fd69f3b1a52a3..1903308466498 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order.php @@ -53,12 +53,12 @@ protected function _construct() /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context - * @param Attribute $attribute - * @param Manager $sequenceManager * @param Snapshot $entitySnapshot * @param RelationComposite $entityRelationComposite + * @param Attribute $attribute + * @param Manager $sequenceManager * @param StateHandler $stateHandler - * @param string $connectionName + * @param string|null $connectionName */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, @@ -137,6 +137,8 @@ protected function calculateItems(\Magento\Sales\Model\Order $object) } /** + * Before save + * * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ @@ -152,15 +154,15 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) ]; $object->setStoreName(implode(PHP_EOL, $name)); $object->setTotalItemCount($this->calculateItems($object)); + $object->setData( + 'protect_code', + substr( + hash('sha256', uniqid(Random::getRandomNumber(), true) . ':' . microtime(true)), + 5, + 32 + ) + ); } - $object->setData( - 'protect_code', - substr( - hash('sha256', uniqid(Random::getRandomNumber(), true) . ':' . microtime(true)), - 5, - 32 - ) - ); $isNewCustomer = !$object->getCustomerId() || $object->getCustomerId() === true; if ($isNewCustomer && $object->getCustomer()) { $object->setCustomerId($object->getCustomer()->getId()); @@ -169,7 +171,7 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) } /** - * {@inheritdoc} + * @inheritdoc */ public function save(\Magento\Framework\Model\AbstractModel $object) { diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php index 53459f2c3e52f..d1440a2b547a4 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php @@ -15,13 +15,14 @@ use Magento\Framework\View\Result\Layout; use Magento\Framework\App\ResponseInterface; use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Export Coupons to csv file * * Class \Magento\SalesRule\Controller\Adminhtml\Promo\Quote\ExportCouponsCsv */ -class ExportCouponsCsv extends Quote implements HttpGetActionInterface +class ExportCouponsCsv extends Quote implements HttpGetActionInterface, HttpPostActionInterface { /** * Export coupon codes as CSV file diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php index fa3d4455410c4..401d8aea1aded 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php @@ -15,13 +15,14 @@ use Magento\Framework\View\Result\Layout; use Magento\Framework\App\ResponseInterface; use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Export coupons to xml file * * Class \Magento\SalesRule\Controller\Adminhtml\Promo\Quote\ExportCouponsXml */ -class ExportCouponsXml extends Quote implements HttpGetActionInterface +class ExportCouponsXml extends Quote implements HttpGetActionInterface, HttpPostActionInterface { /** * Export coupon codes as excel xml file diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js index 9a34e57df86c7..65443fadf8007 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js @@ -668,7 +668,7 @@ define([ * @returns {Object} Chainable */ toggleListVisible: function () { - this.listVisible(!this.listVisible()); + this.listVisible(!this.disabled() && !this.listVisible()); return this; }, diff --git a/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js b/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js index be9044143c5a4..3c5e72d4d66ed 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js @@ -13,10 +13,12 @@ define([ return Component.extend({ defaults: { listingNamespace: null, + bookmarkProvider: 'componentType = bookmark, ns = ${ $.listingNamespace }', filterProvider: 'componentType = filters, ns = ${ $.listingNamespace }', filterKey: 'filters', searchString: location.search, modules: { + bookmarks: '${ $.bookmarkProvider }', filterComponent: '${ $.filterProvider }' } }, @@ -49,6 +51,16 @@ define([ return; } + if (!_.isUndefined(this.bookmarks())) { + if (!_.size(this.bookmarks().getViewData(this.bookmarks().defaultIndex))) { + setTimeout(function () { + this.apply(); + }.bind(this), 500); + + return; + } + } + if (Object.keys(urlFilter).length) { applied = this.filterComponent().get('applied'); filters = $.extend({}, applied, urlFilter); diff --git a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less index fa158589feb96..654236e143a29 100644 --- a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less +++ b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less @@ -18,15 +18,10 @@ // _____________________________________________ .currency-addon { + .lib-vendor-prefix-display(inline-flex); border: 1px solid rgb(173,173,173); - position: relative; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; flex-flow: row nowrap; + position: relative; width: 100%; .admin__control-text { diff --git a/app/design/frontend/Magento/blank/web/css/source/_navigation.less b/app/design/frontend/Magento/blank/web/css/source/_navigation.less index fad906a089400..f9cca1ca16a18 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_navigation.less +++ b/app/design/frontend/Magento/blank/web/css/source/_navigation.less @@ -28,10 +28,10 @@ .nav-toggle { .lib-icon-font( - @icon-menu, - @_icon-font-size: 28px, - @_icon-font-color: @header-icons-color, - @_icon-font-color-hover: @header-icons-color-hover + @icon-menu, + @_icon-font-size: 28px, + @_icon-font-color: @header-icons-color, + @_icon-font-color-hover: @header-icons-color-hover ); .lib-icon-text-hide(); cursor: pointer; @@ -54,13 +54,13 @@ .parent { .level-top { - position: relative; .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 42px, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 42px, + @_icon-font-position: after, + @_icon-font-display: block ); + position: relative; &:after { position: absolute; @@ -70,8 +70,8 @@ &.ui-state-active { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } @@ -82,12 +82,10 @@ -webkit-overflow-scrolling: touch; .lib-css(transition, left .3s, 1); height: 100%; - left: -80%; left: calc(~'-1 * (100% - @{active-nav-indent})'); overflow: auto; position: fixed; top: 0; - width: 80%; width: calc(~'100% - @{active-nav-indent}'); .switcher { @@ -109,13 +107,13 @@ .switcher-trigger { strong { - position: relative; .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 42px, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 42px, + @_icon-font-position: after, + @_icon-font-display: block ); + position: relative; &:after { position: absolute; @@ -126,16 +124,18 @@ &.active strong { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } + .switcher-dropdown { .lib-list-reset-styles(); display: none; padding: @indent__s 0; } + .switcher-options { &.active { .switcher-dropdown { @@ -143,6 +143,7 @@ } } } + .header.links { .lib-list-reset-styles(); border-bottom: 1px solid @color-gray82; @@ -200,13 +201,11 @@ .nav-open { .page-wrapper { - left: 80%; left: calc(~'100% - @{active-nav-indent}'); } .nav-sections { @_shadow: 0 0 5px 0 rgba(50, 50, 50, .75); - .lib-css(box-shadow, @_shadow, 1); left: 0; z-index: 99; @@ -293,10 +292,6 @@ display: none; } - .nav-sections-item-content { - display: block !important; - } - .nav-sections-item-content > * { display: none; } diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php index d99b056ca359e..59aa2e7c719bf 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php @@ -32,15 +32,20 @@ public function startTest(TestCase $test) { Bootstrap::getInstance()->reinitialize(); /** Apply method level fixtures if thy are available, apply class level fixtures otherwise */ - $this->_applyFixtures($this->_getFixtures($test, 'method') ?: $this->_getFixtures($test, 'class')); + $this->_applyFixtures( + $this->_getFixtures($test, 'method') ?: $this->_getFixtures($test, 'class'), + $test + ); } /** * Handler for 'endTest' event + * + * @param TestCase $test */ - public function endTest() + public function endTest(TestCase $test) { - $this->_revertFixtures(); + $this->_revertFixtures($test); $objectManager = Bootstrap::getObjectManager(); $objectManager->get(AttributeMetadataCache::class)->clean(); } diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php index 7a4f472c69513..538c0b0ee5fac 100644 --- a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php @@ -225,6 +225,7 @@ public function testUpdateBundleAddSelection() public function testUpdateBundleAddAndDeleteOption() { $bundleProduct = $this->createDynamicBundleProduct(); + $linkedProductPrice = 20; $bundleProductOptions = $this->getBundleProductOptions($bundleProduct); @@ -238,7 +239,7 @@ public function testUpdateBundleAddAndDeleteOption() [ 'sku' => 'simple2', 'qty' => 2, - "price" => 20, + "price" => $linkedProductPrice, "price_type" => 1, "is_default" => false, ], @@ -256,6 +257,7 @@ public function testUpdateBundleAddAndDeleteOption() $this->assertFalse(isset($bundleOptions[1])); $this->assertEquals('simple2', $bundleOptions[0]['product_links'][0]['sku']); $this->assertEquals(2, $bundleOptions[0]['product_links'][0]['qty']); + $this->assertEquals($linkedProductPrice, $bundleOptions[0]['product_links'][0]['price']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 21b93645fd15a..461ab6c989104 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -43,6 +43,11 @@ class CategoryRepositoryTest extends WebapiAbstract */ private $adminTokens; + /** + * @var string[] + */ + private $createdCategories; + /** * @inheritDoc */ @@ -132,8 +137,7 @@ public function testCreate() sprintf('"%s" field value is invalid', $fieldName) ); } - // delete category to clean up auto-generated url rewrites - $this->deleteCategory($result['id']); + $this->createdCategories = [$result['id']]; } /** @@ -214,8 +218,7 @@ public function testUpdate() $this->assertFalse((bool)$category->getIsActive(), 'Category "is_active" must equal to false'); $this->assertEquals("Update Category Test", $category->getName()); $this->assertEquals("Update Category Description Test", $category->getDescription()); - // delete category to clean up auto-generated url rewrites - $this->deleteCategory($categoryId); + $this->createdCategories = [$categoryId]; } /** @@ -243,8 +246,7 @@ public function testUpdateWithDefaultSortByAttribute() $this->assertTrue((bool)$category->getIsActive(), 'Category "is_active" must equal to true'); $this->assertEquals("Update Category Test With default_sort_by Attribute", $category->getName()); $this->assertEquals("name", $category->getDefaultSortBy()); - // delete category to clean up auto-generated url rewrites - $this->deleteCategory($categoryId); + $this->createdCategories = [$categoryId]; } protected function getSimpleCategoryData($categoryData = []) @@ -476,5 +478,23 @@ public function testSaveDesign(): void } //We don't have permissions to do that. $this->assertEquals('Not allowed to edit the category\'s design attributes', $exceptionMessage); + $this->createdCategories = [$result['id']]; + } + + /** + * @inheritDoc + * + * @return void + */ + protected function tearDown(): void + { + if (!empty($this->createdCategories)) { + // delete category to clean up auto-generated url rewrites + foreach ($this->createdCategories as $categoryId) { + $this->deleteCategory($categoryId); + } + } + + parent::tearDown(); } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 2f4b7bf79c1d6..9172d7cf857e5 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -7,8 +7,6 @@ namespace Magento\TestFramework\Annotation; -use Magento\Framework\Component\ComponentRegistrarInterface; -use Magento\Framework\Exception\LocalizedException; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\Exception; use PHPUnit\Framework\TestCase; @@ -106,10 +104,18 @@ protected function _applyOneFixture($fixture) * Execute fixture scripts if any * * @param array $fixtures + * @param TestCase $test * @return void */ - protected function _applyFixtures(array $fixtures) + protected function _applyFixtures(array $fixtures, TestCase $test) { + /** @var \Magento\TestFramework\Annotation\TestsIsolation $testsIsolation */ + $testsIsolation = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\TestFramework\Annotation\TestsIsolation::class + ); + $dbIsolationState = $this->getDbIsolationState($test); + $testsIsolation->createDbSnapshot($test, $dbIsolationState); + /* Execute fixture scripts */ foreach ($fixtures as $oneFixture) { $this->_applyOneFixture($oneFixture); @@ -122,9 +128,10 @@ protected function _applyFixtures(array $fixtures) /** * Revert changes done by fixtures * + * @param TestCase|null $test * @return void */ - protected function _revertFixtures() + protected function _revertFixtures(?TestCase $test = null) { $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($this->getAnnotation()); @@ -149,13 +156,22 @@ protected function _revertFixtures() } $this->_appliedFixtures = []; $resolver->setCurrentFixtureType(null); + + if (null !== $test) { + /** @var \Magento\TestFramework\Annotation\TestsIsolation $testsIsolation */ + $testsIsolation = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\TestFramework\Annotation\TestsIsolation::class + ); + $dbIsolationState = $this->getDbIsolationState($test); + $testsIsolation->checkTestIsolation($test, $dbIsolationState); + } } /** * Return is explicit set isolation state * * @param TestCase $test - * @return bool|null + * @return array|null */ protected function getDbIsolationState(TestCase $test) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixture.php index 02e53fc0a80ed..ffcdc186af520 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixture.php @@ -32,7 +32,7 @@ public function startTestTransactionRequest(TestCase $test, Transaction $param): if ($this->getDbIsolationState($test) !== ['disabled']) { $param->requestTransactionStart(); } else { - $this->_applyFixtures($fixtures); + $this->_applyFixtures($fixtures, $test); } } } @@ -51,7 +51,7 @@ public function endTestTransactionRequest(TestCase $test, Transaction $param): v if ($this->getDbIsolationState($test) !== ['disabled']) { $param->requestTransactionRollback(); } else { - $this->_revertFixtures(); + $this->_revertFixtures($test); } } } @@ -64,12 +64,13 @@ public function endTestTransactionRequest(TestCase $test, Transaction $param): v */ public function startTransaction(TestCase $test): void { - $this->_applyFixtures($this->_getFixtures($test)); + $this->_applyFixtures($this->_getFixtures($test), $test); } /** * Handler for 'rollbackTransaction' event * + * @param TestCase $test * @return void */ public function rollbackTransaction(): void diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureBeforeTransaction.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureBeforeTransaction.php index 5685fea44f734..b36aebfd84728 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureBeforeTransaction.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureBeforeTransaction.php @@ -24,7 +24,7 @@ public function startTest(TestCase $test) { $fixtures = $this->_getFixtures($test); if ($fixtures) { - $this->_applyFixtures($fixtures); + $this->_applyFixtures($fixtures, $test); } } @@ -37,7 +37,7 @@ public function endTest(TestCase $test) { /* Isolate other tests from test-specific fixtures */ if ($this->_appliedFixtures && $this->_getFixtures($test)) { - $this->_revertFixtures(); + $this->_revertFixtures($test); } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/TestsIsolation.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/TestsIsolation.php new file mode 100644 index 0000000000000..119ee1013a15c --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/TestsIsolation.php @@ -0,0 +1,194 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\TestFramework\Annotation; + +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\ResourceConnection; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\AssertionFailedError; + +/** + * Validates tests isolation. Makes sure that test does not keep exceed data in DB. + */ +class TestsIsolation +{ + /** + * This variable was created to keep initial data cached + * + * @var array + */ + private $dbTableState = []; + + /** + * @var string[] + */ + private $testTypesToCheckIsolation = [ + 'integration', + ]; + + /** + * @var int + */ + private $isolationLevel = 0; + + /** + * @var string[] + */ + private $dbStateTables = [ + 'catalog_product_entity', + 'eav_attribute', + 'catalog_category_entity', + 'eav_attribute_set', + 'store', + 'store_website', + 'url_rewrite' + ]; + + /** + * Pull data from specific table + * + * @param string $table + * @return array + */ + private function pullDbState(string $table): array + { + $resource = ObjectManager::getInstance()->get(ResourceConnection::class); + $connection = $resource->getConnection(); + $select = $connection->select()->from($table); + return $connection->fetchAll($select); + } + + /** + * Create DB snapshot before test run. + * + * @param TestCase $test + * @param array|null $dbIsolationState + * @return void + */ + public function createDbSnapshot(TestCase $test, ?array $dbIsolationState): void + { + if (null !== $dbIsolationState + && ($dbIsolationState !== ['enabled']) + && ($this->checkIsolationRequired($test)) + ) { + ++$this->isolationLevel; + if ($this->isolationLevel === 1) { + $this->saveDbStateBeforeTestRun($test); + } + } + } + + /** + * Check DB isolation when test ended. + * + * @param TestCase $test + * @param array|null $dbIsolationState + * @return void + */ + public function checkTestIsolation(TestCase $test, ?array $dbIsolationState): void + { + if (null !== $dbIsolationState + && ($dbIsolationState !== ['enabled']) + && ($this->checkIsolationRequired($test)) + ) { + --$this->isolationLevel; + if ($this->isolationLevel === 1) { + $this->checkResidualData($test); + } + } + } + + /** + * Saving DB snapshot before fixtures applying. + * + * @param TestCase $test + * @return void + */ + private function saveDbStateBeforeTestRun(TestCase $test): void + { + try { + if (empty($this->dbTableState)) { + foreach ($this->dbStateTables as $table) { + $this->dbTableState[$table] = $this->pullDbState($table); + } + } + } catch (\Throwable $e) { + $test->getTestResultObject()->addFailure($test, new AssertionFailedError($e->getMessage()), 0); + } + } + + /** + * Check if test isolation is required for given scope of tests. + * + * @param TestCase $test + * @return bool + */ + private function checkIsolationRequired(TestCase $test): bool + { + $isRequired = false; + if (!$test->getTestResultObject()) { + return $isRequired; + } + + $testFilename = $test->getTestResultObject()->topTestSuite()->getName(); + foreach ($this->testTypesToCheckIsolation as $testType) { + if (false !== strpos($testFilename, \sprintf('/dev/tests/%s/', $testType))) { + $isRequired = true; + break; + } + } + + return $isRequired; + } + + /** + * Check if there's residual data in DB after test execution. + * + * @param TestCase $test + * @return void + */ + private function checkResidualData(TestCase $test): void + { + $isolationProblem = []; + foreach ($this->dbTableState as $table => $isolationData) { + try { + $diff = $this->dataDiff($isolationData, $this->pullDbState($table)); + if (!empty($diff)) { + $isolationProblem[$table] = $diff; + } + } catch (\Throwable $e) { + $test->getTestResultObject()->addFailure($test, new AssertionFailedError($e->getMessage()), 0); + } + } + + if (!empty($isolationProblem)) { + $test->getTestResultObject()->addFailure( + $test, + new AssertionFailedError( + "There was a problem with isolation: " . var_export($isolationProblem, true) + ), + 0 + ); + } + } + + /** + * Compare data difference for m-dimensional array + * + * @param array $dataBefore + * @param array $dataAfter + * @return array + */ + private function dataDiff(array $dataBefore, array $dataAfter): array + { + $diff = []; + if (count($dataBefore) !== count($dataAfter)) { + $diff = \array_slice($dataAfter, count($dataBefore)); + } + + return $diff; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Indexer/TestCase.php b/dev/tests/integration/framework/Magento/TestFramework/Indexer/TestCase.php index b9a481e97c9a3..3360fa4342a5a 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Indexer/TestCase.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Indexer/TestCase.php @@ -7,7 +7,30 @@ class TestCase extends \PHPUnit\Framework\TestCase { + /** + * @var bool + */ + protected static $dbRestored = false; + + /** + * @inheritDoc + * + * @throws \Magento\Framework\Exception\LocalizedException + * @return void + */ public static function tearDownAfterClass(): void + { + if (empty(static::$dbRestored)) { + self::restoreFromDb(); + } + } + + /** + * Restore DB data after test execution. + * + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected static function restoreFromDb(): void { $db = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getBootstrap() ->getApplication() diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index b3cfc2ae4fe79..3abe6ea4e061d 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -8,10 +8,12 @@ namespace Magento\Test\Annotation; use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Event\Param\Transaction; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; +use Magento\TestFramework\Annotation\TestsIsolation; /** * Test class for \Magento\TestFramework\Annotation\DataFixture. @@ -25,6 +27,11 @@ class DataFixtureTest extends TestCase */ protected $object; + /** + * @var TestsIsolation|\PHPUnit\Framework\MockObject\MockObject + */ + protected $testsIsolationMock; + /** * @inheritdoc */ @@ -33,6 +40,18 @@ protected function setUp(): void $this->object = $this->getMockBuilder(DataFixture::class) ->setMethods(['_applyOneFixture', 'getComponentRegistrar', 'getTestKey']) ->getMock(); + $this->testsIsolationMock = $this->getMockBuilder(TestsIsolation::class) + ->setMethods(['createDbSnapshot', 'checkTestIsolation']) + ->getMock(); + /** @var ObjectManagerInterface|\PHPUnit\Framework\MockObject\MockObject $objectManager */ + $objectManager = $this->getMockBuilder(ObjectManagerInterface::class) + ->setMethods(['get']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $objectManager->expects($this->atLeastOnce())->method('get')->with(TestsIsolation::class) + ->willReturn($this->testsIsolationMock); + \Magento\TestFramework\Helper\Bootstrap::setObjectManager($objectManager); + $directory = __DIR__; if (!defined('INTEGRATION_TESTS_DIR')) { define('INTEGRATION_TESTS_DIR', dirname($directory, 4)); diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php index 1ce2b01b10212..f6b8a06d2e16f 100644 --- a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php @@ -7,6 +7,7 @@ namespace Magento\AdvancedPricingImportExport\Model\Export; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\File\Csv; use Magento\TestFramework\Indexer\TestCase; use Magento\TestFramework\Helper\Bootstrap; @@ -103,6 +104,8 @@ public function testExport() $this->assertEquals(count($origPricingData[$index]), count($newPricingData)); $this->assertEqualsOtherThanSkippedAttributes($origPricingData[$index], $newPricingData, []); } + + $this->removeImportedProducts($skus); } /** @@ -163,6 +166,7 @@ public function testExportMultipleWebsites() $this->assertEquals(count($origPricingData[$index]), count($newPricingData)); $this->assertEqualsOtherThanSkippedAttributes($origPricingData[$index], $newPricingData, []); } + $this->removeImportedProducts($skus); } /** @@ -173,14 +177,16 @@ public function testExportMultipleWebsites() */ public function testExportImportOfAdvancedPricing(): void { + $simpleSku = 'simple'; + $secondSimpleSku = 'second_simple'; $csvfile = uniqid('importexport_') . '.csv'; $exportContent = $this->exportData($csvfile); $this->assertStringContainsString( - 'second_simple,"All Websites [USD]","ALL GROUPS",10.0000,3.00,Discount', + \sprintf('%s,"All Websites [USD]","ALL GROUPS",10.0000,3.00,Discount', $secondSimpleSku), $exportContent ); $this->assertStringContainsString( - 'simple,"All Websites [USD]",General,5.0000,95.000000,Fixed', + \sprintf('%s,"All Websites [USD]",General,5.0000,95.000000,Fixed', $simpleSku), $exportContent ); $this->updateTierPriceDataInCsv($csvfile); @@ -224,6 +230,8 @@ public function testExportImportOfAdvancedPricing(): void ], 0.1 ); + + $this->removeImportedProducts([$simpleSku, $secondSimpleSku]); } /** @@ -331,4 +339,31 @@ private function assertEqualsOtherThanSkippedAttributes($expected, $actual, $ski } } } + + /** + * Cleanup test by removing imported product. + * + * @param string[] $skus + * @return void + */ + private function removeImportedProducts(array $skus): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $registry = $this->objectManager->get(\Magento\Framework\Registry::class); + /** @var ProductRepositoryInterface $productRepository */ + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); + + foreach ($skus as $sku) { + try { + $productRepository->deleteById($sku); + } catch (NoSuchEntityException $e) { + // product already deleted + } + } + + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', false); + } } diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/create_products_rollback.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/create_products_rollback.php new file mode 100644 index 0000000000000..a814a7faea34b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/create_products_rollback.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var ObjectManagerInterface $objectManager */ +$objectManager = Bootstrap::getObjectManager(); + +/** + * @var Product $productModel + * @var ProductRepositoryInterface $productRepository + */ +$productModel = $objectManager->create(Product::class); +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$skus = ['AdvancedPricingSimple 1', 'AdvancedPricingSimple 2']; +foreach ($skus as $sku) { + try { + $product = $productRepository->getById($sku); + $productRepository->delete($product); + } catch (NoSuchEntityException $exception) { + // product already removed + } +} diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/product_with_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/product_with_second_website_rollback.php new file mode 100644 index 0000000000000..c5678d3fdab4a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/_files/product_with_second_website_rollback.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Store/_files/website_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/AdvancedPricingImportExport/_files/create_products_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing_rollback.php index 513c1fff62fb6..fc33758a9d01d 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing_rollback.php @@ -13,7 +13,7 @@ * bundled items should not contain products with required custom options. * However, if to create such a bundle product, it will be always out of stock. */ -Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/products.php'); +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/products_rollback.php'); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var \Magento\Framework\Registry $registry */ diff --git a/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Import/Product/Type/BundleTest.php b/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Import/Product/Type/BundleTest.php index 361ceed5c02fe..89fe02f3dbc6c 100644 --- a/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Import/Product/Type/BundleTest.php +++ b/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Import/Product/Type/BundleTest.php @@ -5,6 +5,8 @@ */ namespace Magento\BundleImportExport\Model\Import\Product\Type; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\App\Filesystem\DirectoryList; @@ -34,6 +36,11 @@ class BundleTest extends \Magento\TestFramework\Indexer\TestCase */ protected $objectManager; + /** + * @var string[] + */ + private $importedProductSkus; + /** * List of Bundle options SKU * @@ -131,6 +138,7 @@ public function testBundleImport() } } } + $this->importedProductSkus = ['Simple 1', 'Simple 2', 'Simple 3', 'Bundle 1']; } /** @@ -192,6 +200,7 @@ public function testBundleImportWithMultipleStoreViews(): void } } } + $this->importedProductSkus = ['Simple 1', 'Simple 2', 'Simple 3', 'Bundle 1']; } /** @@ -199,6 +208,26 @@ public function testBundleImportWithMultipleStoreViews(): void */ protected function tearDown(): void { + if (!empty($this->importedProductSkus)) { + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->create(ProductRepositoryInterface::class); + $registry = $objectManager->get(\Magento\Framework\Registry::class); + /** @var ProductRepositoryInterface $productRepository */ + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); + + foreach ($this->importedProductSkus as $sku) { + try { + $productRepository->deleteById($sku); + } catch (NoSuchEntityException $e) { + // product already deleted + } + } + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', false); + } + parent::tearDown(); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_base_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_base_rollback.php index 67bdb3d5c5e59..4515297fd1e8a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_base_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_base_rollback.php @@ -44,15 +44,6 @@ $lastProductId = 0; foreach ($testCases as $index => $testCase) { - $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Category::class - ); - $position = $index + 1; - $categoryId = $index + 4; - $category->load($categoryId); - if ($category->getId()) { - $category->delete(); - } /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( @@ -74,3 +65,11 @@ ++$lastProductId; } } + +/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ +$collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); +$collection + ->addAttributeToFilter('level', ['in' => [2, 3, 4]]) + ->load() + ->delete(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/second_product_simple_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/second_product_simple_rollback.php index b045bfe4f6977..09e13c381aaed 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/second_product_simple_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/second_product_simple_rollback.php @@ -9,6 +9,7 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Registry; use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\UrlRewrite; $objectManager = Bootstrap::getObjectManager(); /** @var Registry $registry */ @@ -26,5 +27,9 @@ //Product already removed } +$urlRewrite = $objectManager->create(UrlRewrite::class); +$urlRewrite->load('simple2.html', 'request_path'); +$urlRewrite->delete(); + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites_rollback.php index 1fa44427b3fbe..f671c43004ffa 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites_rollback.php @@ -25,7 +25,7 @@ $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); $collection - ->addAttributeToFilter('level', 2) + ->addAttributeToFilter('name', ['in' => ['Old Root', 'Category 2', 'Category 1']]) ->load() ->delete(); 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 4502501da4f4f..a9699ea4a8050 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1815,6 +1815,9 @@ public function testExistingProductWithUrlKeys() 'simple2' => 'url-key2', 'simple3' => 'url-key3' ]; + // added by _files/products_to_import_with_valid_url_keys.csv + $this->importedProducts[] = 'simple3'; + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Framework\Filesystem::class); $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); @@ -1855,6 +1858,9 @@ public function testAddUpdateProductWithInvalidUrlKeys() : void 'simple2' => 'normal-url', 'simple3' => 'some!wrong\'url' ]; + // added by _files/products_to_import_with_invalid_url_keys.csv + $this->importedProducts[] = 'simple3'; + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Framework\Filesystem::class); $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); @@ -2004,6 +2010,9 @@ public function testImportWithoutUrlKeys() 'simple2' => 'simple-2', 'simple3' => 'simple-3' ]; + // added by _files/products_to_import_without_url_keys.csv + $this->importedProducts[] = 'simple3'; + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $source = $this->objectManager->create( @@ -2221,11 +2230,15 @@ function (ProductInterface $item) { $registry->register('isSecureArea', true); $productSkuList = ['simple1', 'simple2', 'simple3']; + $categoryIds = []; foreach ($productSkuList as $sku) { try { + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var \Magento\Catalog\Model\Product $product */ $product = $productRepository->get($sku, true); + $categoryIds[] = $product->getCategoryIds(); if ($product->getId()) { $productRepository->delete($product); } @@ -2235,6 +2248,14 @@ function (ProductInterface $item) { } } + /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ + $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); + $collection + ->addAttributeToFilter('entity_id', ['in' => \array_unique(\array_merge(...$categoryIds))]) + ->load() + ->delete(); + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); } @@ -3169,6 +3190,12 @@ public function testEmptyAttributeValueShouldBeIgnoredAfterUpdateProductByImport */ public function testCheckDoubleImportOfProducts() { + $this->importedProducts = [ + 'simple1', + 'simple2', + 'simple3', + ]; + /** @var SearchCriteria $searchCriteria */ $searchCriteria = $this->searchCriteriaBuilder->create(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/products_for_sku_search_weight_score_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/products_for_sku_search_weight_score_rollback.php index 775d405654fdf..3622cecb7143d 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/products_for_sku_search_weight_score_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/_files/products_for_sku_search_weight_score_rollback.php @@ -18,7 +18,16 @@ $productRepository = $objectManager->create(ProductRepositoryInterface::class); /** @var Registry $registry */ $registry = $objectManager->get(Registry::class); -$productSkus = ['1234-1234-1234-1234', 'Simple', 'product_with_description', 'product_with_attribute']; +$productSkus = [ + '1234-1234-1234-1234', + 'Simple', + 'product_with_description', + 'product_with_attribute', + 'nintendo-wii', + 'xbox', + 'console_description', + 'gamecube_attribute', +]; $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Fixtures/product_custom_url_key_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Fixtures/product_custom_url_key_rollback.php index 78b4f5ec238df..25fe62b91c6da 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Fixtures/product_custom_url_key_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Fixtures/product_custom_url_key_rollback.php @@ -5,18 +5,6 @@ */ declare(strict_types=1); -use Magento\Framework\Registry; -use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; -$objectManager = Bootstrap::getObjectManager(); - -/** @var Registry $registry */ -$registry = $objectManager->get(Registry::class); -$registry->unregister('isSecureArea'); -$registry->register('isSecureArea', true); - Resolver::getInstance()->requireDataFixture('Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php'); - -$registry->unregister('isSecureArea'); -$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php index 6be7354911654..fab5b173625d3 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category_rollback.php @@ -46,6 +46,8 @@ $urlRewrite = $objectManager->create(UrlRewrite::class); $urlRewrite->load('non-exist-product.html', 'request_path'); $urlRewrite->delete(); +$urlRewrite->load('.html', 'request_path'); +$urlRewrite->delete(); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_stores_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_stores_rollback.php index 86f0ce34af00c..6b7d4072ead9a 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_stores_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_stores_rollback.php @@ -6,9 +6,12 @@ declare(strict_types=1); use Magento\Framework\Exception\NoSuchEntityException; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); +Resolver::getInstance()->requireDataFixture('Magento/CatalogUrlRewrite/_files/categories_with_stores_rollback.php'); + /** @var \Magento\Framework\Registry $registry */ $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); diff --git a/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/PageDesignTest.php b/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/PageDesignTest.php index de1a78c87953c..9f8a620b8d2a5 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/PageDesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/PageDesignTest.php @@ -11,18 +11,21 @@ use Magento\Cms\Api\Data\PageInterface; use Magento\Cms\Api\GetPageByIdentifierInterface; use Magento\Cms\Model\Page; -use Magento\Cms\Model\PageFactory; use Magento\Framework\Acl\Builder; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Framework\Message\MessageInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\AbstractBackendController; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory; +use Magento\UrlRewrite\Model\UrlRewrite; /** * Test the saving CMS pages design via admin area interface. * * @magentoAppArea adminhtml + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PageDesignTest extends AbstractBackendController { @@ -77,6 +80,7 @@ protected function setUp(): void $this->aclBuilder = Bootstrap::getObjectManager()->get(Builder::class); $this->pageRetriever = Bootstrap::getObjectManager()->get(GetPageByIdentifierInterface::class); $this->scopeConfig = Bootstrap::getObjectManager()->get(ScopeConfigInterface::class); + $this->pagesToDelete = []; } /** @@ -86,11 +90,40 @@ protected function tearDown(): void { parent::tearDown(); + $pageIds = []; foreach ($this->pagesToDelete as $identifier) { - $page = $this->pageRetriever->execute($identifier); + $pageIds[] = $identifier; + $page = $this->pageRetriever->execute($identifier, 0); $page->delete(); } - $this->pagesToDelete = []; + $this->removeUrlRewrites(); + } + + /** + * Removes url rewrites created during test execution. + * + * @return void + */ + private function removeUrlRewrites(): void + { + if (!empty($this->pagesToDelete)) { + /** @var UrlRewriteCollectionFactory $urlRewriteCollectionFactory */ + $urlRewriteCollectionFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + UrlRewriteCollectionFactory::class + ); + /** @var UrlRewriteCollection $urlRewriteCollection */ + $urlRewriteCollection = $urlRewriteCollectionFactory->create(); + $urlRewriteCollection->addFieldToFilter('request_path', ['in' => $this->pagesToDelete]); + $urlRewrites = $urlRewriteCollection->getItems(); + /** @var UrlRewrite $urlRewrite */ + foreach ($urlRewrites as $urlRewrite) { + try { + $urlRewrite->delete(); + } catch (\Exception $exception) { + // already removed + } + } + } } /** @@ -150,6 +183,7 @@ public function testSaveDesign(): void self::equalTo($sessionMessages), MessageInterface::TYPE_ERROR ); + $this->pagesToDelete = [$id]; } /** @@ -181,6 +215,7 @@ public function testSaveDesignWithDefaults(): void $this->assertNotEmpty($page->getId()); $this->assertNotNull($page->getPageLayout()); $this->assertEquals($defaultLayout, $page->getPageLayout()); + $this->pagesToDelete = [$id]; } /** @@ -227,5 +262,6 @@ public function testSaveLayoutXml(): void $updated = $this->pageRetriever->execute('test_custom_layout_page_1', 0); $this->assertEmpty($updated->getCustomLayoutUpdateXml()); $this->assertEmpty($updated->getLayoutUpdateXml()); + $this->pagesToDelete = ['test_custom_layout_page_1']; } } diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php index 9ca4f78660b3a..a97faa29a1588 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php @@ -4,6 +4,10 @@ * See COPYING.txt for license details. */ +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_boolean_attribute_rollback.php'); + /** @var $objectManager \Magento\Framework\ObjectManagerInterface */ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store_rollback.php b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store_rollback.php new file mode 100644 index 0000000000000..59aa4bda3872a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store_rollback.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Customer\Model\CustomerRegistry; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_for_second_store_rollback.php'); +Resolver::getInstance()->requireDataFixture( + 'Magento/Catalog/_files/product_simple_out_of_stock_without_categories_rollback.php' +); + +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$objectManager = Bootstrap::getObjectManager(); +/** @var CustomerRegistry $customerRegistry */ +$customerRegistry = Bootstrap::getObjectManager()->create(CustomerRegistry::class); +$customer = $customerRegistry->remove(1); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +try { + $product = $productRepository->deleteById('simple'); +} catch (\Exception $e) { + // product already removed +} +/** @var Magento\Store\Model\Store $store */ +$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); +$store->load('fixture_second_store'); +if ($store->getId()) { + $store->delete(); +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Reports/_files/recently_compared_out_of_stock_product_rollback.php b/dev/tests/integration/testsuite/Magento/Reports/_files/recently_compared_out_of_stock_product_rollback.php index 677bfb32cd8e9..f3d31bee387f6 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/_files/recently_compared_out_of_stock_product_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Reports/_files/recently_compared_out_of_stock_product_rollback.php @@ -7,5 +7,5 @@ use Magento\TestFramework\Workaround\Override\Fixture\Resolver; -Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/out_of_stock_product_with_category.php'); +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/out_of_stock_product_with_category_rollback.php'); Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/Reports/_files/recently_viewed_disabled_product_by_customer_rollback.php b/dev/tests/integration/testsuite/Magento/Reports/_files/recently_viewed_disabled_product_by_customer_rollback.php index f3dedf0a35d96..5c5ad143ac77f 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/_files/recently_viewed_disabled_product_by_customer_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Reports/_files/recently_viewed_disabled_product_by_customer_rollback.php @@ -43,3 +43,6 @@ $session->logout(); $config->setValue('reports/options/enabled', $originalValue); } + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/second_product_simple_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php index 2dc5f5adc86d2..a09e656b90726 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php @@ -74,6 +74,21 @@ public function testAclNoAccess() parent::testAclNoAccess(); } + /** + * Checks that order protect code is not changing after invoice submitting + * + * @return void + */ + public function testOrderProtectCodePreserveAfterInvoiceSave(): void + { + $order = $this->prepareRequest(); + $protectCode = $order->getProtectCode(); + $this->dispatch($this->uri); + $invoicedOrder = $this->getOrder('100000001'); + + $this->assertEquals($protectCode, $invoicedOrder->getProtectCode()); + } + /** * @param array $params * @return \Magento\Sales\Api\Data\OrderInterface|null diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsCsvTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsCsvTest.php new file mode 100644 index 0000000000000..954c23498ec66 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsCsvTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote\ExportCoupons; + +use Magento\Framework\App\ResourceConnection; +use Magento\SalesRule\Model\ResourceModel\Rule\Collection as RuleCollection; +use Magento\SalesRule\Model\Rule; +use Magento\TestFramework\TestCase\AbstractBackendController; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test export coupon csv + * + * Verify export csv + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/SalesRule/_files/cart_rule_with_coupon_list.php + */ +class ExportCouponsCsvTest extends AbstractBackendController +{ + /** + * @var string + */ + protected $uri = 'backend/sales_rule/promo_quote/exportCouponsCsv'; + + /** + * @var string + */ + protected $resource = 'Magento_SalesRule::quote'; + + /** + * @var Rule + */ + private $salesRule; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + $this->resourceConnection = Bootstrap::getObjectManager()->get(ResourceConnection::class); + $this->initSalesRule(); + } + + /** + * Prepare request + * + * @return void + */ + private function prepareRequest(): void + { + $couponList = $this->getCouponsIdList(); + if (count($couponList)) { + $this->getRequest()->setParams(['internal_ids' => $couponList[0]])->setMethod('POST'); + } + } + + /** + * Init current sales rule + * + * @return void + */ + private function initSalesRule(): void + { + /** @var RuleCollection $collection */ + $collection = Bootstrap::getObjectManager()->create(RuleCollection::class); + $collection->addFieldToFilter('name', 'Rule with coupon list'); + $this->salesRule = $collection->getFirstItem(); + } + + /** + * Retrieve id list of coupons + * + * @return array + */ + private function getCouponsIdList(): array + { + $select = $this->resourceConnection->getConnection() + ->select() + ->from($this->resourceConnection->getTableName('salesrule_coupon')) + ->columns(['coupon_id']) + ->where('rule_id=?', $this->salesRule->getId()); + + return $this->resourceConnection->getConnection()->fetchCol($select); + } + + /** + * Test export csv + * + * @return void + */ + public function testExportCsv(): void + { + $this->prepareRequest(); + $this->dispatch($this->uri); + $this->assertStringNotContainsString('404 Error', $this->getResponse()->getBody()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsXmlTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsXmlTest.php new file mode 100644 index 0000000000000..d222b064a0d2c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCoupons/ExportCouponsXmlTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote\ExportCoupons; + +use Magento\Framework\App\ResourceConnection; +use Magento\SalesRule\Model\ResourceModel\Rule\Collection as RuleCollection; +use Magento\SalesRule\Model\Rule; +use Magento\TestFramework\TestCase\AbstractBackendController; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test export coupon xml + * + * Verify export xml + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/SalesRule/_files/cart_rule_with_coupon_list.php + */ +class ExportCouponsXmlTest extends AbstractBackendController +{ + /** + * @var string + */ + protected $uri = 'backend/sales_rule/promo_quote/exportCouponsXml'; + + /** + * @var string + */ + protected $resource = 'Magento_SalesRule::quote'; + + /** + * @var Rule + */ + private $salesRule; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + $this->resourceConnection = Bootstrap::getObjectManager()->get(ResourceConnection::class); + $this->initSalesRule(); + } + + /** + * Prepare request + * + * @return void + */ + private function prepareRequest(): void + { + $couponList = $this->getCouponsIdList(); + if (count($couponList)) { + $this->getRequest()->setParams(['internal_ids' => $couponList[0]])->setMethod('POST'); + } + } + + /** + * Init current sales rule + * + * @return void + */ + private function initSalesRule(): void + { + /** @var RuleCollection $collection */ + $collection = Bootstrap::getObjectManager()->create(RuleCollection::class); + $collection->addFieldToFilter('name', 'Rule with coupon list'); + $this->salesRule = $collection->getFirstItem(); + } + + /** + * Retrieve id list of coupons + * + * @return array + */ + private function getCouponsIdList(): array + { + $select = $this->resourceConnection->getConnection() + ->select() + ->from($this->resourceConnection->getTableName('salesrule_coupon')) + ->columns(['coupon_id']) + ->where('rule_id=?', $this->salesRule->getId()); + + return $this->resourceConnection->getConnection()->fetchCol($select); + } + + /** + * Test export xml + * + * @return void + */ + public function testExportCsv(): void + { + $this->prepareRequest(); + $this->dispatch($this->uri); + $this->assertStringNotContainsString('404 Error', $this->getResponse()->getBody()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php index 3ec185e71a1e5..355239f9dc2e7 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php @@ -87,6 +87,9 @@ protected function tearDown(): void { $this->setIncrement(1); + self::restoreFromDb(); + self::$dbRestored = true; + parent::tearDown(); } diff --git a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php index 2829cffd8d8a7..10e5cf40bd500 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php @@ -75,6 +75,8 @@ protected function tearDown(): void $indexer = $this->indexerRegistry->get($indexerId); $indexer->setScheduled($state); } + self::restoreFromDb(); + self::$dbRestored = true; } public static function setUpBeforeClass(): void diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php index 19d064bb79834..0ccfdf0af5c94 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php @@ -3,8 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + declare(strict_types=1); +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory; +use Magento\UrlRewrite\Model\UrlRewrite; + /** @var \Magento\Framework\Registry $registry */ $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); @@ -33,5 +38,21 @@ $store->delete(); } +$urlRewriteCollectionFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + UrlRewriteCollectionFactory::class +); +/** @var UrlRewriteCollection $urlRewriteCollection */ +$urlRewriteCollection = $urlRewriteCollectionFactory->create(); +$urlRewriteCollection->addFieldToFilter('store_id', ['gt' => 1]); +$urlRewrites = $urlRewriteCollection->getItems(); +/** @var UrlRewrite $urlRewrite */ +foreach ($urlRewrites as $urlRewrite) { + try { + $urlRewrite->delete(); + } catch (\Exception $exception) { + // already removed + } +} + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php index 56ba31fad4ed2..a434321189015 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php @@ -4,6 +4,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory; +use Magento\UrlRewrite\Model\UrlRewrite; + /** @var \Magento\Framework\Registry $registry */ $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); @@ -15,6 +20,24 @@ $store->load('fixture_second_store'); if ($store->getId()) { + $storeId = $store->getId(); + + $urlRewriteCollectionFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + UrlRewriteCollectionFactory::class + ); + /** @var UrlRewriteCollection $urlRewriteCollection */ + $urlRewriteCollection = $urlRewriteCollectionFactory->create(); + $urlRewriteCollection->addFieldToFilter('store_id', ['eq' => $storeId]); + $urlRewrites = $urlRewriteCollection->getItems(); + /** @var UrlRewrite $urlRewrite */ + foreach ($urlRewrites as $urlRewrite) { + try { + $urlRewrite->delete(); + } catch (\Exception $exception) { + // already removed + } + } + $store->delete(); } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php index 8289244d6581a..fa7d18124fdf1 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php @@ -7,6 +7,9 @@ use Magento\Framework\Registry; use Magento\Store\Model\Store; use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewrite; $objectManager = Bootstrap::getObjectManager(); @@ -29,5 +32,23 @@ $store->delete(); } +/** @var UrlRewriteCollectionFactory $urlRewriteCollectionFactory */ +$urlRewriteCollectionFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + UrlRewriteCollectionFactory::class +); +/** @var UrlRewriteCollection $urlRewriteCollection */ +$urlRewriteCollection = $urlRewriteCollectionFactory->create(); +$urlRewriteCollection + ->addFieldToFilter('store_id', ['nin' => [0, 1]]); +$urlRewrites = $urlRewriteCollection->getItems(); +/** @var UrlRewrite $urlRewrite */ +foreach ($urlRewrites as $urlRewrite) { + try { + $urlRewrite->delete(); + } catch (\Exception $exception) { + // already removed + } +} + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php index 96fc92c3c0ca5..a119b6259b5f6 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php @@ -5,8 +5,9 @@ */ namespace Magento\Tax\Model\Sales\Total\Quote; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Model\Quote\TotalsCollector; -use Magento\Tax\Model\Calculation; use Magento\TestFramework\Helper\Bootstrap; require_once __DIR__ . '/SetupUtil.php'; @@ -15,6 +16,9 @@ /** * Class TaxTest + * + * Tests sales taxes with discounts/price rules during checkout. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TaxTest extends \Magento\TestFramework\Indexer\TestCase @@ -302,6 +306,11 @@ public function testTaxCalculation($configData, $quoteData, $expectedResults) $quoteAddress = $quote->getShippingAddress(); $this->totalsCollector->collectAddressTotals($quote, $quoteAddress); $this->verifyResult($quoteAddress, $expectedResults); + + $skus = array_map(function ($item) { + return $item['sku']; + }, $quoteData['items'] ?? []); + $this->removeProducts($skus); } /** @@ -315,4 +324,32 @@ public function taxDataProvider() global $taxCalculationData; return $taxCalculationData; } + + /** + * Cleanup test by removing products. + * + * @param string[] $skus + * @return void + */ + private function removeProducts(array $skus): void + { + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->create(ProductRepositoryInterface::class); + $registry = $objectManager->get(\Magento\Framework\Registry::class); + /** @var ProductRepositoryInterface $productRepository */ + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); + + foreach ($skus as $sku) { + try { + $productRepository->deleteById($sku); + } catch (NoSuchEntityException $e) { + // product already deleted + } + } + + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', false); + } } diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_rollback.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_rollback.php index 4d2c148141943..d8bf0e6bfb731 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_rollback.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrite_rollback.php @@ -5,9 +5,13 @@ */ declare(strict_types=1); +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + /** @var \Magento\Framework\Registry $registry */ $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +Resolver::getInstance()->requireDataFixture('Magento/Store/_files/second_store_rollback.php'); + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_rollback.php b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_rollback.php index ee47961dec55b..ac1d846563188 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_rollback.php @@ -7,6 +7,9 @@ use Magento\TestFramework\Workaround\Override\Fixture\Resolver; +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); + /** @var \Magento\Framework\ObjectManagerInterface $objectManager */ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_product_rollback.php b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_product_rollback.php index 665644cd9b6db..9e46bc60b9a79 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_product_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_product_rollback.php @@ -13,6 +13,10 @@ use Magento\TestFramework\Workaround\Override\Fixture\Resolver; $objectManager = Bootstrap::getObjectManager(); + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/simple_product_disabled_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); + /** @var Registry $registry */ $registry = $objectManager->get(Registry::class); /** @var WishlistResource $wishListResource */ @@ -28,6 +32,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/simple_product_disabled.php'); -Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_simple_product_rollback.php b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_simple_product_rollback.php new file mode 100644 index 0000000000000..8ce2f4b64d851 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Wishlist/_files/wishlist_with_disabled_simple_product_rollback.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Wishlist/_files/wishlist_rollback.php'); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js index f46ff6b30abbe..c0ecec40516fa 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js @@ -246,6 +246,12 @@ define([ expect(type).toEqual('object'); }); + it('Must be false if "disabled" is true', function () { + obj.listVisible(false); + obj.disabled(true); + obj.toggleListVisible(); + expect(obj.listVisible()).toEqual(false); + }); it('Must be false if "listVisible" is true', function () { obj.listVisible(true); obj.toggleListVisible();