Skip to content

Commit

Permalink
Merge pull request #9005 from adobe-commerce-tier-4/PR_Tier4_June24
Browse files Browse the repository at this point in the history
[Support Tier-4 odubovyk] 06-13-24 Regular delivery of bugfixes and improvements
  • Loading branch information
2 parents 1bafc57 + a8e1a86 commit fe2e144
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/************************************************************************
*
* Copyright 2023 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ***********************************************************************
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminFillCatalogProductsListWidgetSkuActionGroup">
<annotations>
<description>Fill catalog products list widget sku.</description>
</annotations>

<arguments>
<argument name="sku" type="string" defaultValue=""/>
</arguments>

<waitForElementVisible selector="{{WidgetSection.AddParam}}" stepKey="waitForAddParamElement"/>
<click selector="{{WidgetSection.AddParam}}" stepKey="clickOnAddParamElement"/>
<waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}"
stepKey="waitForConditionsDropdownVisible"/>
<selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="SKU" stepKey="selectSkuAsCondition"/>
<waitForElementVisible selector="{{WidgetSection.RuleParam}}" stepKey="waitForRuleParamElementVisible"/>
<click selector="{{WidgetSection.RuleParam}}" stepKey="clickToAddRuleParam"/>
<fillField selector=".rule-param-edit input" userInput="{{sku}}" stepKey="fillSkuField"/>
<click selector="{{AdminNewWidgetSection.applyParameter}}" stepKey="clickApplyButton"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/************************************************************************
*
* Copyright 2023 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ***********************************************************************
*/
-->

<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StorefrontBundleAddToCartFromWidget">
<annotations>
<features value="Bundle"/>
<stories value="Bundle product details page"/>
<title value="Customer should be able to add a bundle product to the cart from widget"/>
<description value="Customer should be able to add a bundle product to the cart from widget"/>
<severity value="CRITICAL"/>
<testCaseId value="AC-10867"/>
<useCaseId value="ACP2E-2615"/>
<group value="WYSIWYGDisabled"/>
<group value="Bundle"/>
</annotations>
<before>
<actionGroup ref="AdminLoginActionGroup" stepKey="login"/>
<createData entity="SimpleProduct2" stepKey="simpleProduct1"/>
</before>
<after>
<actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteBundleProductBySku">
<argument name="sku" value="{{BundleProductWithSlashSku.sku}}"/>
</actionGroup>
<deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/>
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
</after>

<!-- Start creating a bundle product -->
<actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="goToProductList"/>
<actionGroup ref="GoToCreateProductPageActionGroup" stepKey="goToCreateProduct">
<argument name="product" value="BundleProduct"/>
</actionGroup>
<actionGroup ref="FillProductNameAndSkuInProductFormActionGroup" stepKey="fillNameAndSku">
<argument name="product" value="BundleProductWithSlashSku"/>
</actionGroup>

<!-- Add Option One, a "Drop-down" type option -->
<actionGroup ref="AddBundleOptionWithOneProductActionGroup" stepKey="addBundleOptionWithOneProduct">
<argument name="x" value="0"/>
<argument name="n" value="1"/>
<argument name="prodOneSku" value="$$simpleProduct1.sku$$"/>
<argument name="prodTwoSku" value=""/>
<argument name="optionTitle" value="Option One"/>
<argument name="inputType" value="select"/>
</actionGroup>

<!-- Save product, edit Homepage CMS page and add products widget -->
<actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/>
<amOnPage url="{{AdminCmsPageEditPage.url(CmsHomePageContent.page_id)}}" stepKey="navigateToEditCmsHomePage"/>
<click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" />
<actionGroup ref="AdminInsertWidgetToCmsPageContentActionGroup" stepKey="insertWidgetToCmsPageContentActionGroup">
<argument name="widgetType" value="Catalog Products List"/>
</actionGroup>
<actionGroup ref="AdminFillCatalogProductsListWidgetSkuActionGroup" stepKey="selectProductForListing">
<argument name="sku" value="{{BundleProductWithSlashSku.sku}}"/>
</actionGroup>
<actionGroup ref="AdminClickInsertWidgetActionGroup" stepKey="clickInsertWidgetButton2"/>
<actionGroup ref="SaveCmsPageActionGroup" stepKey="clickSaveButton"/>
<see selector="{{AdminMessagesSection.success}}" userInput="You saved the page." stepKey="seeSuccess"/>

<!-- Go to storefront homepage and add to cart -->
<actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/>
<actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/>
<actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/>
<waitForPageLoad stepKey="waitForProductAdded"/>
<waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="seeSuccessMessage"/>
</test>
</tests>
22 changes: 21 additions & 1 deletion app/code/Magento/CatalogWidget/Block/Product/ProductsList.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\Catalog\ViewModel\Product\OptionsData;
use Magento\CatalogWidget\Model\Rule;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Http\Context as HttpContext;
Expand Down Expand Up @@ -130,6 +131,11 @@ class ProductsList extends AbstractProduct implements BlockInterface, IdentityIn
*/
private $categoryRepository;

