@@ -45,4 +45,7 @@
+
+
+
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
index 36f9d35327fc..28395f8eeb84 100644
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
+++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
@@ -7,8 +7,9 @@
/**
* @var $block \Magento\OfflinePayments\Block\Info\Checkmo
*/
+$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId());
?>
-= $block->escapeHtml($block->getMethod()->getTitle()) ?>
+= $block->escapeHtml($paymentTitle) ?>
getInfo()->getAdditionalInformation()) : ?>
getPayableTo()) : ?>
= $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?>
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
index d8d952526e67..f85a8f8357dd 100644
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
+++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
@@ -7,8 +7,9 @@
/**
* @var $block \Magento\OfflinePayments\Block\Info\Checkmo
*/
+$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId());
?>
-= $block->escapeHtml($block->getMethod()->getTitle()) ?>
+= $block->escapeHtml($paymentTitle) ?>
{{pdf_row_separator}}
getInfo()->getAdditionalInformation()) : ?>
{{pdf_row_separator}}
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml
index 2a6de7f0cc35..ae7f654a1350 100644
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml
+++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml
@@ -6,8 +6,9 @@
/**
* @var $block \Magento\OfflinePayments\Block\Info\Purchaseorder
*/
+$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId());
?>
-= $block->escapeHtml($block->getMethod()->getTitle()) ?>
+= $block->escapeHtml($paymentTitle) ?>
= $block->escapeHtml(__('Purchase Order Number')) ?>: |
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
index 8b9c37f11256..3cd88bddbfb1 100644
--- a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
+++ b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml
@@ -9,8 +9,9 @@
* @see \Magento\Payment\Block\Info
*/
$specificInfo = $block->getSpecificInformation();
+$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId());
?>
-= $block->escapeHtml($block->getMethod()->getTitle()) ?>
+= $block->escapeHtml($paymentTitle) ?>
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
index a8583ea5549f..54b9e48d07a9 100644
--- a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
+++ b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml
@@ -8,8 +8,9 @@
* @see \Magento\Payment\Block\Info
* @var \Magento\Payment\Block\Info $block
*/
+$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId());
?>
-= $block->escapeHtml($block->getMethod()->getTitle()) ?>{{pdf_row_separator}}
+= $block->escapeHtml($paymentTitle) ?>{{pdf_row_separator}}
getSpecificInformation()) : ?>
$value) : ?>
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php
index 9a271f741edd..001c581dc0da 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php
@@ -5,8 +5,7 @@
*/
namespace Magento\Sales\Block\Adminhtml\Order\Create\Search;
-use Magento\Sales\Block\Adminhtml\Order\Create\Search\Grid\DataProvider\ProductCollection
- as ProductCollectionDataProvider;
+use Magento\Sales\Block\Adminhtml\Order\Create\Search\Grid\DataProvider\ProductCollection;
use Magento\Framework\App\ObjectManager;
/**
@@ -48,7 +47,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
protected $_productFactory;
/**
- * @var ProductCollectionDataProvider $productCollectionProvider
+ * @var ProductCollection $productCollectionProvider
*/
private $productCollectionProvider;
@@ -60,7 +59,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
* @param \Magento\Backend\Model\Session\Quote $sessionQuote
* @param \Magento\Sales\Model\Config $salesConfig
* @param array $data
- * @param ProductCollectionDataProvider|null $productCollectionProvider
+ * @param ProductCollection|null $productCollectionProvider
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
@@ -70,14 +69,14 @@ public function __construct(
\Magento\Backend\Model\Session\Quote $sessionQuote,
\Magento\Sales\Model\Config $salesConfig,
array $data = [],
- ProductCollectionDataProvider $productCollectionProvider = null
+ ProductCollection $productCollectionProvider = null
) {
$this->_productFactory = $productFactory;
$this->_catalogConfig = $catalogConfig;
$this->_sessionQuote = $sessionQuote;
$this->_salesConfig = $salesConfig;
$this->productCollectionProvider = $productCollectionProvider
- ?: ObjectManager::getInstance()->get(ProductCollectionDataProvider::class);
+ ?: ObjectManager::getInstance()->get(ProductCollection::class);
parent::__construct($context, $backendHelper, $data);
}
@@ -94,6 +93,7 @@ protected function _construct()
$this->setCheckboxCheckCallback('order.productGridCheckboxCheck.bind(order)');
$this->setRowInitCallback('order.productGridRowInit.bind(order)');
$this->setDefaultSort('entity_id');
+ $this->setFilterKeyPressCallback('order.productGridFilterKeyPress');
$this->setUseAjax(true);
if ($this->getRequest()->getParam('collapse')) {
$this->setIsCollapsed(true);
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
index 341ee16ae910..45cd504be201 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
@@ -188,7 +188,7 @@ protected function _processActionData($action = null)
&& $this->_getOrderCreateModel()->getShippingAddress()->getSameAsBilling() && empty($shippingMethod)
) {
$this->_getOrderCreateModel()->setShippingAsBilling(1);
- } else {
+ } elseif ($syncFlag !== null) {
$this->_getOrderCreateModel()->setShippingAsBilling((int)$syncFlag);
}
}
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml
index 3f178ae02102..90e2aa8e1252 100644
--- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml
@@ -92,7 +92,7 @@
Clears the Email, First Name, Last Name, Street Line 1, City, Postal Code and Phone fields when adding an Order and then verifies that they are required after attempting to Save.
-
+
@@ -181,7 +181,7 @@
EXTENDS: addConfigurableProductToOrder. Selects the provided Option to the Configurable Product.
-
+
@@ -195,7 +195,7 @@
-
+
@@ -213,7 +213,7 @@
-
+
@@ -235,7 +235,7 @@
-
+
{{price}}
@@ -320,6 +320,22 @@
+
+
+ Change Shipping Method on the Admin 'Create New Order for' page.
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -516,7 +532,7 @@
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormBillingAddressSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormBillingAddressSection.xml
index 2d1a4d5a4cba..4fde9db1d21d 100644
--- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormBillingAddressSection.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormBillingAddressSection.xml
@@ -9,6 +9,7 @@
-
\ No newline at end of file
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
index b31582552ccc..a478d79d8553 100644
--- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
@@ -9,6 +9,7 @@
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderForCustomerWithTwoAddressesTaxableAndNonTaxableTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderForCustomerWithTwoAddressesTaxableAndNonTaxableTest.xml
new file mode 100644
index 000000000000..d6bf0eec301d
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderForCustomerWithTwoAddressesTaxableAndNonTaxableTest.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
index 3fe9d0878288..4e0741451074 100644
--- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
+++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
@@ -795,6 +795,20 @@ define([
grid.reloadParams = {'products[]':this.gridProducts.keys()};
},
+ productGridFilterKeyPress: function (grid, event) {
+ var returnKey = parseInt(Event.KEY_RETURN || 13, 10);
+
+ if (event.keyCode === returnKey) {
+ if (typeof event.stopPropagation === 'function') {
+ event.stopPropagation();
+ }
+
+ if (typeof event.preventDefault === 'function') {
+ event.preventDefault();
+ }
+ }
+ },
+
/**
* Submit configured products to quote
*/
diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
index 0acece9271f7..e6b03755bea4 100644
--- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
+++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
@@ -31,6 +31,11 @@ class EntityUrl implements ResolverInterface
*/
private $customUrlLocator;
+ /**
+ * @var int
+ */
+ private $redirectType;
+
/**
* @param UrlFinderInterface $urlFinder
* @param CustomUrlLocatorInterface $customUrlLocator
@@ -57,49 +62,83 @@ public function resolve(
throw new GraphQlInputException(__('"url" argument should be specified and not empty'));
}
+ $storeId = (int)$context->getExtensionAttributes()->getStore()->getId();
$result = null;
$url = $args['url'];
if (substr($url, 0, 1) === '/' && $url !== '/') {
$url = ltrim($url, '/');
}
+ $this->redirectType = 0;
$customUrl = $this->customUrlLocator->locateUrl($url);
$url = $customUrl ?: $url;
- $urlRewrite = $this->findCanonicalUrl($url, (int)$context->getExtensionAttributes()->getStore()->getId());
- if ($urlRewrite) {
- if (!$urlRewrite->getEntityId()) {
+ $finalUrlRewrite = $this->findFinalUrl($url, $storeId);
+ if ($finalUrlRewrite) {
+ $relativeUrl = $finalUrlRewrite->getRequestPath();
+ $resultArray = $this->rewriteCustomUrls($finalUrlRewrite, $storeId) ?? [
+ 'id' => $finalUrlRewrite->getEntityId(),
+ 'canonical_url' => $relativeUrl,
+ 'relative_url' => $relativeUrl,
+ 'redirectCode' => $this->redirectType,
+ 'type' => $this->sanitizeType($finalUrlRewrite->getEntityType())
+ ];
+
+ if (empty($resultArray['id'])) {
throw new GraphQlNoSuchEntityException(
__('No such entity found with matching URL key: %url', ['url' => $url])
);
}
- $result = [
- 'id' => $urlRewrite->getEntityId(),
- 'canonical_url' => $urlRewrite->getTargetPath(),
- 'relative_url' => $urlRewrite->getTargetPath(),
- 'type' => $this->sanitizeType($urlRewrite->getEntityType())
- ];
+
+ $result = $resultArray;
}
return $result;
}
/**
- * Find the canonical url passing through all redirects if any
+ * Handle custom urls with and without redirects
+ *
+ * @param UrlRewrite $finalUrlRewrite
+ * @param int $storeId
+ * @return array|null
+ */
+ private function rewriteCustomUrls(UrlRewrite $finalUrlRewrite, int $storeId): ?array
+ {
+ if ($finalUrlRewrite->getEntityType() === 'custom' || !($finalUrlRewrite->getEntityId() > 0)) {
+ $finalCustomUrlRewrite = clone $finalUrlRewrite;
+ $finalUrlRewrite = $this->findFinalUrl($finalCustomUrlRewrite->getTargetPath(), $storeId, true);
+ $relativeUrl =
+ $finalCustomUrlRewrite->getRedirectType() == 0
+ ? $finalCustomUrlRewrite->getRequestPath() : $finalUrlRewrite->getRequestPath();
+ return [
+ 'id' => $finalUrlRewrite->getEntityId(),
+ 'canonical_url' => $relativeUrl,
+ 'relative_url' => $relativeUrl,
+ 'redirectCode' => $finalCustomUrlRewrite->getRedirectType(),
+ 'type' => $this->sanitizeType($finalUrlRewrite->getEntityType())
+ ];
+ }
+ return null;
+ }
+
+ /**
+ * Find the final url passing through all redirects if any
*
* @param string $requestPath
* @param int $storeId
+ * @param bool $findCustom
* @return UrlRewrite|null
*/
- private function findCanonicalUrl(string $requestPath, int $storeId) : ?UrlRewrite
+ private function findFinalUrl(string $requestPath, int $storeId, bool $findCustom = false): ?UrlRewrite
{
$urlRewrite = $this->findUrlFromRequestPath($requestPath, $storeId);
- if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
+ if ($urlRewrite) {
+ $this->redirectType = $urlRewrite->getRedirectType();
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath(), $storeId);
}
- }
- if (!$urlRewrite) {
+ } else {
$urlRewrite = $this->findUrlFromTargetPath($requestPath, $storeId);
}
- if ($urlRewrite && !$urlRewrite->getEntityId() && !$urlRewrite->getIsAutogenerated()) {
+ if ($urlRewrite && ($findCustom && !$urlRewrite->getEntityId() && !$urlRewrite->getIsAutogenerated())) {
$urlRewrite = $this->findUrlFromTargetPath($urlRewrite->getTargetPath(), $storeId);
}
@@ -113,7 +152,7 @@ private function findCanonicalUrl(string $requestPath, int $storeId) : ?UrlRewri
* @param int $storeId
* @return UrlRewrite|null
*/
- private function findUrlFromRequestPath(string $requestPath, int $storeId) : ?UrlRewrite
+ private function findUrlFromRequestPath(string $requestPath, int $storeId): ?UrlRewrite
{
return $this->urlFinder->findOneByData(
[
@@ -130,7 +169,7 @@ private function findUrlFromRequestPath(string $requestPath, int $storeId) : ?Ur
* @param int $storeId
* @return UrlRewrite|null
*/
- private function findUrlFromTargetPath(string $targetPath, int $storeId) : ?UrlRewrite
+ private function findUrlFromTargetPath(string $targetPath, int $storeId): ?UrlRewrite
{
return $this->urlFinder->findOneByData(
[
diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
index ace3e0eae831..7f7ebb627b4d 100644
--- a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
@@ -9,6 +9,7 @@ type EntityUrl @doc(description: "EntityUrl is an output object containing the `
id: Int @doc(description: "The ID assigned to the object associated with the specified url. This could be a product ID, category ID, or page ID.")
canonical_url: String @deprecated(reason: "The canonical_url field is deprecated, use relative_url instead.")
relative_url: String @doc(description: "The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original.")
+ redirectCode: Int @doc(description: "301 or 302 HTTP code for url permanent or temporary redirect or 0 for the 200 no redirect")
type: UrlRewriteEntityTypeEnum @doc(description: "One of PRODUCT, CATEGORY, or CMS_PAGE.")
}
diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php
new file mode 100644
index 000000000000..d2ea44fff5bc
--- /dev/null
+++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php
@@ -0,0 +1,118 @@
+ 'INCLUDE_FPT_WITHOUT_DETAILS',
+ WeeeDisplayConfig::DISPLAY_INCL_DESCR => 'INCLUDE_FPT_WITH_DETAILS',
+ WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL => 'EXCLUDE_FPT_AND_INCLUDE_WITH_DETAILS',
+ WeeeDisplayConfig::DISPLAY_EXCL => 'EXCLUDE_FPT_WITHOUT_DETAILS'
+ ];
+
+ /**
+ * @var Data
+ */
+ private $weeeHelper;
+
+ /**
+ * @var TaxHelper
+ */
+ private $taxHelper;
+
+ /**
+ * @var array
+ */
+ private $computedFptSettings = [];
+
+ /**
+ * @param Data $weeeHelper
+ * @param TaxHelper $taxHelper
+ */
+ public function __construct(Data $weeeHelper, TaxHelper $taxHelper)
+ {
+ $this->weeeHelper = $weeeHelper;
+ $this->taxHelper = $taxHelper;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (empty($this->computedFptSettings)) {
+ /** @var StoreInterface $store */
+ $store = $context->getExtensionAttributes()->getStore();
+ $storeId = (int)$store->getId();
+
+ $this->computedFptSettings = [
+ 'product_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone,
+ 'category_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone,
+ 'sales_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone,
+ ];
+ if ($this->weeeHelper->isEnabled($store)) {
+ $productFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_ITEM_VIEW, $storeId);
+ $categoryFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_ITEM_LIST, $storeId);
+ $salesModulesFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_SALES, $storeId);
+
+ $this->computedFptSettings = [
+ 'product_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$productFptDisplay] ??
+ self::$weeeDisplaySettingsNone,
+ 'category_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$categoryFptDisplay] ??
+ self::$weeeDisplaySettingsNone,
+ 'sales_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$salesModulesFptDisplay] ??
+ self::$weeeDisplaySettingsNone,
+ ];
+ }
+ }
+
+ return $this->computedFptSettings[$info->fieldName] ?? null;
+ }
+
+ /**
+ * Get the weee system display setting
+ *
+ * @param string $zone
+ * @param string $storeId
+ * @return string
+ */
+ private function getWeeDisplaySettingsByZone(string $zone, int $storeId): int
+ {
+ return (int) $this->weeeHelper->typeOfDisplay(
+ null,
+ $zone,
+ $storeId
+ );
+ }
+}
diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls
index 5c6d2f98b43f..18b0e7c1823e 100644
--- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls
@@ -14,3 +14,17 @@ type FixedProductTax @doc(description: "A single FPT that can be applied to a pr
amount: Money @doc(description: "Amount of the FPT as a money object.")
label: String @doc(description: "The label assigned to the FPT to be displayed on the frontend.")
}
+
+type StoreConfig {
+ product_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "Corresponds to the 'Display Prices On Product View Page' field. It indicates how FPT information is displayed on product pages") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig")
+ category_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "Corresponds to the 'Display Prices In Product Lists' field. It indicates how FPT information is displayed on category pages") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig")
+ sales_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "Corresponds to the 'Display Prices In Sales Modules' field. It indicates how FPT information is displayed on cart, checkout, and order pages") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig")
+}
+
+enum FixedProductTaxDisplaySettings @doc(description: "This enumeration display settings for the fixed product tax") {
+ INCLUDE_FPT_WITHOUT_DETAILS @doc(description: "The displayed price includes the FPT amount without displaying the ProductPrice.fixed_product_taxes values. This value corresponds to 'Including FPT only'")
+ INCLUDE_FPT_WITH_DETAILS @doc(description: "The displayed price includes the FPT amount while displaying the values of ProductPrice.fixed_product_taxes separately. This value corresponds to 'Including FPT and FPT description'")
+ EXCLUDE_FPT_AND_INCLUDE_WITH_DETAILS @doc(description: "The displayed price does not include the FPT amount. The values of ProductPrice.fixed_product_taxes and the price including the FPT are displayed separately. This value corresponds to 'Excluding FPT, Including FPT description and final price'")
+ EXCLUDE_FPT_WITHOUT_DETAILS @doc(description: "The displayed price does not include the FPT amount. The values from ProductPrice.fixed_product_taxes are not displayed. This value corresponds to 'Excluding FPT'")
+ FPT_DISABLED @doc(description: "The FPT feature is not enabled. You can omit ProductPrice.fixed_product_taxes from your query")
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php
new file mode 100644
index 000000000000..0e88af2fcb22
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php
@@ -0,0 +1,476 @@
+graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertCount(1, $result['categoryList']);
+ $this->assertResponseFields($result['categoryList'][0], $expectedResult);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ * @dataProvider filterMultipleCategoriesDataProvider
+ * @param $field
+ * @param $condition
+ * @param $value
+ * @param $expectedResult
+ */
+ public function testFilterMultipleCategoriesByField($field, $condition, $value, $expectedResult)
+ {
+ $query = <<graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertCount(count($expectedResult), $result['categoryList']);
+ foreach ($expectedResult as $i => $expected) {
+ $this->assertResponseFields($result['categoryList'][$i], $expected);
+ }
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testFilterCategoryByMultipleFields()
+ {
+ $query = <<graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertCount(3, $result['categoryList']);
+
+ $expectedCategories = [7 => 'Movable', 9 => 'Movable Position 1', 10 => 'Movable Position 2'];
+ $actualCategories = array_column($result['categoryList'], 'name', 'id');
+ $this->assertEquals($expectedCategories, $actualCategories);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testFilterWithInactiveCategory()
+ {
+ $query = <<graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertCount(1, $result['categoryList']);
+ $actualCategories = array_column($result['categoryList'], 'url_key', 'id');
+ $this->assertContains('category-2', $actualCategories);
+ $this->assertNotContains('inactive', $actualCategories);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testQueryChildCategoriesWithProducts()
+ {
+ $query = <<graphQlQuery($query);
+
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertCount(1, $result['categoryList']);
+ $baseCategory = $result['categoryList'][0];
+
+ $this->assertEquals('Category 1', $baseCategory['name']);
+ $this->assertArrayHasKey('products', $baseCategory);
+ //Check base category products
+ $expectedBaseCategoryProducts = [
+ ['sku' => 'simple', 'name' => 'Simple Product'],
+ ['sku' => '12345', 'name' => 'Simple Product Two'],
+ ['sku' => 'simple-4', 'name' => 'Simple Product Three']
+ ];
+ $this->assertCategoryProducts($baseCategory, $expectedBaseCategoryProducts);
+ //Check base category children
+ $expectedBaseCategoryChildren = [
+ ['name' => 'Category 1.1', 'description' => 'Category 1.1 description.'],
+ ['name' => 'Category 1.2', 'description' => 'Its a description of Test Category 1.2']
+ ];
+ $this->assertCategoryChildren($baseCategory, $expectedBaseCategoryChildren);
+
+ //Check first child category
+ $firstChildCategory = $baseCategory['children'][0];
+ $this->assertEquals('Category 1.1', $firstChildCategory['name']);
+ $this->assertEquals('Category 1.1 description.', $firstChildCategory['description']);
+ $firstChildCategoryExpectedProducts = [
+ ['sku' => 'simple', 'name' => 'Simple Product'],
+ ['sku' => '12345', 'name' => 'Simple Product Two'],
+ ];
+ $this->assertCategoryProducts($firstChildCategory, $firstChildCategoryExpectedProducts);
+ $firstChildCategoryChildren = [['name' =>'Category 1.1.1']];
+ $this->assertCategoryChildren($firstChildCategory, $firstChildCategoryChildren);
+ //Check second child category
+ $secondChildCategory = $baseCategory['children'][1];
+ $this->assertEquals('Category 1.2', $secondChildCategory['name']);
+ $this->assertEquals('Its a description of Test Category 1.2', $secondChildCategory['description']);
+ $firstChildCategoryExpectedProducts = [
+ ['sku' => 'simple', 'name' => 'Simple Product'],
+ ['sku' => 'simple-4', 'name' => 'Simple Product Three']
+ ];
+ $this->assertCategoryProducts($secondChildCategory, $firstChildCategoryExpectedProducts);
+ $firstChildCategoryChildren = [];
+ $this->assertCategoryChildren($secondChildCategory, $firstChildCategoryChildren);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testNoResultsFound()
+ {
+ $query = <<graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertArrayHasKey('categoryList', $result);
+ $this->assertEquals([], $result['categoryList']);
+ }
+
+ /**
+ * When no filters are supplied, the root category is returned
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testEmptyFiltersReturnRootCategory()
+ {
+ $query = <<get(StoreManagerInterface::class);
+ $storeRootCategoryId = $storeManager->getStore()->getRootCategoryId();
+
+ $result = $this->graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertArrayHasKey('categoryList', $result);
+ $this->assertEquals('Default Category', $result['categoryList'][0]['name']);
+ $this->assertEquals($storeRootCategoryId, $result['categoryList'][0]['id']);
+ }
+
+ /**
+ * Filtering with match value less than minimum query should return empty result
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/categories.php
+ */
+ public function testMinimumMatchQueryLength()
+ {
+ $query = <<graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertArrayHasKey('categoryList', $result);
+ $this->assertEquals([], $result['categoryList']);
+ }
+
+ /**
+ * @return array
+ */
+ public function filterSingleCategoryDataProvider(): array
+ {
+ return [
+ [
+ 'ids',
+ 'eq',
+ '4',
+ [
+ 'id' => '4',
+ 'name' => 'Category 1.1',
+ 'url_key' => 'category-1-1',
+ 'url_path' => 'category-1/category-1-1',
+ 'children_count' => '0',
+ 'path' => '1/2/3/4',
+ 'position' => '1'
+ ]
+ ],
+ [
+ 'name',
+ 'match',
+ 'Movable Position 2',
+ [
+ 'id' => '10',
+ 'name' => 'Movable Position 2',
+ 'url_key' => 'movable-position-2',
+ 'url_path' => 'movable-position-2',
+ 'children_count' => '0',
+ 'path' => '1/2/10',
+ 'position' => '6'
+ ]
+ ],
+ [
+ 'url_key',
+ 'eq',
+ 'category-1-1-1',
+ [
+ 'id' => '5',
+ 'name' => 'Category 1.1.1',
+ 'url_key' => 'category-1-1-1',
+ 'url_path' => 'category-1/category-1-1/category-1-1-1',
+ 'children_count' => '0',
+ 'path' => '1/2/3/4/5',
+ 'position' => '1'
+ ]
+ ],
+ ];
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @return array
+ */
+ public function filterMultipleCategoriesDataProvider(): array
+ {
+ return[
+ //Filter by multiple IDs
+ [
+ 'ids',
+ 'in',
+ '["4", "9", "10"]',
+ [
+ [
+ 'id' => '4',
+ 'name' => 'Category 1.1',
+ 'url_key' => 'category-1-1',
+ 'url_path' => 'category-1/category-1-1',
+ 'children_count' => '0',
+ 'path' => '1/2/3/4',
+ 'position' => '1'
+ ],
+ [
+ 'id' => '9',
+ 'name' => 'Movable Position 1',
+ 'url_key' => 'movable-position-1',
+ 'url_path' => 'movable-position-1',
+ 'children_count' => '0',
+ 'path' => '1/2/9',
+ 'position' => '5'
+ ],
+ [
+ 'id' => '10',
+ 'name' => 'Movable Position 2',
+ 'url_key' => 'movable-position-2',
+ 'url_path' => 'movable-position-2',
+ 'children_count' => '0',
+ 'path' => '1/2/10',
+ 'position' => '6'
+ ]
+ ]
+ ],
+ //Filter by multiple url keys
+ [
+ 'url_key',
+ 'in',
+ '["category-1-2", "movable"]',
+ [
+ [
+ 'id' => '7',
+ 'name' => 'Movable',
+ 'url_key' => 'movable',
+ 'url_path' => 'movable',
+ 'children_count' => '0',
+ 'path' => '1/2/7',
+ 'position' => '3'
+ ],
+ [
+ 'id' => '13',
+ 'name' => 'Category 1.2',
+ 'url_key' => 'category-1-2',
+ 'url_path' => 'category-1/category-1-2',
+ 'children_count' => '0',
+ 'path' => '1/2/3/13',
+ 'position' => '2'
+ ]
+ ]
+ ],
+ //Filter by matching multiple names
+ [
+ 'name',
+ 'match',
+ '"Position"',
+ [
+ [
+ 'id' => '9',
+ 'name' => 'Movable Position 1',
+ 'url_key' => 'movable-position-1',
+ 'url_path' => 'movable-position-1',
+ 'children_count' => '0',
+ 'path' => '1/2/9',
+ 'position' => '5'
+ ],
+ [
+ 'id' => '10',
+ 'name' => 'Movable Position 2',
+ 'url_key' => 'movable-position-2',
+ 'url_path' => 'movable-position-2',
+ 'children_count' => '0',
+ 'path' => '1/2/10',
+ 'position' => '6'
+ ],
+ [
+ 'id' => '11',
+ 'name' => 'Movable Position 3',
+ 'url_key' => 'movable-position-3',
+ 'url_path' => 'movable-position-3',
+ 'children_count' => '0',
+ 'path' => '1/2/11',
+ 'position' => '7'
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Check category products
+ *
+ * @param array $category
+ * @param array $expectedProducts
+ */
+ private function assertCategoryProducts(array $category, array $expectedProducts)
+ {
+ $this->assertEquals(count($expectedProducts), $category['products']['total_count']);
+ $this->assertCount(count($expectedProducts), $category['products']['items']);
+ $this->assertResponseFields($category['products']['items'], $expectedProducts);
+ }
+
+ /**
+ * Check category child categories
+ *
+ * @param array $category
+ * @param array $expectedChildren
+ */
+ private function assertCategoryChildren(array $category, array $expectedChildren)
+ {
+ $this->assertArrayHasKey('children', $category);
+ $this->assertCount(count($expectedChildren), $category['children']);
+ foreach ($expectedChildren as $i => $expectedChild) {
+ $this->assertResponseFields($category['children'][$i], $expectedChild);
+ }
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogUrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogUrlRewrite/UrlResolverTest.php
index b15cfe3a5b91..29696e29908f 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogUrlRewrite/UrlResolverTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogUrlRewrite/UrlResolverTest.php
@@ -65,33 +65,25 @@ public function testProductUrlResolver()
'store_id' => $storeId
]
);
- $targetPath = $actualUrls->getTargetPath();
+ $relativePath = $actualUrls->getRequestPath();
$expectedType = $actualUrls->getEntityType();
+ $redirectCode = $actualUrls->getRedirectType();
- $query
- = <<graphQlQuery($query);
- $this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
- $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $urlPath,
+ $relativePath,
+ $expectedType,
+ $redirectCode
+ );
}
/**
- * Tests the use case where relative_url is provided as resolver input in the Query
+ * Test the use case where non seo friendly is provided as resolver input in the Query
*
* @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
*/
- public function testProductUrlWithCanonicalUrlInput()
+ public function testProductUrlWithNonSeoFriendlyUrlInput()
{
$productSku = 'p002';
/** @var ProductRepositoryInterface $productRepository */
@@ -122,25 +114,127 @@ public function testProductUrlWithCanonicalUrlInput()
'store_id' => $storeId
]
);
- $targetPath = $actualUrls->getTargetPath();
+ // even of non seo friendly path requested, the seo friendly path should be prefered
+ $relativePath = $actualUrls->getRequestPath();
$expectedType = $actualUrls->getEntityType();
- $canonicalPath = $actualUrls->getTargetPath();
+ $nonSeoFriendlyPath = $actualUrls->getTargetPath();
+ $redirectCode = $actualUrls->getRedirectType();
+
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $nonSeoFriendlyPath,
+ $relativePath,
+ $expectedType,
+ $redirectCode
+ );
+ }
+
+ /**
+ * Test the use case where non seo friendly is provided as resolver input in the Query
+ *
+ * @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
+ */
+ public function testRedirectsAndCustomInput()
+ {
+ $productSku = 'p002';
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
+ $product = $productRepository->get($productSku, false, null, true);
+
+ // generate permanent redirects
+ $renamedKey = 'p002-ren';
+ $product->setUrlKey($renamedKey)->setData('save_rewrites_history', true)->save();
+
+ $storeId = $product->getStoreId();
+
$query
= <<graphQlQuery($query);
- $this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
- $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+ $urlPath = $response['products']['items'][0]['url_key'] . $response['products']['items'][0]['url_suffix'];
+ $suffix = $response['products']['items'][0]['url_suffix'];
+
+ /** @var UrlFinderInterface $urlFinder */
+ $urlFinder = $this->objectManager->get(UrlFinderInterface::class);
+ $actualUrls = $urlFinder->findOneByData(
+ [
+ 'request_path' => $urlPath,
+ 'store_id' => $storeId
+ ]
+ );
+ // querying the end redirect gives the same record
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $renamedKey . $suffix,
+ $actualUrls->getRequestPath(),
+ $actualUrls->getEntityType(),
+ 0
+ );
+
+ // querying a url that's a redirect the active redirected final url
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $productSku . $suffix,
+ $actualUrls->getRequestPath(),
+ $actualUrls->getEntityType(),
+ 301
+ );
+
+ // create custom url that doesn't redirect
+ /** @var UrlRewrite $urlRewriteModel */
+ $urlRewriteModel = $this->objectManager->create(UrlRewrite::class);
+
+ $customUrl = 'custom-path';
+ $urlRewriteArray = [
+ 'entity_type' => 'custom',
+ 'entity_id' => '0',
+ 'request_path' => $customUrl,
+ 'target_path' => 'p002.html',
+ 'redirect_type' => '0',
+ 'store_id' => '1',
+ 'description' => '',
+ 'is_autogenerated' => '0',
+ 'metadata' => null,
+ ];
+ foreach ($urlRewriteArray as $key => $value) {
+ $urlRewriteModel->setData($key, $value);
+ }
+ $urlRewriteModel->save();
+
+ // querying a custom url that should return the target entity but relative should be the custom url
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $customUrl,
+ $customUrl,
+ $actualUrls->getEntityType(),
+ 0
+ );
+
+ // change custom url that does redirect
+ $urlRewriteModel->setRedirectType('301');
+ $urlRewriteModel->setId($urlRewriteModel->getId());
+ $urlRewriteModel->save();
+
+ ObjectManager::getInstance()->get(\Magento\TestFramework\Helper\CacheCleaner::class)->cleanAll();
+
+ //modifying query by adding spaces to avoid getting cached values.
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $customUrl,
+ $actualUrls->getRequestPath(),
+ strtoupper($actualUrls->getEntityType()),
+ 301
+ );
+ $urlRewriteModel->delete();
}
/**
@@ -166,7 +260,7 @@ public function testCategoryUrlResolver()
]
);
$categoryId = $actualUrls->getEntityId();
- $targetPath = $actualUrls->getTargetPath();
+ $relativePath = $actualUrls->getRequestPath();
$expectedType = $actualUrls->getEntityType();
$query
@@ -181,26 +275,17 @@ public function testCategoryUrlResolver()
$response = $this->graphQlQuery($query);
$urlPath = $response['category']['url_key'] . $response['category']['url_suffix'];
- $query
- = <<graphQlQuery($query);
- $this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals($categoryId, $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
- $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+ $this->queryUrlAndAssertResponse(
+ (int) $categoryId,
+ $urlPath,
+ $relativePath,
+ $expectedType,
+ 0
+ );
}
/**
- * Tests the use case where the url_key of the existing product is changed
+ * Test the use case where the url_key of the existing product is changed
*
* @magentoApiDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php
*/
@@ -238,24 +323,16 @@ public function testProductUrlRewriteResolver()
'store_id' => $storeId
]
);
- $targetPath = $actualUrls->getTargetPath();
+ $relativePath = $actualUrls->getRequestPath();
$expectedType = $actualUrls->getEntityType();
- $query
- = <<graphQlQuery($query);
- $this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals($product->getEntityId(), $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
- $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+
+ $this->queryUrlAndAssertResponse(
+ (int) $product->getEntityId(),
+ $urlPath,
+ $relativePath,
+ $expectedType,
+ 0
+ );
}
/**
@@ -288,6 +365,7 @@ public function testInvalidUrlResolverInput()
id
relative_url
type
+ redirectCode
}
}
QUERY;
@@ -319,7 +397,7 @@ public function testCategoryUrlWithLeadingSlash()
]
);
$categoryId = $actualUrls->getEntityId();
- $targetPath = $actualUrls->getTargetPath();
+ $relativePath = $actualUrls->getRequestPath();
$expectedType = $actualUrls->getEntityType();
$query
@@ -333,22 +411,14 @@ public function testCategoryUrlWithLeadingSlash()
QUERY;
$response = $this->graphQlQuery($query);
$urlPath = $response['category']['url_key'] . $response['category']['url_suffix'];
-
- $query = <<graphQlQuery($query);
- $this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals($categoryId, $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
- $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+ $urlPathWithLeadingSlash = "/{$urlPath}";
+ $this->queryUrlAndAssertResponse(
+ (int) $categoryId,
+ $urlPathWithLeadingSlash,
+ $relativePath,
+ $expectedType,
+ 0
+ );
}
/**
@@ -371,7 +441,7 @@ public function testGetNonExistentUrlRewrite()
'store_id' => 1
]
);
- $targetPath = $actualUrls->getTargetPath();
+ $relativePath = $actualUrls->getRequestPath();
$query = <<graphQlQuery($query);
$this->assertArrayHasKey('urlResolver', $response);
$this->assertEquals('PRODUCT', $response['urlResolver']['type']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
+ $this->assertEquals($relativePath, $response['urlResolver']['relative_url']);
+ $this->assertEquals(0, $response['urlResolver']['redirectCode']);
+ }
+
+ /**
+ * Assert response from GraphQl
+ *
+ * @param string $productId
+ * @param string $urlKey
+ * @param string $relativePath
+ * @param string $expectedType
+ * @param int $redirectCode
+ */
+ private function queryUrlAndAssertResponse(
+ int $productId,
+ string $urlKey,
+ string $relativePath,
+ string $expectedType,
+ int $redirectCode
+ ): void {
+ $query
+ = <<graphQlQuery($query);
+ $this->assertArrayHasKey('urlResolver', $response);
+ $this->assertEquals($productId, $response['urlResolver']['id']);
+ $this->assertEquals($relativePath, $response['urlResolver']['relative_url']);
+ $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']);
+ $this->assertEquals($redirectCode, $response['urlResolver']['redirectCode']);
}
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CmsUrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CmsUrlRewrite/UrlResolverTest.php
index ece421925a31..072c6bc38de7 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CmsUrlRewrite/UrlResolverTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CmsUrlRewrite/UrlResolverTest.php
@@ -53,13 +53,34 @@ public function testCMSPageUrlResolver()
id
relative_url
type
+ redirectCode
}
}
QUERY;
$response = $this->graphQlQuery($query);
$this->assertEquals($cmsPageId, $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
+ $this->assertEquals($requestPath, $response['urlResolver']['relative_url']);
$this->assertEquals(strtoupper(str_replace('-', '_', $expectedEntityType)), $response['urlResolver']['type']);
+ $this->assertEquals(0, $response['urlResolver']['redirectCode']);
+
+ // querying by non seo friendly url path should return seo friendly relative url
+ $query
+ = <<graphQlQuery($query);
+ $this->assertEquals($cmsPageId, $response['urlResolver']['id']);
+ $this->assertEquals($requestPath, $response['urlResolver']['relative_url']);
+ $this->assertEquals(strtoupper(str_replace('-', '_', $expectedEntityType)), $response['urlResolver']['type']);
+ $this->assertEquals(0, $response['urlResolver']['redirectCode']);
}
/**
@@ -77,10 +98,6 @@ public function testResolveSlash()
$page = $this->objectManager->get(\Magento\Cms\Model\Page::class);
$page->load($homePageIdentifier);
$homePageId = $page->getId();
- /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $urlPathGenerator */
- $urlPathGenerator = $this->objectManager->get(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator::class);
- /** @param \Magento\Cms\Api\Data\PageInterface $page */
- $targetPath = $urlPathGenerator->getCanonicalUrlPath($page);
$query
= <<graphQlQuery($query);
$this->assertArrayHasKey('urlResolver', $response);
$this->assertEquals($homePageId, $response['urlResolver']['id']);
- $this->assertEquals($targetPath, $response['urlResolver']['relative_url']);
+ $this->assertEquals($homePageIdentifier, $response['urlResolver']['relative_url']);
$this->assertEquals('CMS_PAGE', $response['urlResolver']['type']);
+ $this->assertEquals(0, $response['urlResolver']['redirectCode']);
}
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php
index 048ccb70af0d..1dc5a813de2b 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php
@@ -38,6 +38,12 @@ class ProductViewTest extends GraphQlAbstract
/** @var \Magento\Tax\Model\Calculation\Rule[] */
private $fixtureTaxRules;
+ /** @var string */
+ private $defaultRegionSystemSetting;
+
+ /** @var string */
+ private $defaultPriceDisplayType;
+
/**
* @var StoreManagerInterface
*/
@@ -52,19 +58,26 @@ protected function setUp()
/** @var \Magento\Config\Model\ResourceModel\Config $config */
$config = $this->objectManager->get(\Magento\Config\Model\ResourceModel\Config::class);
+ /** @var ScopeConfigInterface $scopeConfig */
+ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+
+ $this->defaultRegionSystemSetting = $scopeConfig->getValue(
+ Config::CONFIG_XML_PATH_DEFAULT_REGION
+ );
+
+ $this->defaultPriceDisplayType = $scopeConfig->getValue(
+ Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE
+ );
+
//default state tax calculation AL
$config->saveConfig(
Config::CONFIG_XML_PATH_DEFAULT_REGION,
- 1,
- ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
1
);
$config->saveConfig(
Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
- 3,
- ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
- 1
+ 3
);
$this->getFixtureTaxRates();
$this->getFixtureTaxRules();
@@ -72,6 +85,9 @@ protected function setUp()
/** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */
$config = $this->objectManager->get(\Magento\Framework\App\Config\ReinitableConfigInterface::class);
$config->reinit();
+ /** @var ScopeConfigInterface $scopeConfig */
+ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+ $scopeConfig->clean();
}
public function tearDown()
@@ -82,16 +98,12 @@ public function tearDown()
//default state tax calculation AL
$config->saveConfig(
Config::CONFIG_XML_PATH_DEFAULT_REGION,
- null,
- ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
- 1
+ $this->defaultRegionSystemSetting
);
$config->saveConfig(
Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
- 1,
- ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
- 1
+ $this->defaultPriceDisplayType
);
$taxRules = $this->getFixtureTaxRules();
if (count($taxRules)) {
@@ -107,6 +119,10 @@ public function tearDown()
/** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */
$config = $this->objectManager->get(\Magento\Framework\App\Config\ReinitableConfigInterface::class);
$config->reinit();
+
+ /** @var ScopeConfigInterface $scopeConfig */
+ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+ $scopeConfig->clean();
}
/**
@@ -253,6 +269,22 @@ private function getFixtureTaxRules()
*/
private function assertBaseFields($product, $actualResponse)
{
+ $pricesTypes = [
+ 'minimalPrice',
+ 'regularPrice',
+ 'maximalPrice',
+ ];
+ foreach ($pricesTypes as $priceType) {
+ if (isset($actualResponse['price'][$priceType]['amount']['value'])) {
+ $actualResponse['price'][$priceType]['amount']['value'] =
+ round($actualResponse['price'][$priceType]['amount']['value'], 4);
+ }
+
+ if (isset($actualResponse['price'][$priceType]['adjustments'][0]['amount']['value'])) {
+ $actualResponse['price'][$priceType]['adjustments'][0]['amount']['value'] =
+ round($actualResponse['price'][$priceType]['adjustments'][0]['amount']['value'], 4);
+ }
+ }
// product_object_field_name, expected_value
$assertionMap = [
['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()],
@@ -271,7 +303,7 @@ private function assertBaseFields($product, $actualResponse)
[
'amount' =>
[
- 'value' => 0.286501,
+ 'value' => 0.2865,
'currency' => 'USD',
],
'code' => 'TAX',
@@ -289,7 +321,7 @@ private function assertBaseFields($product, $actualResponse)
[
'amount' =>
[
- 'value' => 0.750001,
+ 'value' => 0.7500,
'currency' => 'USD',
],
'code' => 'TAX',
@@ -307,7 +339,7 @@ private function assertBaseFields($product, $actualResponse)
[
'amount' =>
[
- 'value' => 0.286501,
+ 'value' => 0.2865,
'currency' => 'USD',
],
'code' => 'TAX',
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
index bd20741fb741..5e6415f82b25 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
@@ -39,6 +39,7 @@ public function testNonExistentEntityUrlRewrite()
id
relative_url
type
+ redirectCode
}
}
QUERY;
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/ProductPriceWithFPTTest.php
similarity index 86%
rename from dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php
rename to dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/ProductPriceWithFPTTest.php
index 3f568c2635d0..385e3419bbf6 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/ProductPriceWithFPTTest.php
@@ -5,7 +5,7 @@
*/
declare(strict_types=1);
-namespace Magento\GraphQl\Catalog;
+namespace Magento\GraphQl\Weee;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
@@ -27,12 +27,64 @@ class ProductPriceWithFPTTest extends GraphQlAbstract
/** @var ObjectManager $objectManager */
private $objectManager;
+ /** @var string[] $objectManager */
+ private $initialConfig;
+
+ /** @var ScopeConfigInterface */
+ private $scopeConfig;
+
/**
* @inheritdoc
*/
- protected function setUp() :void
+ protected function setUp(): void
{
$this->objectManager = Bootstrap::getObjectManager();
+
+ /** @var ScopeConfigInterface $scopeConfig */
+ $this->scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+
+ $currentSettingsArray = [
+ 'tax/display/type',
+ 'tax/weee/enable',
+ 'tax/weee/display',
+ 'tax/defaults/region',
+ 'tax/weee/apply_vat',
+ 'tax/calculation/price_includes_tax'
+ ];
+
+ foreach ($currentSettingsArray as $configPath) {
+ $this->initialConfig[$configPath] = $this->scopeConfig->getValue(
+ $configPath
+ );
+ }
+ /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */
+ $config = $this->objectManager->get(\Magento\Framework\App\Config\ReinitableConfigInterface::class);
+ $config->reinit();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function tearDown(): void
+ {
+ $this->writeConfig($this->initialConfig);
+ }
+
+ /**
+ * Write configuration for weee
+ *
+ * @param array $weeTaxSettings
+ * @return void
+ */
+ private function writeConfig(array $weeTaxSettings): void
+ {
+ /** @var WriterInterface $configWriter */
+ $configWriter = $this->objectManager->get(WriterInterface::class);
+
+ foreach ($weeTaxSettings as $path => $value) {
+ $configWriter->save($path, $value);
+ }
+ $this->scopeConfig->clean();
}
/**
@@ -49,16 +101,7 @@ protected function setUp() :void
*/
public function testCatalogPriceExcludeTaxAndIncludeFPTOnly(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
$skus = ['simple-with-ftp'];
$query = $this->getProductQuery($skus);
@@ -115,16 +158,7 @@ public function catalogPriceExcludeTaxAndIncludeFPTOnlySettingsProvider()
*/
public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
$skus = ['simple-with-ftp'];
$query = $this->getProductQuery($skus);
@@ -181,16 +215,7 @@ public function catalogPriceExcludeTaxAndIncludeFPTWithDescriptionSettingsProvid
*/
public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
/** @var TaxClassCollectionFactory $taxClassCollectionFactory */
$taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class);
@@ -257,16 +282,7 @@ public function catalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnlyS
*/
public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
/** @var TaxClassCollectionFactory $taxClassCollectionFactory */
$taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class);
@@ -333,16 +349,7 @@ public function catalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescriptio
*/
public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
$skus = ['simple-with-ftp'];
$query = $this->getProductQuery($skus);
@@ -400,16 +407,7 @@ public function catalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescriptio
*/
public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
$skus = ['simple-with-ftp'];
$query = $this->getProductQuery($skus);
@@ -469,16 +467,8 @@ public function catalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnlySettingsPr
public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT(
array $weeTaxSettings
) {
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
+ $this->writeConfig($weeTaxSettings);
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
/** @var TaxClassCollectionFactory $taxClassCollectionFactory */
$taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class);
$taxClassCollection = $taxClassCollectionFactory->create();
@@ -524,7 +514,7 @@ public function catalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAp
return [
[
'weeTaxSettings' => [
- 'tax/calculation/price_includes_tax' > '1',
+ 'tax/calculation/price_includes_tax' => '1',
'tax/display/type' => '2',
'tax/weee/enable' => '1',
'tax/weee/display' => '0',
@@ -552,16 +542,7 @@ public function catalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAp
*/
public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs(array $weeTaxSettings)
{
- /** @var WriterInterface $configWriter */
- $configWriter = $this->objectManager->get(WriterInterface::class);
-
- foreach ($weeTaxSettings as $path => $value) {
- $configWriter->save($path, $value);
- }
-
- /** @var ScopeConfigInterface $scopeConfig */
- $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
- $scopeConfig->clean();
+ $this->writeConfig($weeTaxSettings);
/** @var TaxClassCollectionFactory $taxClassCollectionFactory */
$taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class);
@@ -631,6 +612,65 @@ public function catalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTsSetti
];
}
+ /**
+ * Test FPT disabled feature
+ *
+ * FPT enabled : FALSE
+ *
+ * @param array $weeTaxSettings
+ * @return void
+ *
+ * @dataProvider catalogPriceDisabledFPTSettingsProvider
+ * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php
+ */
+ public function testCatalogPriceDisableFPT(array $weeTaxSettings)
+ {
+ $this->writeConfig($weeTaxSettings);
+
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
+ /** @var Product $product1 */
+ $product1 = $productRepository->get('simple-with-ftp');
+ $product1->setFixedProductAttribute(
+ [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10, 'delete' => '']]
+ );
+ $productRepository->save($product1);
+
+ $skus = ['simple-with-ftp'];
+ $query = $this->getProductQuery($skus);
+ $result = $this->graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+ $this->assertNotEmpty($result['products']['items']);
+ $product = $result['products']['items'][0];
+ $this->assertEquals(100, round($product['price_range']['minimum_price']['regular_price']['value'], 2));
+ $this->assertCount(
+ 0,
+ $product['price_range']['minimum_price']['fixed_product_taxes'],
+ 'Fixed product tax count is incorrect'
+ );
+ $this->assertResponseFields(
+ $product['price_range']['minimum_price']['fixed_product_taxes'],
+ []
+ );
+ }
+
+ /**
+ * CatalogPriceDisableFPT settings data provider
+ *
+ * @return array
+ */
+ public function catalogPriceDisabledFPTSettingsProvider()
+ {
+ return [
+ [
+ 'weeTaxSettings' => [
+ 'tax/weee/enable' => '0',
+ 'tax/weee/display' => '1',
+ ],
+ ],
+ ];
+ }
+
/**
* Get GraphQl query to fetch products by sku
*
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/StoreConfigFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/StoreConfigFPTTest.php
new file mode 100644
index 000000000000..451ea78ee308
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Weee/StoreConfigFPTTest.php
@@ -0,0 +1,204 @@
+objectManager = Bootstrap::getObjectManager();
+ }
+
+ /**
+ * FPT All Display settings
+ *
+ * @param array $weeTaxSettings
+ * @param string $displayValue
+ * @return void
+ *
+ * @dataProvider sameFPTDisplaySettingsProvider
+ */
+ public function testSameFPTDisplaySettings(array $weeTaxSettings, $displayValue)
+ {
+ /** @var WriterInterface $configWriter */
+ $configWriter = $this->objectManager->get(WriterInterface::class);
+
+ foreach ($weeTaxSettings as $path => $value) {
+ $configWriter->save($path, $value);
+ }
+
+ /** @var ScopeConfigInterface $scopeConfig */
+ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+ $scopeConfig->clean();
+
+ $query = $this->getStoreConfigQuery();
+ $result = $this->graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+
+ $this->assertNotEmpty($result['storeConfig']['product_fixed_product_tax_display_setting']);
+ $this->assertNotEmpty($result['storeConfig']['category_fixed_product_tax_display_setting']);
+ $this->assertNotEmpty($result['storeConfig']['sales_fixed_product_tax_display_setting']);
+
+ $this->assertEquals($displayValue, $result['storeConfig']['product_fixed_product_tax_display_setting']);
+ $this->assertEquals($displayValue, $result['storeConfig']['category_fixed_product_tax_display_setting']);
+ $this->assertEquals($displayValue, $result['storeConfig']['sales_fixed_product_tax_display_setting']);
+ }
+
+ /**
+ * SameFPTDisplaySettings settings data provider
+ *
+ * @return array
+ */
+ public function sameFPTDisplaySettingsProvider()
+ {
+ return [
+ [
+ 'weeTaxSettingsDisplayIncludedOnly' => [
+ 'tax/weee/enable' => '1',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_INCL,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_INCL,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_INCL,
+ ],
+ 'displayValue' => 'INCLUDE_FPT_WITHOUT_DETAILS',
+ ],
+ [
+ 'weeTaxSettingsDisplayIncludedAndDescription' => [
+ 'tax/weee/enable' => '1',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_INCL_DESCR,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_INCL_DESCR,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_INCL_DESCR,
+ ],
+ 'displayValue' => 'INCLUDE_FPT_WITH_DETAILS',
+ ],
+ [
+ 'weeTaxSettingsDisplayIncludedAndExcludedAndDescription' => [
+ 'tax/weee/enable' => '1',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL,
+ ],
+ 'displayValue' => 'EXCLUDE_FPT_AND_INCLUDE_WITH_DETAILS',
+ ],
+ [
+ 'weeTaxSettingsDisplayExcluded' => [
+ 'tax/weee/enable' => '1',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_EXCL,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_EXCL,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_EXCL,
+ ],
+ 'displayValue' => 'EXCLUDE_FPT_WITHOUT_DETAILS',
+ ],
+ [
+ 'weeTaxSettingsDisplayExcluded' => [
+ 'tax/weee/enable' => '0',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_EXCL,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_EXCL,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_EXCL,
+ ],
+ 'displayValue' => 'FPT_DISABLED',
+ ],
+ ];
+ }
+
+ /**
+ * FPT Display setting shuffled
+ *
+ * @param array $weeTaxSettings
+ * @return void
+ *
+ * @dataProvider differentFPTDisplaySettingsProvider
+ */
+ public function testDifferentFPTDisplaySettings(array $weeTaxSettings)
+ {
+ /** @var WriterInterface $configWriter */
+ $configWriter = $this->objectManager->get(WriterInterface::class);
+
+ foreach ($weeTaxSettings as $path => $value) {
+ $configWriter->save($path, $value);
+ }
+
+ /** @var ScopeConfigInterface $scopeConfig */
+ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class);
+ $scopeConfig->clean();
+
+ $query = $this->getStoreConfigQuery();
+ $result = $this->graphQlQuery($query);
+ $this->assertArrayNotHasKey('errors', $result);
+
+ $this->assertNotEmpty($result['storeConfig']['product_fixed_product_tax_display_setting']);
+ $this->assertNotEmpty($result['storeConfig']['category_fixed_product_tax_display_setting']);
+ $this->assertNotEmpty($result['storeConfig']['sales_fixed_product_tax_display_setting']);
+
+ $this->assertEquals(
+ 'INCLUDE_FPT_WITHOUT_DETAILS',
+ $result['storeConfig']['product_fixed_product_tax_display_setting']
+ );
+ $this->assertEquals(
+ 'INCLUDE_FPT_WITH_DETAILS',
+ $result['storeConfig']['category_fixed_product_tax_display_setting']
+ );
+ $this->assertEquals(
+ 'EXCLUDE_FPT_AND_INCLUDE_WITH_DETAILS',
+ $result['storeConfig']['sales_fixed_product_tax_display_setting']
+ );
+ }
+
+ /**
+ * DifferentFPTDisplaySettings settings data provider
+ *
+ * @return array
+ */
+ public function differentFPTDisplaySettingsProvider()
+ {
+ return [
+ [
+ 'weeTaxSettingsDisplay' => [
+ 'tax/weee/enable' => '1',
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_VIEW => WeeeDisplayConfig::DISPLAY_INCL,
+ Config::XML_PATH_FPT_DISPLAY_PRODUCT_LIST => WeeeDisplayConfig::DISPLAY_INCL_DESCR,
+ Config::XML_PATH_FPT_DISPLAY_SALES => WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL,
+ ]
+ ],
+ ];
+ }
+
+ /**
+ * Get GraphQl query to fetch storeConfig and FPT serttings
+ *
+ * @return string
+ */
+ private function getStoreConfigQuery(): string
+ {
+ return <<objectManager = Bootstrap::getObjectManager();
+ $this->filterBuilder = $this->objectManager->create(FilterBuilder::class);
+ $this->sortOrderBuilder = $this->objectManager->create(SortOrderBuilder::class);
+ $this->searchCriteriaBuilder = $this->objectManager->create(SearchCriteriaBuilder::class);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function tearDown()
+ {
+ try {
+ /** @var CartRepositoryInterface $quoteRepository */
+ $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
+ $cart = $this->getCart('multishipping_quote_id');
+ $quoteRepository->delete($cart);
+ } catch (\InvalidArgumentException $e) {
+ // Do nothing if cart fixture was not used
+ }
+ parent::tearDown();
+ }
+
+ /**
+ * Tests that multishipping quote contains all addresses in shipping assignments.
+ *
+ * @magentoApiDataFixture Magento/Multishipping/Fixtures/quote_with_split_items.php
+ */
+ public function testGetMultishippingCart()
+ {
+ $cart = $this->getCart('multishipping_quote_id');
+ $cartId = $cart->getId();
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => '/V1/carts/' . $cartId,
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ ],
+ 'soap' => [
+ 'service' => 'quoteCartRepositoryV1',
+ 'serviceVersion' => 'V1',
+ 'operation' => 'quoteCartRepositoryV1Get',
+ ],
+ ];
+
+ $requestData = ['cartId' => $cartId];
+ $cartData = $this->_webApiCall($serviceInfo, $requestData);
+
+ $shippingAssignments = $cart->getExtensionAttributes()->getShippingAssignments();
+ foreach ($shippingAssignments as $key => $shippingAssignment) {
+ $address = $shippingAssignment->getShipping()->getAddress();
+ $cartItem = $shippingAssignment->getItems()[0];
+ $this->assertEquals(
+ $address->getId(),
+ $cartData['extension_attributes']['shipping_assignments'][$key]['shipping']['address']['id']
+ );
+ $this->assertEquals(
+ $cartItem->getSku(),
+ $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['sku']
+ );
+ $this->assertEquals(
+ $cartItem->getQty(),
+ $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['qty']
+ );
+ }
+ }
+
+ /**
+ * Retrieve quote by given reserved order ID
+ *
+ * @param string $reservedOrderId
+ * @return Quote
+ * @throws \InvalidArgumentException
+ */
+ private function getCart(string $reservedOrderId): Quote
+ {
+ /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
+ $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
+ $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId)
+ ->create();
+
+ /** @var CartRepositoryInterface $quoteRepository */
+ $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
+ $items = $quoteRepository->getList($searchCriteria)->getItems();
+
+ if (empty($items)) {
+ throw new \InvalidArgumentException('There is no quote with provided reserved order ID.');
+ }
+
+ return array_pop($items);
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
index 8cb82f5c8f20..5a894758dc9e 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
@@ -42,6 +42,9 @@ class CartRepositoryTest extends WebapiAbstract
*/
private $filterBuilder;
+ /**
+ * @inheritdoc
+ */
protected function setUp()
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
@@ -59,8 +62,10 @@ protected function setUp()
protected function tearDown()
{
try {
+ /** @var CartRepositoryInterface $quoteRepository */
+ $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
$cart = $this->getCart('test01');
- $cart->delete();
+ $quoteRepository->delete($cart);
} catch (\InvalidArgumentException $e) {
// Do nothing if cart fixture was not used
}
@@ -74,18 +79,27 @@ protected function tearDown()
* @return \Magento\Quote\Model\Quote
* @throws \InvalidArgumentException
*/
- protected function getCart($reservedOrderId)
+ private function getCart($reservedOrderId)
{
- /** @var $cart \Magento\Quote\Model\Quote */
- $cart = $this->objectManager->get(\Magento\Quote\Model\Quote::class);
- $cart->load($reservedOrderId, 'reserved_order_id');
- if (!$cart->getId()) {
+ /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
+ $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
+ $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId)
+ ->create();
+
+ /** @var CartRepositoryInterface $quoteRepository */
+ $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
+ $items = $quoteRepository->getList($searchCriteria)->getItems();
+
+ if (empty($items)) {
throw new \InvalidArgumentException('There is no quote with provided reserved order ID.');
}
- return $cart;
+
+ return array_pop($items);
}
/**
+ * Tests successfull get cart web-api call.
+ *
* @magentoApiDataFixture Magento/Sales/_files/quote.php
*/
public function testGetCart()
@@ -130,6 +144,8 @@ public function testGetCart()
}
/**
+ * Tests exception when cartId is not provided.
+ *
* @expectedException \Exception
* @expectedExceptionMessage No such entity with
*/
@@ -154,6 +170,8 @@ public function testGetCartThrowsExceptionIfThereIsNoCartWithProvidedId()
}
/**
+ * Tests carts search.
+ *
* @magentoApiDataFixture Magento/Sales/_files/quote.php
*/
public function testGetList()
@@ -184,6 +202,7 @@ public function testGetList()
$this->searchCriteriaBuilder->addFilters([$grandTotalFilter, $subtotalFilter]);
$this->searchCriteriaBuilder->addFilters([$minCreatedAtFilter]);
$this->searchCriteriaBuilder->addFilters([$maxCreatedAtFilter]);
+ $this->searchCriteriaBuilder->addFilter('reserved_order_id', 'test01');
/** @var SortOrder $sortOrder */
$sortOrder = $this->sortOrderBuilder->setField('subtotal')->setDirection(SortOrder::SORT_ASC)->create();
$this->searchCriteriaBuilder->setSortOrders([$sortOrder]);
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php
index 9f697a1be633..cd9512c22789 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php
@@ -6,6 +6,9 @@
namespace Magento\TestFramework\Mail\Template;
+/**
+ * Class TransportBuilderMock
+ */
class TransportBuilderMock extends \Magento\Framework\Mail\Template\TransportBuilder
{
/**
@@ -38,11 +41,12 @@ public function getSentMessage()
* Return transport mock.
*
* @return \Magento\TestFramework\Mail\TransportInterfaceMock
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function getTransport()
{
$this->prepareMessage();
$this->reset();
- return new \Magento\TestFramework\Mail\TransportInterfaceMock();
+ return new \Magento\TestFramework\Mail\TransportInterfaceMock($this->message);
}
}
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php
index 8f967b501a59..5bf98b76e7d5 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php
@@ -6,8 +6,28 @@
namespace Magento\TestFramework\Mail;
+use Magento\Framework\Mail\EmailMessageInterface;
+
+/**
+ * Class TransportInterfaceMock
+ */
class TransportInterfaceMock implements \Magento\Framework\Mail\TransportInterface
{
+ /**
+ * @var null|EmailMessageInterface
+ */
+ private $message;
+
+ /**
+ * TransportInterfaceMock constructor.
+ *
+ * @param null|EmailMessageInterface $message
+ */
+ public function __construct($message = null)
+ {
+ $this->message = $message;
+ }
+
/**
* Mock of send a mail using transport
*
@@ -15,16 +35,17 @@ class TransportInterfaceMock implements \Magento\Framework\Mail\TransportInterfa
*/
public function sendMessage()
{
+ //phpcs:ignore Squiz.PHP.NonExecutableCode.ReturnNotRequired
return;
}
/**
* Get message
*
- * @return string
+ * @return null|EmailMessageInterface
*/
public function getMessage()
{
- return '';
+ return $this->message;
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductHydratorTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductHydratorTest.php
new file mode 100644
index 000000000000..948170218332
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductHydratorTest.php
@@ -0,0 +1,75 @@
+objectManager = Bootstrap::getObjectManager();
+ $this->hydratorPool = $this->objectManager->create(HydratorPool::class);
+ }
+
+ /**
+ * Test that Hydrator correctly populates entity with data
+ */
+ public function testProductHydrator()
+ {
+ $addAttributes = [
+ 'sku' => 'product_updated',
+ 'name' => 'Product (Updated)',
+ 'type_id' => 'simple',
+ 'status' => 1,
+ ];
+
+ /** @var Product $product */
+ $product = $this->objectManager->create(Product::class);
+ $product->setId(42)
+ ->setSku('product')
+ ->setName('Product')
+ ->setPrice(10)
+ ->setQty(123);
+ $product->lockAttribute('sku');
+ $product->lockAttribute('type_id');
+ $product->lockAttribute('price');
+
+ /** @var HydratorInterface $hydrator */
+ $hydrator = $this->hydratorPool->getHydrator(ProductInterface::class);
+ $hydrator->hydrate($product, $addAttributes);
+
+ $expected = [
+ 'entity_id' => 42,
+ 'sku' => 'product_updated',
+ 'name' => 'Product (Updated)',
+ 'type_id' => 'simple',
+ 'status' => 1,
+ 'price' => 10,
+ 'qty' => 123,
+ ];
+ $this->assertEquals($expected, $product->getData());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php
index a5ab96193246..25bb55ffbc32 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php
@@ -64,6 +64,7 @@
->setIsActive(true)
->setIsAnchor(true)
->setPosition(1)
+ ->setDescription('Category 1.1 description.')
->save();
$category = $objectManager->create(\Magento\Catalog\Model\Category::class);
@@ -79,6 +80,7 @@
->setPosition(1)
->setCustomUseParentSettings(0)
->setCustomDesign('Magento/blank')
+ ->setDescription('This is the description for Category 1.1.1')
->save();
$category = $objectManager->create(\Magento\Catalog\Model\Category::class);
diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php b/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php
index bbbcc3133d4b..6d5f760d7894 100644
--- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php
+++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php
@@ -10,9 +10,9 @@
$template->setOptions(['area' => 'test area', 'store' => 1]);
$template->setData(
[
- 'template_text' =>
- file_get_contents(__DIR__ . '/template_fixture.html'),
- 'template_code' => \Magento\Theme\Model\Config\ValidatorTest::TEMPLATE_CODE
+ 'template_text' => file_get_contents(__DIR__ . '/template_fixture.html'),
+ 'template_code' => \Magento\Theme\Model\Config\ValidatorTest::TEMPLATE_CODE,
+ 'template_type' => \Magento\Email\Model\Template::TYPE_TEXT
]
);
$template->save();
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php
new file mode 100644
index 000000000000..03bdc9a36552
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php
@@ -0,0 +1,100 @@
+di = Bootstrap::getObjectManager();
+ $this->builder = $this->di->get(TransportBuilder::class);
+ $this->template = $this->di->get(Template::class);
+ }
+
+ /**
+ * @magentoDataFixture Magento/Email/Model/_files/email_template.php
+ * @magentoDbIsolation enabled
+ *
+ * @param string|array $email
+ * @dataProvider emailDataProvider
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function testAddToEmail($email)
+ {
+ $templateId = $this->template->load('email_exception_fixture', 'template_code')->getId();
+
+ $this->builder->setTemplateModel(BackendTemplate::class);
+
+ $vars = ['reason' => 'Reason', 'customer' => 'Customer'];
+ $options = ['area' => 'frontend', 'store' => 1];
+ $this->builder->setTemplateIdentifier($templateId)->setTemplateVars($vars)->setTemplateOptions($options);
+
+ $this->builder->addTo($email);
+
+ /** @var EmailMessage $emailMessage */
+ $emailMessage = $this->builder->getTransport();
+
+ $addresses = $emailMessage->getMessage()->getTo();
+
+ $emails = [];
+ /** @var Address $toAddress */
+ foreach ($addresses as $address) {
+ $emails[] = $address->getEmail();
+ }
+
+ if (is_string($email)) {
+ $this->assertCount(1, $emails);
+ $this->assertEquals($email, $emails[0]);
+ } else {
+ $this->assertEquals($email, $emails);
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function emailDataProvider(): array
+ {
+ return [
+ [
+ 'billy.everything@someserver.com',
+ ],
+ [
+ [
+ 'billy.everything@someserver.com',
+ 'john.doe@someserver.com',
+ ]
+ ]
+ ];
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php
new file mode 100644
index 000000000000..a8e9059a84eb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php
@@ -0,0 +1,145 @@
+dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
+ $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC'];
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ }
+
+ /**
+ * Test request is served from cache
+ *
+ * @magentoDataFixture Magento/Catalog/_files/category_product.php
+ */
+ public function testSecondRequestIsServedFromCache()
+ {
+ $categoryId ='333';
+ $query
+ = <<dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+
+ $cacheResponse = $this->dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('HIT', $cacheResponse->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $cacheResponse->getHeader('X-Magento-Tags')->getFieldValue());
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ }
+
+ /**
+ * Test cache tags are generated
+ *
+ * @magentoDataFixture Magento/Catalog/_files/category_tree.php
+ */
+ public function testRequestCacheTagsForCategoryListOnMultipleIds(): void
+ {
+ $categoryId1 ='400';
+ $categoryId2 = '401';
+ $query
+ = <<dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ }
+
+ /**
+ * Test request is served from cache
+ *
+ * @magentoDataFixture Magento/Catalog/_files/category_tree.php
+ */
+ public function testSecondRequestIsServedFromCacheOnMultipleIds()
+ {
+ $categoryId1 ='400';
+ $categoryId2 = '401';
+ $query
+ = <<dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue());
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+
+ $cacheResponse = $this->dispatchGraphQlGETRequest(['query' => $query]);
+ $this->assertEquals('HIT', $cacheResponse->getHeader('X-Magento-Cache-Debug')->getFieldValue());
+ $actualCacheTags = explode(',', $cacheResponse->getHeader('X-Magento-Tags')->getFieldValue());
+ $this->assertEquals($expectedCacheTags, $actualCacheTags);
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php b/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php
index 3bd966018b94..ff4f3f8a58bc 100644
--- a/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php
+++ b/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php
@@ -5,9 +5,24 @@
*/
namespace Magento\Payment\Block;
+use Magento\Framework\View\Element\Text;
+use Magento\Framework\View\LayoutInterface;
+use Magento\OfflinePayments\Model\Banktransfer;
+use Magento\OfflinePayments\Model\Checkmo;
+use Magento\Payment\Block\Info as BlockInfo;
+use Magento\Payment\Block\Info\Instructions;
+use Magento\Payment\Model\Info;
+use Magento\Sales\Model\Order;
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * Class InfoTest
+ */
class InfoTest extends \PHPUnit\Framework\TestCase
{
/**
+ * Tests payment info block.
+ *
* @magentoConfigFixture current_store payment/banktransfer/title Bank Method Title
* @magentoConfigFixture current_store payment/checkmo/title Checkmo Title Of The Method
* @magentoAppArea adminhtml
@@ -15,37 +30,32 @@ class InfoTest extends \PHPUnit\Framework\TestCase
public function testGetChildPdfAsArray()
{
/** @var $layout \Magento\Framework\View\Layout */
- $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
- \Magento\Framework\View\LayoutInterface::class
- );
- $block = $layout->createBlock(\Magento\Payment\Block\Info::class, 'block');
+ $layout = Bootstrap::getObjectManager()->get(LayoutInterface::class);
+ $block = $layout->createBlock(BlockInfo::class, 'block');
- /** @var $paymentInfoBank \Magento\Payment\Model\Info */
- $paymentInfoBank = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\Payment\Model\Info::class
- );
- $paymentInfoBank->setMethodInstance(
- \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\OfflinePayments\Model\Banktransfer::class
- )
+ /** @var $paymentInfoBank Info */
+ $paymentInfoBank = Bootstrap::getObjectManager()->create(
+ Info::class
);
- /** @var $childBank \Magento\Payment\Block\Info\Instructions */
- $childBank = $layout->addBlock(\Magento\Payment\Block\Info\Instructions::class, 'child.one', 'block');
+ $order = Bootstrap::getObjectManager()->create(Order::class);
+ $banktransferPayment = Bootstrap::getObjectManager()->create(Banktransfer::class);
+ $paymentInfoBank->setMethodInstance($banktransferPayment);
+ $paymentInfoBank->setOrder($order);
+ /** @var $childBank Instructions */
+ $childBank = $layout->addBlock(Instructions::class, 'child.one', 'block');
$childBank->setInfo($paymentInfoBank);
$nonExpectedHtml = 'non-expected html';
- $childHtml = $layout->addBlock(\Magento\Framework\View\Element\Text::class, 'child.html', 'block');
+ $childHtml = $layout->addBlock(Text::class, 'child.html', 'block');
$childHtml->setText($nonExpectedHtml);
- /** @var $paymentInfoCheckmo \Magento\Payment\Model\Info */
- $paymentInfoCheckmo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\Payment\Model\Info::class
- );
- $paymentInfoCheckmo->setMethodInstance(
- \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\OfflinePayments\Model\Checkmo::class
- )
+ /** @var $paymentInfoCheckmo Info */
+ $paymentInfoCheckmo = Bootstrap::getObjectManager()->create(
+ Info::class
);
+ $checkmoPayment = Bootstrap::getObjectManager()->create(Checkmo::class);
+ $paymentInfoCheckmo->setMethodInstance($checkmoPayment);
+ $paymentInfoCheckmo->setOrder($order);
/** @var $childCheckmo \Magento\OfflinePayments\Block\Info\Checkmo */
$childCheckmo = $layout->addBlock(
\Magento\OfflinePayments\Block\Info\Checkmo::class,
diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php
index b763130c5a2c..0d36bf02f007 100644
--- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php
+++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php
@@ -432,6 +432,8 @@ private function addAddressByType(string $addressType, $email, ?string $name = n
$this->messageData[$addressType],
$convertedAddressArray
);
+ } else {
+ $this->messageData[$addressType] = $convertedAddressArray;
}
}
}
diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js
index 1c9319f95a64..28bdb96e5cdb 100644
--- a/lib/web/mage/adminhtml/grid.js
+++ b/lib/web/mage/adminhtml/grid.js
@@ -63,6 +63,7 @@ define([
this.initRowCallback = false;
this.doFilterCallback = false;
this.sortableUpdateCallback = false;
+ this.filterKeyPressCallback = false;
this.reloadParams = false;
@@ -511,6 +512,10 @@ define([
if (event.keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq
this.doFilter();
}
+
+ if (this.filterKeyPressCallback) {
+ this.filterKeyPressCallback(this, event);
+ }
},
/**
diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx
index 00ae0bdbb8a4..b6154e136131 100644
--- a/setup/performance-toolkit/benchmark.jmx
+++ b/setup/performance-toolkit/benchmark.jmx
@@ -39431,6 +39431,64 @@ if (name == null) {
Failure = false;
}
}
+
+
+
+ false
+
+
+
+
+
+ true
+
+
+
+ false
+ {"query":"{\n categoryList{\n name\n id\n level\n description\n path\n path_in_store\n url_key\n url_path\n children {\n id\n description\n default_sort_by\n children {\n id\n description\n level\n children {\n level\n id\n children {\n id\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}
+ =
+
+
+
+
+
+
+
+ ${request_protocol}
+
+ ${base_path}graphql
+ POST
+ true
+ false
+ true
+ false
+ false
+
+ mpaf/tool/fragments/ce/graphql/query_root_category_list.jmx
+
+
+
+ graphql_categoryList_query_name
+ $.data.categoryList[0].name
+
+
+ BODY
+ JSON
+
+
+
+ String name = vars.get("graphql_categoryList_query_name");
+if (name == null) {
+ Failure = true;
+ FailureMessage = "Not Expected \"children\" to be null";
+} else {
+ if (!name.equals("Default Category")) {
+ Failure = true;
+ FailureMessage = "Expected \"name\" to equal \"Default Category\", Actual: " + name;
+ } else {
+ Failure = false;
+ }
+}
@@ -40368,6 +40426,301 @@ function assertCategoryChildren(category, response) {
+
+ 1
+ false
+ 1
+ ${graphqlGetCategoryListByCategoryIdPercentage}
+ mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx
+
+
+
+var testLabel = "${testLabel}" ? " (${testLabel})" : "";
+if (testLabel
+ && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy'
+) {
+ if (sampler.getName().indexOf(testLabel) == -1) {
+ sampler.setName(sampler.getName() + testLabel);
+ }
+} else if (sampler.getName().indexOf("SetUp - ") == -1) {
+ sampler.setName("SetUp - " + sampler.getName());
+}
+
+ javascript
+ mpaf/tool/fragments/_system/setup_label.jmx
+
+
+
+ vars.put("testLabel", "GraphQL Get Category List by category_url_key");
+
+ true
+
+
+
+
+
+
+ Content-Type
+ application/json
+
+
+ Accept
+ */*
+
+
+ mpaf/tool/fragments/ce/api/header_manager_before_token.jmx
+
+
+
+ mpaf/tool/fragments/ce/common/init_random_generator_setup.jmx
+
+import java.util.Random;
+
+Random random = new Random();
+if (${seedForRandom} > 0) {
+ random.setSeed(${seedForRandom} + ${__threadNum});
+}
+
+vars.putObject("randomIntGenerator", random);
+
+
+
+ true
+
+
+
+
+ javascript
+
+
+
+ random = vars.getObject("randomIntGenerator");
+
+var categories = props.get("categories");
+number = random.nextInt(categories.length);
+
+vars.put("category_url_key", categories[number].url_key);
+vars.put("category_name", categories[number].name);
+vars.put("category_id", categories[number].id);
+vars.putObject("category", categories[number]);
+
+ mpaf/tool/fragments/ce/common/extract_category_setup.jmx
+
+
+
+ true
+
+
+
+ false
+ {"query" : "{\n categoryList(filters:{url_key: {in: [\"${category_url_key}\"]}}) {\n id\n children {\n id\n name\n url_key\n url_path\n children_count\n path\n image\n productImagePreview: products(pageSize: 1, sort: {name: ASC}) {\n items {\n small_image {\n label\n url\n }\n }\n }\n }\n }\n}"}
+ =
+
+
+
+
+ ${graphql_port_number}
+ 60000
+ 200000
+ ${request_protocol}
+
+ ${base_path}graphql
+ POST
+ true
+ false
+ true
+ false
+ false
+
+ mpaf/tool/fragments/ce/graphql/get_category_list_by_category_url_key.jmx
+
+
+
+ javascript
+
+
+
+ var category = vars.getObject("category");
+var response = JSON.parse(prev.getResponseDataAsString());
+
+assertCategoryId(category, response);
+assertCategoryChildren(category, response);
+
+function assertCategoryId(category, response) {
+ if (response.data == undefined || response.data.categoryList == undefined || response.data.categoryList[0].id != category.id) {
+ AssertionResult.setFailureMessage("Cannot find category with id \"" + category.id + "\"");
+ AssertionResult.setFailure(true);
+ }
+}
+
+function assertCategoryChildren(category, response) {
+ foundCategory = response.data && response.data.categoryList ? response.data.categoryList[0] : null;
+ if (foundCategory) {
+ var childrenFound = foundCategory.children.map(function (c) {return parseInt(c.id)});
+ var children = category.children.map(function (c) {return parseInt(c)});
+ if (JSON.stringify(children.sort()) != JSON.stringify(childrenFound.sort())) {
+ AssertionResult.setFailureMessage("Cannot math children categories \"" + JSON.stringify(children) + "\" for to found one: \"" + JSON.stringify(childrenFound) + "\"");
+ AssertionResult.setFailure(true);
+ }
+ }
+
+}
+
+
+
+
+
+
+
+
+
+ 1
+ false
+ 1
+ ${graphqlGetCategoryListByCategoryIdPercentage}
+ mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx
+
+
+
+var testLabel = "${testLabel}" ? " (${testLabel})" : "";
+if (testLabel
+ && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy'
+) {
+ if (sampler.getName().indexOf(testLabel) == -1) {
+ sampler.setName(sampler.getName() + testLabel);
+ }
+} else if (sampler.getName().indexOf("SetUp - ") == -1) {
+ sampler.setName("SetUp - " + sampler.getName());
+}
+
+ javascript
+ mpaf/tool/fragments/_system/setup_label.jmx
+
+
+
+ vars.put("testLabel", "GraphQL Get Multiple Categories");
+
+ true
+
+
+
+
+
+
+ Content-Type
+ application/json
+
+
+ Accept
+ */*
+
+
+ mpaf/tool/fragments/ce/api/header_manager_before_token.jmx
+
+
+
+ mpaf/tool/fragments/ce/common/init_random_generator_setup.jmx
+
+import java.util.Random;
+
+Random random = new Random();
+if (${seedForRandom} > 0) {
+ random.setSeed(${seedForRandom} + ${__threadNum});
+}
+
+vars.putObject("randomIntGenerator", random);
+
+
+
+ true
+
+
+
+
+ javascript
+
+
+
+ random = vars.getObject("randomIntGenerator");
+
+var categories = props.get("categories");
+
+var numbers = [];
+
+var sanity = 0;
+for(var i = 0; i < 4; i++){
+ sanity++;
+ if(sanity > 100){
+ break;
+ }
+ var number = random.nextInt(categories.length)
+ if(numbers.indexOf(number) >= 0){
+ i--;
+ continue;
+ }
+ numbers.push(number);
+}
+
+vars.put("category_id_1", categories[numbers[0]].id);
+vars.put("category_id_2", categories[numbers[1]].id);
+vars.put("category_id_3", categories[numbers[2]].id);
+vars.put("category_id_4", categories[numbers[3]].id);
+
+ mpaf/tool/fragments/ce/common/extract_multiple_categories_setup.jmx
+
+
+
+
+ true
+
+
+
+ false
+ {"query" : "{\n categoryList(filters:{ids: {in: [\"${category_id_1}\", \"${category_id_2}\", \"${category_id_3}\", \"${category_id_4}\"]}}) {\n id\n children {\n id\n name\n url_key\n url_path\n children_count\n path\n image\n productImagePreview: products(pageSize: 1, sort: {name: ASC}) {\n items {\n small_image {\n label\n url\n }\n }\n }\n }\n }\n}"}
+ =
+
+
+
+
+ ${graphql_port_number}
+ 60000
+ 200000
+ ${request_protocol}
+
+ ${base_path}graphql
+ POST
+ true
+ false
+ true
+ false
+ false
+
+ mpaf/tool/fragments/ce/graphql/get_multiple_categories_by_id.jmx
+
+
+
+ javascript
+
+
+
+ var response = JSON.parse(prev.getResponseDataAsString());
+
+if(response.data == undefined || response.data.categoryList == undefined){
+ AssertionResult.setFailureMessage("CategoryList results are empty.");
+ AssertionResult.setFailure(true);
+}
+
+if(response.data.categoryList.length !== 4){
+ AssertionResult.setFailureMessage("CategoryList query expected to find 4 categories. " + response.data.categoryList.length + " returned.");
+ AssertionResult.setFailure(true);
+}
+
+
+
+
+
+
+
1
false