/**
* @var OptionsData
*/
private OptionsData $optionsData;

/**
* @param Context $context
* @param CollectionFactory $productCollectionFactory
Expand All @@ -143,6 +149,7 @@ class ProductsList extends AbstractProduct implements BlockInterface, IdentityIn
* @param LayoutFactory|null $layoutFactory
* @param EncoderInterface|null $urlEncoder
* @param CategoryRepositoryInterface|null $categoryRepository
* @param OptionsData|null $optionsData
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
Expand All @@ -158,7 +165,8 @@ public function __construct(
Json $json = null,
LayoutFactory $layoutFactory = null,
EncoderInterface $urlEncoder = null,
CategoryRepositoryInterface $categoryRepository = null
CategoryRepositoryInterface $categoryRepository = null,
OptionsData $optionsData = null
) {
$this->productCollectionFactory = $productCollectionFactory;
$this->catalogProductVisibility = $catalogProductVisibility;
Expand All @@ -171,6 +179,7 @@ public function __construct(
$this->urlEncoder = $urlEncoder ?: ObjectManager::getInstance()->get(EncoderInterface::class);
$this->categoryRepository = $categoryRepository ?? ObjectManager::getInstance()
->get(CategoryRepositoryInterface::class);
$this->optionsData = $optionsData ?: ObjectManager::getInstance()->get(OptionsData::class);
parent::__construct(
$context,
$data
Expand Down Expand Up @@ -306,6 +315,17 @@ public function getAddToCartPostParams(Product $product)
];
}

/**
* Return product options
*
* @param Product $product
* @return array
*/
public function getOptionsData(Product $product): array
{
return $this->optionsData->getOptionsData($product);
}

/**
* @inheritdoc
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ use Magento\Wishlist\Helper\Data;
<?php if ($_item->isSaleable()): ?>
<?php $postParams = $block->getAddToCartPostParams($_item); ?>
<form data-role="tocart-form" data-product-sku="<?= $escaper->escapeHtml($_item->getSku()) ?>" action="<?= $escaper->escapeUrl($postParams['action']) ?>" method="post">
<?php $options = $block->getOptionsData($_item); ?>
<?php foreach ($options as $optionItem): ?>
<input type="hidden"
name="<?= $escaper->escapeHtml($optionItem['name']) ?>"
value="<?= $escaper->escapeHtml($optionItem['value']) ?>">
<?php endforeach; ?>
<input type="hidden" name="product" value="<?= $escaper->escapeHtmlAttr($postParams['data']['product']) ?>">
<input type="hidden" name="<?= /* @noEscape */ Action::PARAM_NAME_URL_ENCODED ?>" value="<?= /* @noEscape */ $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>">
<?= $block->getBlockHtml('formkey') ?>
Expand Down Expand Up @@ -107,13 +113,13 @@ use Magento\Wishlist\Helper\Data;
<div class="actions-secondary" data-role="add-to-links">
<?php if ($this->helper(Data::class)->isAllow() && $showWishlist): ?>
<a href="#"
data-post='<?= /* @noEscape */ $block->getAddToWishlistParams($_item) ?>' class="action towishlist" data-action="add-to-wishlist" title="<?= $block->escapeHtmlAttr(__('Add to Wish List')) ?>">
data-post='<?= /* @noEscape */ $block->getAddToWishlistParams($_item) ?>' class="action towishlist" data-action="add-to-wishlist" title="<?= $escaper->escapeHtmlAttr(__('Add to Wish List')) ?>">
<span><?= $escaper->escapeHtml(__('Add to Wish List')) ?></span>
</a>
<?php endif; ?>
<?php if ($block->getAddToCompareUrl() && $showCompare): ?>
<?php $compareHelper = $this->helper(Compare::class);?>
<a href="#" class="action tocompare" data-post='<?= /* @noEscape */ $compareHelper->getPostDataParams($_item) ?>' title="<?= $block->escapeHtmlAttr(__('Add to Compare')) ?>">
<a href="#" class="action tocompare" data-post='<?= /* @noEscape */ $compareHelper->getPostDataParams($_item) ?>' title="<?= $escaper->escapeHtmlAttr(__('Add to Compare')) ?>">
<span><?= $escaper->escapeHtml(__('Add to Compare')) ?></span>
</a>
<?php endif; ?>
Expand Down
42 changes: 22 additions & 20 deletions app/code/Magento/Sales/Api/Data/ShipmentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
* Shipment interface.
*
* A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This
* document lists the products and their quantities in the delivery package.
* document lists the products and their quantities in the delivery package. This interface creates shipment
* record without items quantity (total_qty) validation. To validate total shipped quantity for each item
* in the order you must use newer `POST /V1/order/:orderId/ship` endpoint.
* @api
* @since 100.0.2
*/
Expand All @@ -21,75 +23,75 @@ interface ShipmentInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
/*
* Entity ID.
*/
const ENTITY_ID = 'entity_id';
public const ENTITY_ID = 'entity_id';
/*
* Store ID.
*/
const STORE_ID = 'store_id';
public const STORE_ID = 'store_id';
/*
* Total weight.
*/
const TOTAL_WEIGHT = 'total_weight';
public const TOTAL_WEIGHT = 'total_weight';
/*
* Total quantity.
* Total quantity. Can be greater than ordered quantity (not validated).
*/
const TOTAL_QTY = 'total_qty';
public const TOTAL_QTY = 'total_qty';
/*
* Email sent flag.
*/
const EMAIL_SENT = 'email_sent';
public const EMAIL_SENT = 'email_sent';
/*
* Order ID.
*/
const ORDER_ID = 'order_id';
public const ORDER_ID = 'order_id';
/*
* Customer ID.
*/
const CUSTOMER_ID = 'customer_id';
public const CUSTOMER_ID = 'customer_id';
/*
* Shipping address ID.
*/
const SHIPPING_ADDRESS_ID = 'shipping_address_id';
public const SHIPPING_ADDRESS_ID = 'shipping_address_id';
/*
* Billing address ID.
*/
const BILLING_ADDRESS_ID = 'billing_address_id';
public const BILLING_ADDRESS_ID = 'billing_address_id';
/*
* Shipment status.
*/
const SHIPMENT_STATUS = 'shipment_status';
public const SHIPMENT_STATUS = 'shipment_status';
/*
* Increment ID.
*/
const INCREMENT_ID = 'increment_id';
public const INCREMENT_ID = 'increment_id';
/*
* Created-at timestamp.
*/
const CREATED_AT = 'created_at';
public const CREATED_AT = 'created_at';
/*
* Updated-at timestamp.
*/
const UPDATED_AT = 'updated_at';
public const UPDATED_AT = 'updated_at';
/*
* Packages.
*/
const PACKAGES = 'packages';
public const PACKAGES = 'packages';
/*
* Shipping label.
*/
const SHIPPING_LABEL = 'shipping_label';
public const SHIPPING_LABEL = 'shipping_label';
/*
* Items.
*/
const ITEMS = 'items';
public const ITEMS = 'items';
/*
* Tracks.
*/
const TRACKS = 'tracks';
public const TRACKS = 'tracks';
/*
* Comments.
*/
const COMMENTS = 'comments';
public const COMMENTS = 'comments';

/**
* Gets the billing address ID for the shipment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,62 @@ public function testRemoveTriggersNoChanges(): void
$this->model->removeTriggers();
}

public function testRemoveTriggersNotLinked(): void
{
$DBTriggers = [
'trg_catalog_category_entity_int_after_insert' => [
'TRIGGER_NAME' => 'trg_catalog_category_entity_int_after_insert',
'ACTION_STATEMENT' => 'BEGIN statement; END',
'EVENT_OBJECT_TABLE' => 'catalog_category_entity_int'
],
'not_linked_trg_catalog_category_entity_int_after_insert' => [
'TRIGGER_NAME' => 'trg_catalog_category_entity_int_after_insert',
'ACTION_STATEMENT' => 'BEGIN statement; END',
'EVENT_OBJECT_TABLE' => 'catalog_category_entity_int'
]
];

$connectionMock = $this->getConnectionMock();
$connectionMock->expects($this->once())
->method('fetchAssoc')
->willReturn($DBTriggers);

$this->resource->expects($this->once())->method('getConnection')->willReturn($connectionMock);

$triggerMock = $this->getMockBuilder(Trigger::class)
->disableOriginalConstructor()
->onlyMethods(['getName', 'getStatements'])
->getMockForAbstractClass();
$triggerMock->expects($this->atLeastOnce())
->method('getName')
->willReturn('trg_catalog_category_entity_int_after_insert');
$triggerMock->expects($this->once())->method('getStatements')->willReturn(['statement;']);

$subscriptionMock = $this->createMock(Subscription::class);
$subscriptionMock->expects($this->once())->method('getTriggers')->willReturn([$triggerMock]);
$subscriptionMock->expects($this->once())->method('create')->willReturn($subscriptionMock);

$viewMock = $this->createMock(View::class);
$viewMock->expects($this->once())
->method('getSubscriptions')
->willReturn(['subscriptionConfig' => []]);
$viewMock->expects($this->once())->method('initSubscriptionInstance')->willReturn($subscriptionMock);

$viewCollectionMock = $this->getMockForAbstractClass(CollectionInterface::class);
$viewCollectionMock->expects($this->once())->method('getViewsByStateMode')->willReturn([$viewMock]);

$this->viewCollectionFactory->expects($this->once())->method('create')->willReturn($viewCollectionMock);

$subscriptionMock->expects($this->never())->method('saveTrigger');
$viewMock->expects($this->once())->method('unsubscribe');

$this->viewFactory->expects($this->once())->method('create')->willReturn($viewMock);
$state = $this->createMock(\Magento\Indexer\Model\Mview\View\State::class);
$viewMock->expects($this->once())->method('getActionClass')->willReturn(true);
$viewMock->expects($this->exactly(2))->method('getState')->willReturn($state);
$this->model->removeTriggers();
}

/**
* Prepare connection mock
*
Expand Down
Loading

0 comments on commit fe2e144

Please sign in to comment.