diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/AdminCheckAnalyticsTrackingTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/AdminCheckAnalyticsTrackingTest.xml
new file mode 100644
index 0000000000000..4f0e9bb000a27
--- /dev/null
+++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/AdminCheckAnalyticsTrackingTest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/AdminNavigateToEmailToFriendSettingsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AdminNavigateToEmailToFriendSettingsActionGroup.xml
new file mode 100644
index 0000000000000..05903581747d9
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AdminNavigateToEmailToFriendSettingsActionGroup.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminEmailToFriendOptionsAvailableActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminEmailToFriendOptionsAvailableActionGroup.xml
new file mode 100644
index 0000000000000..88152a2cb4f73
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminEmailToFriendOptionsAvailableActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminPageIs404ActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminPageIs404ActionGroup.xml
new file mode 100644
index 0000000000000..09b0bdcc146ae
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminPageIs404ActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+ Validates that the '404 Error' message is present in the current Admin Page Header.
+
+
+
+
+
diff --git a/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationEmailToFriendPage.xml b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationEmailToFriendPage.xml
new file mode 100644
index 0000000000000..14bd514f1a16f
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationEmailToFriendPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminCatalogEmailToFriendSettingsTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminCatalogEmailToFriendSettingsTest.xml
new file mode 100644
index 0000000000000..b410a4cb73de7
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminCatalogEmailToFriendSettingsTest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Bundle/Model/Product/BundleOptionDataProvider.php b/app/code/Magento/Bundle/Model/Product/BundleOptionDataProvider.php
new file mode 100644
index 0000000000000..f56c4228e49e5
--- /dev/null
+++ b/app/code/Magento/Bundle/Model/Product/BundleOptionDataProvider.php
@@ -0,0 +1,144 @@
+pricingHelper = $pricingHelper;
+ $this->serializer = $serializer;
+ $this->configuration = $configuration;
+ }
+
+ /**
+ * Extract data for a bundled item
+ *
+ * @param ItemInterface $item
+ *
+ * @return array
+ */
+ public function getData(ItemInterface $item): array
+ {
+ $options = [];
+ $product = $item->getProduct();
+ $optionsQuoteItemOption = $item->getOptionByCode('bundle_option_ids');
+ $bundleOptionsIds = $optionsQuoteItemOption
+ ? $this->serializer->unserialize($optionsQuoteItemOption->getValue())
+ : [];
+
+ /** @var Type $typeInstance */
+ $typeInstance = $product->getTypeInstance();
+
+ if ($bundleOptionsIds) {
+ $selectionsQuoteItemOption = $item->getOptionByCode('bundle_selection_ids');
+ $optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $product);
+ $bundleSelectionIds = $this->serializer->unserialize($selectionsQuoteItemOption->getValue());
+
+ if (!empty($bundleSelectionIds)) {
+ $selectionsCollection = $typeInstance->getSelectionsByIds($bundleSelectionIds, $product);
+ $bundleOptions = $optionsCollection->appendSelections($selectionsCollection, true);
+
+ $options = $this->buildBundleOptions($bundleOptions, $item);
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * Build bundle product options based on current selection
+ *
+ * @param Option[] $bundleOptions
+ * @param ItemInterface $item
+ *
+ * @return array
+ */
+ private function buildBundleOptions(array $bundleOptions, ItemInterface $item): array
+ {
+ $options = [];
+ foreach ($bundleOptions as $bundleOption) {
+ if (!$bundleOption->getSelections()) {
+ continue;
+ }
+
+ $options[] = [
+ 'id' => $bundleOption->getId(),
+ 'label' => $bundleOption->getTitle(),
+ 'type' => $bundleOption->getType(),
+ 'values' => $this->buildBundleOptionValues($bundleOption->getSelections(), $item),
+ ];
+ }
+
+ return $options;
+ }
+
+ /**
+ * Build bundle product option values based on current selection
+ *
+ * @param Product[] $selections
+ * @param ItemInterface $item
+ *
+ * @return array
+ */
+ private function buildBundleOptionValues(array $selections, ItemInterface $item): array
+ {
+ $product = $item->getProduct();
+ $values = [];
+
+ foreach ($selections as $selection) {
+ $qty = (float) $this->configuration->getSelectionQty($product, $selection->getSelectionId());
+ if (!$qty) {
+ continue;
+ }
+
+ $selectionPrice = $this->configuration->getSelectionFinalPrice($item, $selection);
+ $values[] = [
+ 'label' => $selection->getName(),
+ 'id' => $selection->getSelectionId(),
+ 'quantity' => $qty,
+ 'price' => $this->pricingHelper->currency($selectionPrice, false, false),
+ ];
+ }
+
+ return $values;
+ }
+}
diff --git a/app/code/Magento/BundleGraphQl/Model/Wishlist/BundleOptions.php b/app/code/Magento/BundleGraphQl/Model/Wishlist/BundleOptions.php
new file mode 100644
index 0000000000000..217f822e771da
--- /dev/null
+++ b/app/code/Magento/BundleGraphQl/Model/Wishlist/BundleOptions.php
@@ -0,0 +1,54 @@
+bundleOptionDataProvider = $bundleOptionDataProvider;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!$value['itemModel'] instanceof ItemInterface) {
+ throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
+ 'instance' => ItemInterface::class
+ ]));
+ }
+
+ return $this->bundleOptionDataProvider->getData($value['itemModel']);
+ }
+}
diff --git a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml
index 863e152fbe177..7fe0b2a53677c 100644
--- a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml
+++ b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml
@@ -100,4 +100,11 @@
+
+
+
+ - BundleWishlistItem
+
+
+
diff --git a/app/code/Magento/BundleGraphQl/etc/schema.graphqls b/app/code/Magento/BundleGraphQl/etc/schema.graphqls
index a66fa397020a7..a2cba24c7c4d4 100644
--- a/app/code/Magento/BundleGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/BundleGraphQl/etc/schema.graphqls
@@ -117,3 +117,7 @@ type ItemSelectedBundleOptionValue @doc(description: "A list of values for the s
quantity: Float! @doc(description: "Indicates how many of this bundle product were ordered")
price: Money! @doc(description: "The price of the child bundle product")
}
+
+type BundleWishlistItem implements WishlistItemInterface {
+ bundle_options: [SelectedBundleOption!] @doc(description: "An array containing information about the selected bundle items") @resolver(class: "\\Magento\\BundleGraphQl\\Model\\Wishlist\\BundleOptions")
+}
diff --git a/app/code/Magento/Captcha/CustomerData/Captcha.php b/app/code/Magento/Captcha/CustomerData/Captcha.php
index e07bf953abaa3..901477c75610b 100644
--- a/app/code/Magento/Captcha/CustomerData/Captcha.php
+++ b/app/code/Magento/Captcha/CustomerData/Captcha.php
@@ -58,7 +58,7 @@ public function __construct(
/**
* @inheritdoc
*/
- public function getSectionData() :array
+ public function getSectionData(): array
{
$data = [];
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml
index c35e775152ac9..c94bca1ca5c13 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridFilterSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridFilterSection.xml
index 4e86f14611c24..201affacd9adb 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridFilterSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridFilterSection.xml
@@ -38,5 +38,6 @@
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontFooterSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontFooterSection.xml
index 1c937637ad823..a7dd622c56a7f 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontFooterSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontFooterSection.xml
@@ -9,6 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridUrlFilterApplierTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridUrlFilterApplierTest.xml
index fea4436446da2..2eda7b8d02481 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridUrlFilterApplierTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridUrlFilterApplierTest.xml
@@ -31,11 +31,11 @@
-
+
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml
deleted file mode 100644
index 7ec5fea49f64b..0000000000000
--- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
index c4f9bc26ee9f3..9ed36098ab6eb 100644
--- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
+++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
@@ -180,4 +180,12 @@
Magento\Widget\Model\Template\FilterEmulate
+
+
+
+ - SimpleWishlistItem
+ - VirtualWishlistItem
+
+
+
diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls
index 35f2c767b3e1e..35067a6cb99af 100644
--- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls
@@ -492,3 +492,9 @@ type StoreConfig @doc(description: "The type contains information about a store
catalog_default_sort_by : String @doc(description: "Default Sort By.")
root_category_id: Int @doc(description: "The ID of the root category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\RootCategoryId")
}
+
+type SimpleWishlistItem implements WishlistItemInterface @doc(description: "A simple product wish list Item") {
+}
+
+type VirtualWishlistItem implements WishlistItemInterface @doc(description: "A virtual product wish list item") {
+}
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutActionGroup.xml
new file mode 100644
index 0000000000000..8210fe1df73ba
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Checks if visible password field for unregistered email on checkout page
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAssertCheckoutErrorMessageActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAssertCheckoutErrorMessageActionGroup.xml
new file mode 100644
index 0000000000000..6db9d9a1f0673
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAssertCheckoutErrorMessageActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartMessageSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartMessageSection.xml
index cf15cdf15cf15..0c7f200e2b5eb 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartMessageSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartMessageSection.xml
@@ -12,5 +12,6 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml
new file mode 100644
index 0000000000000..41b5f734d0096
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js
index 9adfb549a5b1c..8311d97522980 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js
@@ -113,6 +113,7 @@ define([
$.when(this.isEmailCheckComplete).done(function () {
this.isPasswordVisible(false);
+ checkoutData.setCheckedEmailValue('');
}.bind(this)).fail(function () {
this.isPasswordVisible(true);
checkoutData.setCheckedEmailValue(this.email());
@@ -192,6 +193,10 @@ define([
* @returns {Boolean} - initial visibility state.
*/
resolveInitialPasswordVisibility: function () {
+ if (checkoutData.getInputFieldEmailValue() !== '' && checkoutData.getCheckedEmailValue() !== '') {
+ return true;
+ }
+
if (checkoutData.getInputFieldEmailValue() !== '') {
return checkoutData.getInputFieldEmailValue() === checkoutData.getCheckedEmailValue();
}
diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminEmailToFriendSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminEmailToFriendSection.xml
new file mode 100644
index 0000000000000..956316ed5cb46
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/Section/AdminEmailToFriendSection.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
index cf0e99f7c45c0..37c129dc3bbde 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
@@ -13,6 +13,7 @@
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTierPriceForOneItemTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTierPriceForOneItemTest.xml
index 1491081a82ee4..4de01b0c9d14e 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTierPriceForOneItemTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTierPriceForOneItemTest.xml
@@ -48,7 +48,7 @@
-
+
@@ -109,5 +109,8 @@
Buy {{tierProductPrice.quantity}} for ${{tierProductPrice.price}} each and save 27%
tierPriceText
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
index f705b6a95987c..00030be74324f 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
@@ -740,21 +740,19 @@ define([
* @private
*/
_displayTierPriceBlock: function (optionId) {
- var options, tierPriceHtml;
+ var tierPrices = typeof optionId != 'undefined' && this.options.spConfig.optionPrices[optionId].tierPrices;
- if (typeof optionId != 'undefined' &&
- this.options.spConfig.optionPrices[optionId].tierPrices != [] // eslint-disable-line eqeqeq
- ) {
- options = this.options.spConfig.optionPrices[optionId];
+ if (_.isArray(tierPrices) && tierPrices.length > 0) {
if (this.options.tierPriceTemplate) {
- tierPriceHtml = mageTemplate(this.options.tierPriceTemplate, {
- 'tierPrices': options.tierPrices,
- '$t': $t,
- 'currencyFormat': this.options.spConfig.currencyFormat,
- 'priceUtils': priceUtils
- });
- $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();
+ $(this.options.tierPriceBlockSelector).html(
+ mageTemplate(this.options.tierPriceTemplate, {
+ 'tierPrices': tierPrices,
+ '$t': $t,
+ 'currencyFormat': this.options.spConfig.currencyFormat,
+ 'priceUtils': priceUtils
+ })
+ ).show();
}
} else {
$(this.options.tierPriceBlockSelector).hide();
diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ChildSku.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ChildSku.php
new file mode 100644
index 0000000000000..84decab81c96a
--- /dev/null
+++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ChildSku.php
@@ -0,0 +1,43 @@
+ Product::class
+ ]));
+ }
+
+ /** @var Product $product */
+ $product = $value['model'];
+ $optionProduct = $product->getCustomOption('simple_product')->getProduct();
+
+ return $optionProduct->getSku();
+ }
+}
diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ConfigurableOptions.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ConfigurableOptions.php
new file mode 100644
index 0000000000000..6fcb3e118e5f1
--- /dev/null
+++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Wishlist/ConfigurableOptions.php
@@ -0,0 +1,67 @@
+configurationHelper = $configurationHelper;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!$value['itemModel'] instanceof ItemInterface) {
+ throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
+ 'instance' => ItemInterface::class
+ ]));
+ }
+
+ /** @var ItemInterface $item */
+ $item = $value['itemModel'];
+ $result = [];
+
+ foreach ($this->configurationHelper->getOptions($item) as $option) {
+ $result[] = [
+ 'id' => $option['option_id'],
+ 'option_label' => $option['label'],
+ 'value_id' => $option['option_value'],
+ 'value_label' => $option['value'],
+ ];
+ }
+
+ return $result;
+ }
+}
diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml
index f82bb0dbd4d91..808ca62f7e149 100644
--- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml
+++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml
@@ -36,4 +36,11 @@
+
+
+
+ - ConfigurableWishlistItem
+
+
+
diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls
index 6e85653380acc..257bca11fb5b7 100644
--- a/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/ConfigurableProductGraphQl/etc/schema.graphqls
@@ -68,3 +68,8 @@ type SelectedConfigurableOption {
value_id: Int!
value_label: String!
}
+
+type ConfigurableWishlistItem implements WishlistItemInterface @doc(description: "A configurable product wish list item"){
+ child_sku: String! @doc(description: "The SKU of the simple product corresponding to a set of selected configurable options") @resolver(class: "\\Magento\\ConfigurableProductGraphQl\\Model\\Wishlist\\ChildSku")
+ configurable_options: [SelectedConfigurableOption!] @resolver(class: "\\Magento\\ConfigurableProductGraphQl\\Model\\Wishlist\\ConfigurableOptions") @doc (description: "An array of selected configurable options")
+}
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminClickFirstRowEditLinkOnCustomerGridActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminClickFirstRowEditLinkOnCustomerGridActionGroup.xml
new file mode 100644
index 0000000000000..0cfe9f80d1619
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminClickFirstRowEditLinkOnCustomerGridActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Click edit link for first row on the grid.
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerRetailerWithoutAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerRetailerWithoutAddressTest.xml
index c8e3bc10cc769..9f6d8d645e5f4 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerRetailerWithoutAddressTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerRetailerWithoutAddressTest.xml
@@ -50,8 +50,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryPolandTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryPolandTest.xml
index 5f496e2c5fba3..782c1599bf489 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryPolandTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryPolandTest.xml
@@ -31,8 +31,7 @@
-
-
+
@@ -67,8 +66,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml
index da2eed2006434..304d545fb4c93 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml
@@ -31,8 +31,7 @@
-
-
+
@@ -67,8 +66,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCustomGroupTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCustomGroupTest.xml
index 8afd1648d26e0..7cffd5f304e31 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCustomGroupTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCustomGroupTest.xml
@@ -54,8 +54,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithPrefixTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithPrefixTest.xml
index e9250be637534..eaa3a11edb74e 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithPrefixTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithPrefixTest.xml
@@ -56,8 +56,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithoutAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithoutAddressTest.xml
index 5033f2882af42..98826b147ad81 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithoutAddressTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithoutAddressTest.xml
@@ -49,8 +49,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml
index 5440339e3a95e..683b275ca1ed6 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml
@@ -45,8 +45,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerTest.xml
index 6b484e857d276..5edb9d08da46d 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerTest.xml
@@ -42,8 +42,7 @@
-
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml
index a8391458a1a50..87111ec6fba1a 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml
@@ -53,8 +53,7 @@
-
-
+
diff --git a/app/code/Magento/DownloadableGraphQl/Model/Wishlist/ItemLinks.php b/app/code/Magento/DownloadableGraphQl/Model/Wishlist/ItemLinks.php
new file mode 100644
index 0000000000000..68223054aa806
--- /dev/null
+++ b/app/code/Magento/DownloadableGraphQl/Model/Wishlist/ItemLinks.php
@@ -0,0 +1,68 @@
+convertLinksToArray = $convertLinksToArray;
+ $this->downloadableConfiguration = $downloadableConfiguration;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!$value['itemModel'] instanceof ItemInterface) {
+ throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
+ 'instance' => ItemInterface::class
+ ]));
+ }
+ /** @var ItemInterface $wishlistItem */
+ $itemItem = $value['itemModel'];
+
+ $links = $this->downloadableConfiguration->getLinks($itemItem);
+ $links = $this->convertLinksToArray->execute($links);
+
+ return $links;
+ }
+}
diff --git a/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml b/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml
index c95667de15ac3..51a630d59ca0f 100644
--- a/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml
+++ b/app/code/Magento/DownloadableGraphQl/etc/graphql/di.xml
@@ -39,4 +39,11 @@
+
+
+
+ - DownloadableWishlistItem
+
+
+
diff --git a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls
index 5863e62e81b1b..ba178bb1a427e 100644
--- a/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/DownloadableGraphQl/etc/schema.graphqls
@@ -64,3 +64,8 @@ type DownloadableProductSamples @doc(description: "DownloadableProductSamples de
sample_type: DownloadableFileTypeEnum @deprecated(reason: "`sample_url` serves to get the downloadable sample")
sample_file: String @deprecated(reason: "`sample_url` serves to get the downloadable sample")
}
+
+type DownloadableWishlistItem implements WishlistItemInterface @doc(description: "A downloadable product wish list item") {
+ links_v2: [DownloadableProductLinks] @doc(description: "An array containing information about the selected links") @resolver(class: "\\Magento\\DownloadableGraphQl\\Model\\Wishlist\\ItemLinks")
+ samples: [DownloadableProductSamples] @doc(description: "An array containing information about the selected samples") @resolver(class: "Magento\\DownloadableGraphQl\\Resolver\\Product\\Samples")
+}
diff --git a/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php b/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php
index f33c22a18b4b8..d0ba786c7084e 100644
--- a/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php
+++ b/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php
@@ -78,7 +78,7 @@ public function execute(array $paths): void
if (!empty($failedPaths)) {
throw new CouldNotSaveException(
__(
- 'Could not save directories: %paths',
+ 'Could not create directories: %paths',
[
'paths' => implode(' ,', $failedPaths)
]
diff --git a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/ActionGroup/AdminAssertMediaGalleryFilterPlaceHolderGridActionGroup.xml b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/ActionGroup/AdminAssertMediaGalleryFilterPlaceHolderGridActionGroup.xml
new file mode 100644
index 0000000000000..e21fa89965391
--- /dev/null
+++ b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/ActionGroup/AdminAssertMediaGalleryFilterPlaceHolderGridActionGroup.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Assert asset filter placeholder value
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiUsedInProductFilterTest.xml b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiUsedInProductFilterTest.xml
index 74633fbb73542..c3f3d6ecd9e8d 100644
--- a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiUsedInProductFilterTest.xml
+++ b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiUsedInProductFilterTest.xml
@@ -10,27 +10,22 @@
-
-
+
+
-
+
-
-
-
-
+
-
-
@@ -38,11 +33,7 @@
-
-
-
-
-
+
@@ -59,17 +50,22 @@
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkCategoryGridTest.xml b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkCategoryGridTest.xml
index 7e0fa6c477c45..5cb778dfb9c8c 100644
--- a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkCategoryGridTest.xml
+++ b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkCategoryGridTest.xml
@@ -23,14 +23,12 @@
-
-
@@ -60,5 +58,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkProductGridTest.xml b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkProductGridTest.xml
new file mode 100644
index 0000000000000..db7942d4c53bf
--- /dev/null
+++ b/app/code/Magento/MediaGalleryCatalogUi/Test/Mftf/Test/AdminMediaGalleryCatalogUiVerifyUsedInLinkProductGridTest.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkBlocksGridTest.xml b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkBlocksGridTest.xml
new file mode 100644
index 0000000000000..a0cd04fad54c5
--- /dev/null
+++ b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkBlocksGridTest.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkPagesGridTest.xml b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkPagesGridTest.xml
new file mode 100644
index 0000000000000..de8517eedae0e
--- /dev/null
+++ b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryAssertUsedInLinkPagesGridTest.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInBlocksFilterTest.xml b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInBlocksFilterTest.xml
index 810d9eea4e261..fa6dc6c1a07fa 100644
--- a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInBlocksFilterTest.xml
+++ b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInBlocksFilterTest.xml
@@ -55,6 +55,6 @@
-
+
diff --git a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml
index a6bfdb781a734..038f1ae077b4a 100644
--- a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml
+++ b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml
@@ -21,14 +21,14 @@
-
+
-
+
@@ -39,7 +39,7 @@
-
+
@@ -56,8 +56,9 @@
-
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Media/Index.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Media/Index.php
index 3660374243d16..8c5b3d4d3a9ac 100644
--- a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Media/Index.php
+++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Media/Index.php
@@ -12,6 +12,9 @@
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
+use Magento\MediaContentApi\Model\Config;
+use Magento\Backend\App\Action\Context;
+use Magento\Backend\Model\View\Result\Forward;
/**
* Controller serving the media gallery content
@@ -20,6 +23,24 @@ class Index extends Action implements HttpGetActionInterface
{
public const ADMIN_RESOURCE = 'Magento_Cms::media_gallery';
+ /**
+ * @var Config
+ */
+ private $config;
+
+ /**
+ * Index constructor.
+ * @param Context $context
+ * @param Config $config
+ */
+ public function __construct(
+ Context $context,
+ Config $config
+ ) {
+ parent::__construct($context);
+ $this->config = $config;
+ }
+
/**
* Get the media gallery layout
*
@@ -27,6 +48,14 @@ class Index extends Action implements HttpGetActionInterface
*/
public function execute(): ResultInterface
{
+ if (!$this->config->isEnabled()) {
+ /** @var Forward $resultForward */
+ $resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
+ $resultForward->forward('noroute');
+
+ return $resultForward;
+ }
+
/** @var Page $resultPage */
$resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$resultPage->setActiveMenu('Magento_MediaGalleryUi::media_gallery')
diff --git a/app/code/Magento/MediaGalleryUi/Model/Directories/GetFolderTree.php b/app/code/Magento/MediaGalleryUi/Model/Directories/GetFolderTree.php
index f0998a3e120f2..c22165ba4e51f 100644
--- a/app/code/Magento/MediaGalleryUi/Model/Directories/GetFolderTree.php
+++ b/app/code/Magento/MediaGalleryUi/Model/Directories/GetFolderTree.php
@@ -7,13 +7,14 @@
namespace Magento\MediaGalleryUi\Model\Directories;
+use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\ValidatorException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\Read;
use Magento\MediaGalleryApi\Api\IsPathExcludedInterface;
/**
- * Build folder tree structure by path
+ * Build media gallery folder tree structure by path
*/
class GetFolderTree
{
@@ -22,43 +23,45 @@ class GetFolderTree
*/
private $filesystem;
- /**
- * @var string
- */
- private $path;
-
/**
* @var IsPathExcludedInterface
*/
private $isPathExcluded;
/**
- * Constructor
- *
* @param Filesystem $filesystem
- * @param string $path
* @param IsPathExcludedInterface $isPathExcluded
*/
public function __construct(
Filesystem $filesystem,
- string $path,
IsPathExcludedInterface $isPathExcluded
) {
$this->filesystem = $filesystem;
- $this->path = $path;
$this->isPathExcluded = $isPathExcluded;
}
/**
* Return directory folder structure in array
*
- * @param bool $skipRoot
* @return array
* @throws ValidatorException
*/
- public function execute(bool $skipRoot = true): array
+ public function execute(): array
{
- return $this->buildFolderTree($this->getDirectories(), $skipRoot);
+ $tree = [
+ 'name' => 'root',
+ 'path' => '/',
+ 'children' => []
+ ];
+ $directories = $this->getDirectories();
+ foreach ($directories as $idx => &$node) {
+ $node['children'] = [];
+ $result = $this->findParent($node, $tree);
+ $parent = &$result['treeNode'];
+
+ $parent['children'][] = &$directories[$idx];
+ }
+ return $tree['children'];
}
/**
@@ -72,7 +75,7 @@ private function getDirectories(): array
$directories = [];
/** @var Read $directory */
- $directory = $this->filesystem->getDirectoryRead($this->path);
+ $directory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
if (!$directory->isDirectory()) {
return $directories;
@@ -96,30 +99,6 @@ private function getDirectories(): array
return $directories;
}
- /**
- * Build folder tree structure by provided directories path
- *
- * @param array $directories
- * @param bool $skipRoot
- * @return array
- */
- private function buildFolderTree(array $directories, bool $skipRoot): array
- {
- $tree = [
- 'name' => 'root',
- 'path' => '/',
- 'children' => []
- ];
- foreach ($directories as $idx => &$node) {
- $node['children'] = [];
- $result = $this->findParent($node, $tree);
- $parent = & $result['treeNode'];
-
- $parent['children'][] =& $directories[$idx];
- }
- return $skipRoot ? $tree['children'] : $tree;
- }
-
/**
* Find parent directory
*
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminEnhancedMediaGalleryAssertMassActionModeNotActiveActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminEnhancedMediaGalleryAssertMassActionModeNotActiveActionGroup.xml
index a691f65387e8e..1ec2004b22f24 100644
--- a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminEnhancedMediaGalleryAssertMassActionModeNotActiveActionGroup.xml
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminEnhancedMediaGalleryAssertMassActionModeNotActiveActionGroup.xml
@@ -12,8 +12,8 @@
Asserts that massaction mode is terminated
-
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertAdminEnhancedMediaGalleryUsedInSectionNotDisplayedActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertAdminEnhancedMediaGalleryUsedInSectionNotDisplayedActionGroup.xml
new file mode 100644
index 0000000000000..62adffc931c16
--- /dev/null
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertAdminEnhancedMediaGalleryUsedInSectionNotDisplayedActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+ Assert that's used in section not displayed in view details.
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertFolderIsChangedActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertFolderIsChangedActionGroup.xml
new file mode 100644
index 0000000000000..090dbed8b4f78
--- /dev/null
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AssertFolderIsChangedActionGroup.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ Assert that folder is changed
+
+
+
+
+
+
+
+ {{newSelectedFolder}}
+ {{oldSelectedFolder}}
+
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminEnhancedMediaGalleryViewDetailsSection.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminEnhancedMediaGalleryViewDetailsSection.xml
index e63429677fbae..d6abe464048c7 100644
--- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminEnhancedMediaGalleryViewDetailsSection.xml
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminEnhancedMediaGalleryViewDetailsSection.xml
@@ -19,6 +19,7 @@
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Suite/MediaGalleryUiDisabledSuite.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Suite/MediaGalleryUiDisabledSuite.xml
new file mode 100644
index 0000000000000..727fbde3f17b6
--- /dev/null
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Suite/MediaGalleryUiDisabledSuite.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminEnhancedMediaGalleryDeleteImagesInBulkTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminEnhancedMediaGalleryDeleteImagesInBulkTest.xml
index 94831b039b53a..63c0fbfeefbbf 100644
--- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminEnhancedMediaGalleryDeleteImagesInBulkTest.xml
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminEnhancedMediaGalleryDeleteImagesInBulkTest.xml
@@ -19,9 +19,17 @@
+
-
+
+
+
+
+
+
+
+
@@ -34,7 +42,7 @@
-
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGallerySwitchingBetweenViewsTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGallerySwitchingBetweenViewsTest.xml
new file mode 100644
index 0000000000000..01b8c27b7371d
--- /dev/null
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGallerySwitchingBetweenViewsTest.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml
index ca7a71258fead..3dd294fa50605 100644
--- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml
@@ -36,6 +36,7 @@
+
diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminStandaloneMediaGalleryDisabledTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminStandaloneMediaGalleryDisabledTest.xml
new file mode 100644
index 0000000000000..8b0c984c1df77
--- /dev/null
+++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminStandaloneMediaGalleryDisabledTest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/MediaGalleryUi/Ui/Component/DirectoriesTree.php b/app/code/Magento/MediaGalleryUi/Ui/Component/DirectoryTree.php
similarity index 81%
rename from app/code/Magento/MediaGalleryUi/Ui/Component/DirectoriesTree.php
rename to app/code/Magento/MediaGalleryUi/Ui/Component/DirectoryTree.php
index 4047a4fcb98d8..269bc1f8bcba7 100644
--- a/app/code/Magento/MediaGalleryUi/Ui/Component/DirectoriesTree.php
+++ b/app/code/Magento/MediaGalleryUi/Ui/Component/DirectoryTree.php
@@ -14,7 +14,7 @@
/**
* Directories tree component
*/
-class DirectoriesTree extends Container
+class DirectoryTree extends Container
{
/**
* @var UrlInterface
@@ -50,9 +50,9 @@ public function prepare(): void
array_replace_recursive(
(array) $this->getData('config'),
[
- 'getDirectoryTreeUrl' => $this->url->getUrl("media_gallery/directories/gettree"),
- 'deleteDirectoryUrl' => $this->url->getUrl("media_gallery/directories/delete"),
- 'createDirectoryUrl' => $this->url->getUrl("media_gallery/directories/create")
+ 'getDirectoryTreeUrl' => $this->url->getUrl('media_gallery/directories/gettree'),
+ 'deleteDirectoryUrl' => $this->url->getUrl('media_gallery/directories/delete'),
+ 'createDirectoryUrl' => $this->url->getUrl('media_gallery/directories/create')
]
)
);
diff --git a/app/code/Magento/MediaGalleryUi/etc/di.xml b/app/code/Magento/MediaGalleryUi/etc/di.xml
index a8c4e2a8d8963..6ed3a98bbf03a 100644
--- a/app/code/Magento/MediaGalleryUi/etc/di.xml
+++ b/app/code/Magento/MediaGalleryUi/etc/di.xml
@@ -28,11 +28,6 @@
-
-
- media
-
-
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/media_gallery_listing.xml b/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/media_gallery_listing.xml
index 49206043725f9..66731b1cbae6f 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/media_gallery_listing.xml
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/media_gallery_listing.xml
@@ -219,7 +219,7 @@
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/standalone_media_gallery_listing.xml b/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/standalone_media_gallery_listing.xml
index 655178c104492..3656a8ea25f74 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/standalone_media_gallery_listing.xml
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/ui_component/standalone_media_gallery_listing.xml
@@ -206,7 +206,7 @@
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/css/source/_module.less b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/css/source/_module.less
index fc8bd49126d8e..6b3cd610f0348 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/css/source/_module.less
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/css/source/_module.less
@@ -18,7 +18,7 @@
@color-media-gallery-buttons-border: #adadad;
@color-media-gallery-buttons-text: #514943;
@color-media-gallery-checkbox-background: #eee;
-
+@color-media-gallery-scrollbar-background: #fff;
& when (@media-common = true) {
.media-gallery-delete-image-action,
@@ -170,8 +170,9 @@
height: 30px;
margin: 1px;
padding-left: 6px;
+ padding-right: 10px;
padding-top: 6px;
- width: 100%;
+ width: max-content;
}
.jstree-default .jstree-clicked {
@@ -272,8 +273,18 @@
}
.media-directory-container {
+ &::-webkit-scrollbar {
+ background-color: @color-media-gallery-scrollbar-background;
+ }
+ &::-webkit-scrollbar-thumb {
+ background-color: @color-masonry-grey;
+ }
float: left;
+ max-width: 50%;
+ overflow-x: scroll;
+ overflow-y: hidden;
padding-right: 40px;
+ scrollbar-color: @color-masonry-grey @color-media-gallery-scrollbar-background;
}
.media-gallery-image-block {
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/action/deleteImageWithDetailConfirmation.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/action/deleteImageWithDetailConfirmation.js
index ed40674df20f0..28c021fe4728f 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/action/deleteImageWithDetailConfirmation.js
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/action/deleteImageWithDetailConfirmation.js
@@ -21,25 +21,24 @@ define([
* @param {String} deleteImageUrl
*/
deleteImageAction: function (recordsIds, imageDetailsUrl, deleteImageUrl) {
- var confirmationContent = $t('%1 Are you sure you want to delete "%2" image(s)?')
+ var confirmationContent = $t('%1Are you sure you want to delete "%2" image(s)?')
.replace('%2', Object.keys(recordsIds).length),
deferred = $.Deferred();
- getDetails(imageDetailsUrl, recordsIds)
- .then(function (imageDetails) {
+ getDetails(imageDetailsUrl, recordsIds).then(function (images) {
confirmationContent = confirmationContent.replace(
'%1',
- this.getRecordRelatedContentMessage(imageDetails)
+ this.getRecordRelatedContentMessage(images) + ' '
);
}.bind(this)).fail(function () {
- confirmationContent = confirmationContent.replace('%1', '');
- }).always(function () {
- deleteImages(recordsIds, deleteImageUrl, confirmationContent).then(function (status) {
- deferred.resolve(status);
- }).fail(function (error) {
- deferred.reject(error);
- });
- });
+ confirmationContent = confirmationContent.replace('%1', '');
+ }).always(function () {
+ deleteImages(recordsIds, deleteImageUrl, confirmationContent).then(function (status) {
+ deferred.resolve(status);
+ }).fail(function (error) {
+ deferred.reject(error);
+ });
+ });
return deferred.promise();
},
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directories.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directories.js
index d7f756d8bbd90..6d8d38a1ca1d6 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directories.js
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directories.js
@@ -23,6 +23,7 @@ define([
deleteButtonSelector: '#delete_folder',
createFolderButtonSelector: '#create_folder',
messageDelay: 5,
+ selectedFolder: null,
messagesName: 'media_gallery_listing.media_gallery_listing.messages',
modules: {
directoryTree: '${ $.parentName }.media_gallery_directories',
@@ -47,51 +48,57 @@ define([
*/
initEvents: function () {
$(this.deleteButtonSelector).on('delete_folder', function () {
- this.getConfirmationPopupDeleteFolder();
+ this.deleteFolder();
}.bind(this));
$(this.createFolderButtonSelector).on('create_folder', function () {
- this.getPrompt({
- title: $t('New Folder Name:'),
- content: '',
- actions: {
- /**
- * Confirm action
- */
- confirm: function (folderName) {
- createDirectory(
- this.directoryTree().createDirectoryUrl,
- [this.getNewFolderPath(folderName)]
- ).then(function () {
- this.directoryTree().reloadJsTree().then(function () {
- $(this.directoryTree().directoryTreeSelector).on('loaded.jstree', function () {
- this.directoryTree().locateNode(this.getNewFolderPath(folderName));
- }.bind(this));
- }.bind(this));
+ this.createFolder();
+ }.bind(this));
+ },
- }.bind(this)).fail(function (error) {
- uiAlert({
- content: error
- });
+ /**
+ * Show confirmation popup and create folder based on user input
+ */
+ createFolder: function () {
+ this.getPrompt({
+ title: $t('New Folder Name:'),
+ content: '',
+ actions: {
+ /**
+ * Confirm action
+ */
+ confirm: function (folderName) {
+ createDirectory(
+ this.directoryTree().createDirectoryUrl,
+ [this.getNewFolderPath(folderName)]
+ ).then(function () {
+ this.directoryTree().reloadJsTree().then(function () {
+ $(this.directoryTree().directoryTreeSelector).on('loaded.jstree', function () {
+ this.directoryTree().locateNode(this.getNewFolderPath(folderName));
+ }.bind(this));
+ }.bind(this));
+ }.bind(this)).fail(function (error) {
+ uiAlert({
+ content: error
});
- }.bind(this)
- },
- buttons: [{
- text: $t('Cancel'),
- class: 'action-secondary action-dismiss',
+ });
+ }.bind(this)
+ },
+ buttons: [{
+ text: $t('Cancel'),
+ class: 'action-secondary action-dismiss',
- /**
- * Close modal
- */
- click: function () {
- this.closeModal();
- }
- }, {
- text: $t('Confirm'),
- class: 'action-primary action-accept'
- }]
- });
- }.bind(this));
+ /**
+ * Close modal
+ */
+ click: function () {
+ this.closeModal();
+ }
+ }, {
+ text: $t('Confirm'),
+ class: 'action-primary action-accept'
+ }]
+ });
},
/**
@@ -101,11 +108,11 @@ define([
* @returns {String}
*/
getNewFolderPath: function (folderName) {
- var selectedFolder = _.isUndefined(this.selectedFolder()) ||
- _.isNull(this.selectedFolder()) ? '/' : this.selectedFolder(),
- folderToCreate = selectedFolder !== '/' ? selectedFolder + '/' + folderName : folderName;
+ if (_.isUndefined(this.selectedFolder()) || _.isNull(this.selectedFolder())) {
+ return folderName;
+ }
- return folderToCreate;
+ return this.selectedFolder() + '/' + folderName;
},
/**
@@ -136,7 +143,7 @@ define([
/**
* Confirmation popup for delete folder action.
*/
- getConfirmationPopupDeleteFolder: function () {
+ deleteFolder: function () {
confirm({
title: $t('Are you sure you want to delete this folder?'),
modalClass: 'delete-folder-confirmation-popup',
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directoryTree.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directoryTree.js
index decc337e1b83c..2e1e9a980cd59 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directoryTree.js
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/directory/directoryTree.js
@@ -20,13 +20,15 @@ define([
filterChipsProvider: 'componentType = filters, ns = ${ $.ns }',
directoryTreeSelector: '#media-gallery-directory-tree',
getDirectoryTreeUrl: 'media_gallery/directories/gettree',
+ createDirectoryUrl: 'media_gallery/directories/create',
+ deleteDirectoryUrl: 'media_gallery/directories/delete',
jsTreeReloaded: null,
modules: {
directories: '${ $.name }_directories',
filterChips: '${ $.filterChipsProvider }'
},
listens: {
- '${ $.provider }:params.filters.path': 'clearFiltersHandle'
+ '${ $.provider }:params.filters.path': 'updateSelectedDirectory'
},
viewConfig: [{
component: 'Magento_MediaGalleryUi/js/directory/directories',
@@ -49,7 +51,8 @@ define([
this.renderDirectoryTree().then(function () {
this.initEvents();
}.bind(this));
- }.bind(this));
+ }.bind(this)
+ );
return this;
},
@@ -58,7 +61,6 @@ define([
* Render directory tree component.
*/
renderDirectoryTree: function () {
-
return this.getJsonTree().then(function (data) {
this.createFolderIfNotExists(data).then(function (isFolderCreated) {
if (isFolderCreated) {
@@ -87,37 +89,37 @@ define([
* @param {Array} directories
*/
createFolderIfNotExists: function (directories) {
- var isMediaBrowser = !_.isUndefined(window.MediabrowserUtility),
- currentTreePath = isMediaBrowser ? window.MediabrowserUtility.pathId : null,
+ var requestedDirectory = this.getRequestedDirectory(),
deferred = $.Deferred(),
- decodedPath,
pathArray;
- if (currentTreePath) {
- decodedPath = Base64.idDecode(currentTreePath);
-
- if (!this.isDirectoryExist(directories[0], decodedPath)) {
- pathArray = this.convertPathToPathsArray(decodedPath);
+ if (_.isNull(requestedDirectory)) {
+ deferred.resolve(false);
- $.each(pathArray, function (i, val) {
- if (this.isDirectoryExist(directories[0], val)) {
- pathArray.splice(i, 1);
- }
- }.bind(this));
+ return deferred.promise();
+ }
- createDirectory(
- this.createDirectoryUrl,
- pathArray
- ).then(function () {
- deferred.resolve(true);
- });
- } else {
- deferred.resolve(false);
- }
- } else {
+ if (this.isDirectoryExist(directories[0], requestedDirectory)) {
deferred.resolve(false);
+
+ return deferred.promise();
}
+ pathArray = this.convertPathToPathsArray(requestedDirectory);
+
+ $.each(pathArray, function (i, val) {
+ if (this.isDirectoryExist(directories[0], val)) {
+ pathArray.splice(i, 1);
+ }
+ }.bind(this));
+
+ createDirectory(
+ this.createDirectoryUrl,
+ pathArray
+ ).then(function () {
+ deferred.resolve(true);
+ });
+
return deferred.promise();
},
@@ -199,7 +201,7 @@ define([
/**
* Remove ability to multiple select on nodes
*/
- overrideMultiselectBehavior: function () {
+ disableMultiselectBehavior: function () {
$.jstree.defaults.ui['select_range_modifier'] = false;
$.jstree.defaults.ui['select_multiple_modifier'] = false;
},
@@ -208,8 +210,8 @@ define([
* Handle jstree events
*/
initEvents: function () {
- this.firejsTreeEvents();
- this.overrideMultiselectBehavior();
+ this.initJsTreeEvents();
+ this.disableMultiselectBehavior();
$(window).on('reload.MediaGallery', function () {
this.getJsonTree().then(function (data) {
@@ -217,10 +219,10 @@ define([
if (isCreated) {
this.renderDirectoryTree().then(function () {
this.setJsTreeReloaded(true);
- this.firejsTreeEvents();
+ this.initJsTreeEvents();
}.bind(this));
} else {
- this.checkChipFiltersState();
+ this.updateSelectedDirectory();
}
}.bind(this));
}.bind(this));
@@ -230,30 +232,33 @@ define([
/**
* Fire event for jstree component
*/
- firejsTreeEvents: function () {
+ initJsTreeEvents: function () {
$(this.directoryTreeSelector).on('select_node.jstree', function (element, data) {
- var path = $(data.rslt.obj).data('path');
-
- this.setActiveNodeFilter(path);
+ this.setActiveNodeFilter($(data.rslt.obj).data('path'));
this.setJsTreeReloaded(false);
}.bind(this));
$(this.directoryTreeSelector).on('loaded.jstree', function () {
- this.checkChipFiltersState();
+ this.updateSelectedDirectory();
}.bind(this));
-
},
/**
* Verify directory filter on init event, select folder per directory filter state
*/
- checkChipFiltersState: function () {
+ updateSelectedDirectory: function () {
var currentFilterPath = this.filterChips().filters.path,
- isMediaBrowser = !_.isUndefined(window.MediabrowserUtility),
+ requestedDirectory = this.getRequestedDirectory(),
currentTreePath;
- currentTreePath = this.isFiltersApplied(currentFilterPath) || !isMediaBrowser ? currentFilterPath :
- Base64.idDecode(window.MediabrowserUtility.pathId);
+ if (_.isUndefined(currentFilterPath)) {
+ this.clearFiltersHandle();
+
+ return;
+ }
+
+ currentTreePath = this.isFilterApplied(currentFilterPath) || _.isNull(requestedDirectory) ?
+ currentFilterPath : requestedDirectory;
if (this.folderExistsInTree(currentTreePath)) {
this.locateNode(currentTreePath);
@@ -275,14 +280,23 @@ define([
return false;
},
+ /**
+ * Get requested directory from MediabrowserUtility
+ *
+ * @returns {String|null}
+ */
+ getRequestedDirectory: function () {
+ return !_.isUndefined(window.MediabrowserUtility) && window.MediabrowserUtility.pathId !== '' ?
+ Base64.idDecode(window.MediabrowserUtility.pathId) : null;
+ },
+
/**
* Check if need to select directory by filters state
*
* @param {String} currentFilterPath
*/
- isFiltersApplied: function (currentFilterPath) {
- return !_.isUndefined(currentFilterPath) && currentFilterPath !== '' &&
- currentFilterPath !== 'wysiwyg' && currentFilterPath !== 'catalog/category';
+ isFilterApplied: function (currentFilterPath) {
+ return !_.isUndefined(currentFilterPath) && currentFilterPath !== '';
},
/**
@@ -291,9 +305,7 @@ define([
* @param {String} path
*/
locateNode: function (path) {
- var selectedId = $(this.directoryTreeSelector).jstree('get_selected').attr('id');
-
- if (path === selectedId) {
+ if (path === $(this.directoryTreeSelector).jstree('get_selected').attr('id')) {
return;
}
path = path.replace(/\//g, '\\/');
@@ -303,14 +315,12 @@ define([
},
/**
- * Listener to clear filters event
+ * Clear filters
*/
clearFiltersHandle: function () {
- if (_.isUndefined(this.filterChips().filters.path)) {
- $(this.directoryTreeSelector).jstree('deselect_all');
- this.activeNode(null);
- this.directories().setInActive();
- }
+ $(this.directoryTreeSelector).jstree('deselect_all');
+ this.activeNode(null);
+ this.directories().setInActive();
},
/**
@@ -319,7 +329,6 @@ define([
* @param {String} nodePath
*/
setActiveNodeFilter: function (nodePath) {
-
if (this.activeNode() === nodePath && !this.jsTreeReloaded) {
this.selectStorageRoot();
} else {
@@ -341,14 +350,13 @@ define([
this.filterChips().set('applied', filters);
this.activeNode(null);
this.waitForCondition(
- function () {
- return _.isUndefined(this.directories());
- }.bind(this),
function () {
- this.directories().setInActive();
- }.bind(this)
- );
-
+ return _.isUndefined(this.directories());
+ }.bind(this),
+ function () {
+ this.directories().setInActive();
+ }.bind(this)
+ );
},
/**
@@ -372,8 +380,8 @@ define([
},
/**
- * Remove active node from directory tree, and select next
- */
+ * Remove active node from directory tree, and select next
+ */
removeNode: function () {
$(this.directoryTreeSelector).jstree('remove');
},
@@ -390,7 +398,6 @@ define([
filters = $.extend(true, filters, applied);
filters.path = path;
this.filterChips().set('applied', filters);
-
},
/**
diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/massaction/massactions.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/massaction/massactions.js
index 4f09854005f23..03e82e65b5db5 100644
--- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/massaction/massactions.js
+++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/massaction/massactions.js
@@ -141,10 +141,8 @@ define([
if (response.status === 'canceled') {
return;
}
- this.imageModel().selected({});
- this.massActionMode(false);
- this.switchMode();
- }.bind(this));
+ $(window).trigger('terminateMassAction.MediaGallery');
+ });
}
}.bind(this));
}
diff --git a/app/code/Magento/MessageQueue/etc/di.xml b/app/code/Magento/MessageQueue/etc/di.xml
index f60eb5fbc20df..b283280dc4580 100644
--- a/app/code/Magento/MessageQueue/etc/di.xml
+++ b/app/code/Magento/MessageQueue/etc/di.xml
@@ -6,7 +6,6 @@
*/
-->
-
diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php
index 49212202b5f62..8845395be406e 100644
--- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php
+++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php
@@ -695,7 +695,7 @@ protected function _prepareOrder(\Magento\Quote\Model\Quote\Address $address)
);
$shippingMethodCode = $address->getShippingMethod();
- if (isset($shippingMethodCode) && !empty($shippingMethodCode)) {
+ if ($shippingMethodCode) {
$rate = $address->getShippingRateByCode($shippingMethodCode);
$shippingPrice = $rate->getPrice();
} else {
@@ -975,7 +975,8 @@ public function getMinimumAmountError()
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}
- return $error;
+
+ return __($error);
}
/**
diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontRemoveProductOnCheckoutActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontRemoveProductOnCheckoutActionGroup.xml
new file mode 100644
index 0000000000000..af0f3e2d597b8
--- /dev/null
+++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontRemoveProductOnCheckoutActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml
index db037d50f7dc6..9c89ffa3cd405 100644
--- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml
+++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml
@@ -14,5 +14,6 @@
+
diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithWithVirtualProductTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithWithVirtualProductTest.xml
new file mode 100644
index 0000000000000..632950120474d
--- /dev/null
+++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithWithVirtualProductTest.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Multishipping/etc/config.xml b/app/code/Magento/Multishipping/etc/config.xml
index aee4199ed4757..0df8742016aed 100644
--- a/app/code/Magento/Multishipping/etc/config.xml
+++ b/app/code/Magento/Multishipping/etc/config.xml
@@ -13,5 +13,10 @@
100
+
+
+ The current cart does not match multi shipping criteria, please review or contact the store administrator
+
+
diff --git a/app/code/Magento/Multishipping/i18n/en_US.csv b/app/code/Magento/Multishipping/i18n/en_US.csv
index 0c248bdcc1af3..430b16b8cc237 100644
--- a/app/code/Magento/Multishipping/i18n/en_US.csv
+++ b/app/code/Magento/Multishipping/i18n/en_US.csv
@@ -92,3 +92,4 @@ Options,Options
"Error:","Error:"
"We are unable to process your request. Please, try again later.","We are unable to process your request. Please, try again later."
"Quote address for failed order ID "%1" not found.","Quote address for failed order ID "%1" not found."
+"The current cart does not match multi shipping criteria, please review or contact the store administrator","The current cart does not match multi shipping criteria, please review or contact the store administrator"
diff --git a/app/code/Magento/Newsletter/Model/SubscriptionManager.php b/app/code/Magento/Newsletter/Model/SubscriptionManager.php
index 846d095625e0c..57c6cd8b843a7 100644
--- a/app/code/Magento/Newsletter/Model/SubscriptionManager.php
+++ b/app/code/Magento/Newsletter/Model/SubscriptionManager.php
@@ -195,12 +195,14 @@ private function saveSubscriber(
): bool {
$statusChanged = (int)$subscriber->getStatus() !== $status;
$emailChanged = $subscriber->getEmail() !== $customer->getEmail();
- if ($subscriber->getId()
- && !$statusChanged
- && (int)$subscriber->getCustomerId() === (int)$customer->getId()
- && (int)$subscriber->getStoreId() === $storeId
- && !$emailChanged
- ) {
+ if ($this->dontNeedToSaveSubscriber(
+ $subscriber,
+ $customer,
+ $statusChanged,
+ $storeId,
+ $status,
+ $emailChanged
+ )) {
return false;
}
@@ -220,10 +222,37 @@ private function saveSubscriber(
/**
* If the subscriber is waiting to confirm from the customer
- * and customer changed the email
+ * or customer changed the email
* than need to send confirmation letter to the new email
*/
- return $status === Subscriber::STATUS_NOT_ACTIVE && $emailChanged;
+ return $status === Subscriber::STATUS_NOT_ACTIVE || $emailChanged;
+ }
+
+ /**
+ * Don't need to save subscriber model
+ *
+ * @param Subscriber $subscriber
+ * @param CustomerInterface $customer
+ * @param bool $statusChanged
+ * @param int $storeId
+ * @param int $status
+ * @param bool $emailChanged
+ * @return bool
+ */
+ private function dontNeedToSaveSubscriber(
+ Subscriber $subscriber,
+ CustomerInterface $customer,
+ bool $statusChanged,
+ int $storeId,
+ int $status,
+ bool $emailChanged
+ ): bool {
+ return $subscriber->getId()
+ && !$statusChanged
+ && (int)$subscriber->getCustomerId() === (int)$customer->getId()
+ && (int)$subscriber->getStoreId() === $storeId
+ && !$emailChanged
+ && $status !== Subscriber::STATUS_NOT_ACTIVE;
}
/**
diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriptionManagerTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriptionManagerTest.php
index 4e1f18a26a95a..6139d86191f44 100644
--- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriptionManagerTest.php
+++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriptionManagerTest.php
@@ -454,7 +454,7 @@ public function subscribeCustomerDataProvider(): array
'subscriber_status' => Subscriber::STATUS_SUBSCRIBED,
'subscriber_confirm_code' => '',
],
- 'needToSendEmail' => false,
+ 'needToSendEmail' => true,
],
'Update subscription data: subscription confirm required ' => [
'subscriber_data' => [
@@ -618,7 +618,7 @@ public function unsubscribeCustomerDataProvider(): array
'subscriber_status' => Subscriber::STATUS_NOT_ACTIVE,
'subscriber_confirm_code' => '',
],
- 'needToSendEmail' => false,
+ 'needToSendEmail' => true,
],
'Update subscription data' => [
'subscriber_data' => [
@@ -642,7 +642,7 @@ public function unsubscribeCustomerDataProvider(): array
'subscriber_status' => Subscriber::STATUS_UNSUBSCRIBED,
'subscriber_confirm_code' => '',
],
- 'needToSendEmail' => false,
+ 'needToSendEmail' => true,
],
];
}
diff --git a/app/code/Magento/PageCache/Plugin/AppendNoStoreCacheHeader.php b/app/code/Magento/PageCache/Plugin/AppendNoStoreCacheHeader.php
new file mode 100644
index 0000000000000..fc18855a51710
--- /dev/null
+++ b/app/code/Magento/PageCache/Plugin/AppendNoStoreCacheHeader.php
@@ -0,0 +1,30 @@
+setHeader('Cache-Control', 'no-store');
+ return $response;
+ }
+}
diff --git a/app/code/Magento/PageCache/etc/webapi_rest/di.xml b/app/code/Magento/PageCache/etc/webapi_rest/di.xml
new file mode 100644
index 0000000000000..04906a615a9df
--- /dev/null
+++ b/app/code/Magento/PageCache/etc/webapi_rest/di.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/PageCache/etc/webapi_soap/di.xml b/app/code/Magento/PageCache/etc/webapi_soap/di.xml
new file mode 100644
index 0000000000000..04906a615a9df
--- /dev/null
+++ b/app/code/Magento/PageCache/etc/webapi_soap/di.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml
index 6f4073bf70f46..127fd1dd4e006 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml
@@ -97,8 +97,7 @@
-
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml
index d8a9effa56dac..701b7ebe4a958 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml
@@ -58,8 +58,7 @@
-
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedConfigurableProductOnOrderPageTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedConfigurableProductOnOrderPageTest.xml
index c635e6b0ad6b2..8e9e117d2d995 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedConfigurableProductOnOrderPageTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedConfigurableProductOnOrderPageTest.xml
@@ -96,8 +96,7 @@
-
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedSimpleProductOnOrderPageTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedSimpleProductOnOrderPageTest.xml
index eb28ebfd068da..71da699e533bc 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedSimpleProductOnOrderPageTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/MoveLastOrderedSimpleProductOnOrderPageTest.xml
@@ -46,8 +46,7 @@
-
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedBundleFixedProductOnOrderPageTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedBundleFixedProductOnOrderPageTest.xml
index c3fc7a4952143..452d65ea5ae57 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedBundleFixedProductOnOrderPageTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedBundleFixedProductOnOrderPageTest.xml
@@ -96,8 +96,7 @@
-
-
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedConfigurableProductOnOrderPageTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedConfigurableProductOnOrderPageTest.xml
index 0e021600ab3e3..4d1ebddc7c2b3 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedConfigurableProductOnOrderPageTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/MoveRecentlyViewedConfigurableProductOnOrderPageTest.xml
@@ -99,8 +99,7 @@
-
-
+
diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php
index f15349f11066d..a924805fcba90 100644
--- a/app/code/Magento/Store/Block/Switcher.php
+++ b/app/code/Magento/Store/Block/Switcher.php
@@ -170,9 +170,15 @@ public function getGroups()
if ($store) {
$group->setHomeUrl($store->getHomeUrl());
+ $group->setSortOrder($store->getSortOrder());
$groups[] = $group;
}
}
+
+ usort($groups, static function ($itemA, $itemB) {
+ return (int)$itemA->getSortOrder() <=> (int)$itemB->getSortOrder();
+ });
+
$this->setData('groups', $groups);
}
return $this->getData('groups');
@@ -193,7 +199,12 @@ public function getStores()
$stores = [];
} else {
$stores = $rawStores[$groupId];
+
+ uasort($stores, static function ($itemA, $itemB) {
+ return (int)$itemA->getSortOrder() <=> (int)$itemB->getSortOrder();
+ });
}
+
$this->setData('stores', $stores);
}
return $this->getData('stores');
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCheckStoreViewOptionsActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCheckStoreViewOptionsActionGroup.xml
new file mode 100644
index 0000000000000..ba96633a621c2
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCheckStoreViewOptionsActionGroup.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Goes to the Catalog->Product filters and check store view options at the Store View dropdown
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewFillSortOrderActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewFillSortOrderActionGroup.xml
new file mode 100644
index 0000000000000..1b9b147209c66
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewFillSortOrderActionGroup.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ Fill 'Sort Order' field
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
index bdb1842cf2959..39664ae10a07d 100644
--- a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
@@ -206,4 +206,23 @@
store
add
+
+
+ sameNameStoreView
+ storeViewCode
+ 1
+ null
+ add
+ store
+ customStoreGroup
+
+
+ sameNameStoreView
+ storeViewCode
+ 1
+ null
+ add
+ store
+ customStoreGroup
+
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection/AdminStoresGridSection.xml
index e56836c491276..cd7f180d0bb0e 100644
--- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection/AdminStoresGridSection.xml
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection/AdminStoresGridSection.xml
@@ -22,5 +22,6 @@
+
diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateDuplicateNameStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateDuplicateNameStoreViewTest.xml
new file mode 100644
index 0000000000000..ec81424b1acfa
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateDuplicateNameStoreViewTest.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Test/StorefrontCheckSortOrderStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/StorefrontCheckSortOrderStoreViewTest.xml
new file mode 100644
index 0000000000000..442ee99e12793
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Test/StorefrontCheckSortOrderStoreViewTest.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{SecondStoreGroupUnique.name}}
+ $grabSwatchFirstOption
+
+
+ {{customStoreGroup.name}}
+ $grabSwatchSecondOption
+
+
+
diff --git a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
index 9106da8ffb177..60c69834f6aa6 100644
--- a/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
+++ b/app/code/Magento/Store/Test/Unit/Block/SwitcherTest.php
@@ -7,91 +7,159 @@
namespace Magento\Store\Test\Unit\Block;
+use Magento\Directory\Helper\Data;
+use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Data\Helper\PostHelper;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Block\Switcher;
+use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
+use Magento\Store\Model\Website;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
class SwitcherTest extends TestCase
{
- /** @var Switcher */
- protected $switcher;
-
- /** @var Context|MockObject */
- protected $context;
+ /**
+ * @var Switcher
+ */
+ private $switcher;
- /** @var PostHelper|MockObject */
- protected $corePostDataHelper;
+ /**
+ * @var PostHelper|MockObject
+ */
+ private $corePostDataHelperMock;
- /** @var StoreManagerInterface|MockObject */
- protected $storeManager;
+ /**
+ * @var StoreManagerInterface|MockObject
+ */
+ private $storeManagerMock;
- /** @var UrlInterface|MockObject */
- protected $urlBuilder;
+ /**
+ * @var UrlInterface|MockObject
+ */
+ private $urlBuilderMock;
- /** @var StoreInterface|MockObject */
- private $store;
+ /**
+ * @var ScopeConfigInterface|MockObject
+ */
+ private $scopeConfigMock;
/**
* @return void
*/
protected function setUp(): void
{
- $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
- ->getMock();
- $this->urlBuilder = $this->getMockForAbstractClass(UrlInterface::class);
- $this->context = $this->createMock(Context::class);
- $this->context->expects($this->any())->method('getStoreManager')->willReturn($this->storeManager);
- $this->context->expects($this->any())->method('getUrlBuilder')->willReturn($this->urlBuilder);
- $this->corePostDataHelper = $this->createMock(PostHelper::class);
- $this->store = $this->getMockBuilder(StoreInterface::class)
- ->disableOriginalConstructor()
- ->getMockForAbstractClass();
+ $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)->getMock();
+ $this->urlBuilderMock = $this->createMock(UrlInterface::class);
+ $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class);
+ $contextMock = $this->createMock(Context::class);
+ $contextMock->method('getStoreManager')->willReturn($this->storeManagerMock);
+ $contextMock->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
+ $contextMock->method('getScopeConfig')->willReturn($this->scopeConfigMock);
+ $this->corePostDataHelperMock = $this->createMock(PostHelper::class);
$this->switcher = (new ObjectManager($this))->getObject(
Switcher::class,
[
- 'context' => $this->context,
- 'postDataHelper' => $this->corePostDataHelper,
+ 'context' => $contextMock,
+ 'postDataHelper' => $this->corePostDataHelperMock,
]
);
}
+ public function testGetStoresSortOrder()
+ {
+ $groupId = 1;
+ $storesSortOrder = [
+ 1 => 2,
+ 2 => 4,
+ 3 => 1,
+ 4 => 3
+ ];
+
+ $currentStoreMock = $this->getMockBuilder(Store::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $currentStoreMock->method('getGroupId')->willReturn($groupId);
+ $currentStoreMock->method('isUseStoreInUrl')->willReturn(false);
+ $this->storeManagerMock->method('getStore')
+ ->willReturn($currentStoreMock);
+
+ $currentWebsiteMock = $this->getMockBuilder(Website::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storeManagerMock->method('getWebsite')
+ ->willReturn($currentWebsiteMock);
+
+ $stores = [];
+ foreach ($storesSortOrder as $storeId => $sortOrder) {
+ $storeMock = $this->getMockBuilder(Store::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getId', 'getGroupId', 'getSortOrder', 'isActive', 'getUrl'])
+ ->getMock();
+ $storeMock->method('getId')->willReturn($storeId);
+ $storeMock->method('getGroupId')->willReturn($groupId);
+ $storeMock->method('getSortOrder')->willReturn($sortOrder);
+ $storeMock->method('isActive')->willReturn(true);
+ $storeMock->method('getUrl')->willReturn('https://example.org');
+ $stores[] = $storeMock;
+ }
+
+ $scopeConfigMap = array_map(static function ($item) {
+ return [
+ Data::XML_PATH_DEFAULT_LOCALE,
+ ScopeInterface::SCOPE_STORE,
+ $item,
+ 'en_US'
+ ];
+ }, $stores);
+ $this->scopeConfigMock->method('getValue')
+ ->willReturnMap($scopeConfigMap);
+
+ $currentWebsiteMock->method('getStores')
+ ->willReturn($stores);
+
+ $this->assertEquals([3, 1, 4, 2], array_keys($this->switcher->getStores()));
+ }
+
/**
* @return void
*/
public function testGetTargetStorePostData()
{
- $store = $this->getMockBuilder(Store::class)
+ $storeMock = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->getMock();
- $store->expects($this->any())
- ->method('getCode')
+ $oldStoreMock = $this->getMockBuilder(StoreInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+ $storeMock->method('getCode')
->willReturn('new-store');
$storeSwitchUrl = 'http://domain.com/stores/store/redirect';
- $store->expects($this->atLeastOnce())
+ $storeMock->expects($this->atLeastOnce())
->method('getCurrentUrl')
->with(false)
->willReturn($storeSwitchUrl);
- $this->storeManager->expects($this->once())
+ $this->storeManagerMock->expects($this->once())
->method('getStore')
- ->willReturn($this->store);
- $this->store->expects($this->once())
+ ->willReturn($oldStoreMock);
+ $oldStoreMock->expects($this->once())
->method('getCode')
->willReturn('old-store');
- $this->urlBuilder->expects($this->once())
+ $this->urlBuilderMock->expects($this->once())
->method('getUrl')
->willReturn($storeSwitchUrl);
- $this->corePostDataHelper->expects($this->any())
- ->method('getPostData')
+ $this->corePostDataHelperMock->method('getPostData')
->with($storeSwitchUrl, ['___store' => 'new-store', 'uenc' => null, '___from_store' => 'old-store']);
- $this->switcher->getTargetStorePostData($store);
+ $this->switcher->getTargetStorePostData($storeMock);
}
/**
@@ -104,7 +172,7 @@ public function testIsStoreInUrl($isUseStoreInUrl)
$storeMock->expects($this->once())->method('isUseStoreInUrl')->willReturn($isUseStoreInUrl);
- $this->storeManager->expects($this->any())->method('getStore')->willReturn($storeMock);
+ $this->storeManagerMock->method('getStore')->willReturn($storeMock);
$this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
// check value is cached
$this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
@@ -114,7 +182,7 @@ public function testIsStoreInUrl($isUseStoreInUrl)
* @see self::testIsStoreInUrlDataProvider()
* @return array
*/
- public function isStoreInUrlDataProvider()
+ public function isStoreInUrlDataProvider(): array
{
return [[true], [false]];
}
diff --git a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
index 907eb74e20fa2..f8aa09cb20a61 100644
--- a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
+++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php
@@ -10,7 +10,7 @@
use Magento\Store\Model\System\Store as SystemStore;
/**
- * Class Options
+ * Ui stores options
*/
class Options implements OptionSourceInterface
{
@@ -93,37 +93,38 @@ protected function sanitizeName($name)
*
* @return void
*/
- protected function generateCurrentOptions()
+ protected function generateCurrentOptions(): void
{
$websiteCollection = $this->systemStore->getWebsiteCollection();
$groupCollection = $this->systemStore->getGroupCollection();
$storeCollection = $this->systemStore->getStoreCollection();
- /** @var \Magento\Store\Model\Website $website */
+
foreach ($websiteCollection as $website) {
$groups = [];
- /** @var \Magento\Store\Model\Group $group */
foreach ($groupCollection as $group) {
- if ($group->getWebsiteId() == $website->getId()) {
+ if ($group->getWebsiteId() === $website->getId()) {
$stores = [];
- /** @var \Magento\Store\Model\Store $store */
foreach ($storeCollection as $store) {
- if ($store->getGroupId() == $group->getId()) {
- $name = $this->sanitizeName($store->getName());
- $stores[$name]['label'] = str_repeat(' ', 8) . $name;
- $stores[$name]['value'] = $store->getId();
+ if ($store->getGroupId() === $group->getId()) {
+ $stores[] = [
+ 'label' => str_repeat(' ', 8) . $this->sanitizeName($store->getName()),
+ 'value' => $store->getId(),
+ ];
}
}
if (!empty($stores)) {
- $name = $this->sanitizeName($group->getName());
- $groups[$name]['label'] = str_repeat(' ', 4) . $name;
- $groups[$name]['value'] = array_values($stores);
+ $groups[] = [
+ 'label' => str_repeat(' ', 4) . $this->sanitizeName($group->getName()),
+ 'value' => array_values($stores),
+ ];
}
}
}
if (!empty($groups)) {
- $name = $this->sanitizeName($website->getName());
- $this->currentOptions[$name]['label'] = $name;
- $this->currentOptions[$name]['value'] = array_values($groups);
+ $this->currentOptions[] = [
+ 'label' => $this->sanitizeName($website->getName()),
+ 'value' => array_values($groups),
+ ];
}
}
}
diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSetUpWatermarkForSwatchImageTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSetUpWatermarkForSwatchImageTest.xml
index d56572afd8847..07ce30b702f91 100644
--- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSetUpWatermarkForSwatchImageTest.xml
+++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSetUpWatermarkForSwatchImageTest.xml
@@ -38,8 +38,7 @@
-
-
+
diff --git a/app/code/Magento/Translation/view/frontend/requirejs-config.js b/app/code/Magento/Translation/view/frontend/requirejs-config.js
index b4b3ce0f8c554..9a99d49eddbcf 100644
--- a/app/code/Magento/Translation/view/frontend/requirejs-config.js
+++ b/app/code/Magento/Translation/view/frontend/requirejs-config.js
@@ -10,8 +10,5 @@ var config = {
addClass: 'Magento_Translation/js/add-class',
'Magento_Translation/add-class': 'Magento_Translation/js/add-class'
}
- },
- deps: [
- 'mage/translate-inline'
- ]
+ }
};
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/image-preview.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/image-preview.js
index d675bd7a60ab5..7dcf0994ef56b 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/columns/image-preview.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/image-preview.js
@@ -2,6 +2,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+/* eslint-disable no-undef */
define([
'jquery',
'Magento_Ui/js/grid/columns/column',
@@ -32,7 +33,8 @@ define([
listens: {
'${ $.provider }:params.filters': 'hide',
'${ $.provider }:params.search': 'hide',
- '${ $.provider }:params.paging': 'hide'
+ '${ $.provider }:params.paging': 'hide',
+ '${ $.provider }:data.items': 'updateDisplayedRecord'
},
exports: {
height: '${ $.parentName }.thumbnail_url:previewHeight'
@@ -48,6 +50,25 @@ define([
this._super();
$(document).on('keydown', this.handleKeyDown.bind(this));
+ this.lastOpenedImage.subscribe(function (newValue) {
+
+ if (newValue === false && _.isNull(this.visibleRecord())) {
+ return;
+ }
+
+ if (newValue === this.visibleRecord()) {
+ return;
+ }
+
+ if (newValue === false) {
+ this.hide();
+
+ return;
+ }
+
+ this.show(this.masonry().rows()[newValue]);
+ }.bind(this));
+
return this;
},
@@ -128,8 +149,6 @@ define([
* @param {Object} record
*/
show: function (record) {
- var img;
-
if (record._rowIndex === this.visibleRecord()) {
this.hide();
@@ -141,9 +160,21 @@ define([
this._selectRow(record.rowNumber || null);
this.visibleRecord(record._rowIndex);
- img = $(this.previewImageSelector + ' img');
+ this.lastOpenedImage(record._rowIndex);
+ this.updateImageData();
+ },
- if (img.get(0).complete) {
+ /**
+ * Update image data when image preview is opened
+ */
+ updateImageData: function () {
+ var img = $(this.previewImageSelector + ' img');
+
+ if (!img.get(0)) {
+ setTimeout(function () {
+ this.updateImageData();
+ }.bind(this), 100);
+ } else if (img.get(0).complete) {
this.updateHeight();
this.scrollToPreview();
} else {
@@ -152,8 +183,17 @@ define([
this.scrollToPreview();
}.bind(this));
}
+ },
- this.lastOpenedImage(record._rowIndex);
+ /**
+ * Update preview displayed record data from the new items data if the preview is expanded
+ *
+ * @param {Array} items
+ */
+ updateDisplayedRecord: function (items) {
+ if (!_.isNull(this.visibleRecord())) {
+ this.displayedRecord(items[this.visibleRecord()]);
+ }
},
/**
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js b/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js
index 1f870e9e819a1..be9044143c5a4 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/url-filter-applier.js
@@ -5,8 +5,9 @@
define([
'uiComponent',
- 'underscore'
-], function (Component, _) {
+ 'underscore',
+ 'jquery'
+], function (Component, _, $) {
'use strict';
return Component.extend({
@@ -36,7 +37,9 @@ define([
* Apply filter
*/
apply: function () {
- var urlFilter = this.getFilterParam(this.searchString);
+ var urlFilter = this.getFilterParam(this.searchString),
+ applied,
+ filters;
if (_.isUndefined(this.filterComponent())) {
setTimeout(function () {
@@ -47,8 +50,9 @@ define([
}
if (Object.keys(urlFilter).length) {
- this.filterComponent().setData(urlFilter, false);
- this.filterComponent().apply();
+ applied = this.filterComponent().get('applied');
+ filters = $.extend({}, applied, urlFilter);
+ this.filterComponent().set('applied', filters);
}
},
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Allcart.php b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
index 6300b14dcf515..89413eff8323f 100644
--- a/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
@@ -3,13 +3,24 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+declare(strict_types=1);
+
namespace Magento\Wishlist\Controller\Shared;
+use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
-use Magento\Wishlist\Model\ItemCarrier;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface;
+use Magento\Framework\Controller\Result\Forward;
+use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultFactory;
+use Magento\Wishlist\Model\ItemCarrier;
-class Allcart extends \Magento\Framework\App\Action\Action
+/**
+ * Wishlist Allcart Controller
+ */
+class Allcart extends Action implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* @var WishlistProvider
@@ -17,7 +28,7 @@ class Allcart extends \Magento\Framework\App\Action\Action
protected $wishlistProvider;
/**
- * @var \Magento\Wishlist\Model\ItemCarrier
+ * @var ItemCarrier
*/
protected $itemCarrier;
@@ -39,21 +50,22 @@ public function __construct(
/**
* Add all items from wishlist to shopping cart
*
- * @return \Magento\Framework\Controller\ResultInterface
+ * {@inheritDoc}
*/
public function execute()
{
$wishlist = $this->wishlistProvider->getWishlist();
if (!$wishlist) {
- /** @var \Magento\Framework\Controller\Result\Forward $resultForward */
+ /** @var Forward $resultForward */
$resultForward = $this->resultFactory->create(ResultFactory::TYPE_FORWARD);
$resultForward->forward('noroute');
return $resultForward;
}
$redirectUrl = $this->itemCarrier->moveAllToCart($wishlist, $this->getRequest()->getParam('qty'));
- /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+ /** @var Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setUrl($redirectUrl);
+
return $resultRedirect;
}
}
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Cart.php b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
index c0a394ce9d762..939cbe3a2c46f 100644
--- a/app/code/Magento/Wishlist/Controller/Shared/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
@@ -13,7 +13,7 @@
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context as ActionContext;
use Magento\Framework\App\Action\HttpPostActionInterface;
-use Magento\Framework\Controller\Result\Redirect;
+use Magento\Framework\Controller\Result\Redirect as ResultRedirect;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Escaper;
use Magento\Framework\Exception\LocalizedException;
@@ -124,9 +124,11 @@ public function execute()
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, __('We can\'t add the item to the cart right now.'));
}
- /** @var Redirect $resultRedirect */
+
+ /** @var ResultRedirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setUrl($redirectUrl);
+
return $resultRedirect;
}
}
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
index eea3346e8e81b..d9339af8144f4 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/AllcartTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
declare(strict_types=1);
namespace Magento\Wishlist\Test\Unit\Controller\Shared;
@@ -20,83 +21,60 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+/**
+ * Test for \Magento\Wishlist\Controller\Shared\Allcart.
+ */
class AllcartTest extends TestCase
{
/**
* @var Allcart
*/
- protected $allcartController;
-
- /**
- * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
- */
- protected $objectManagerHelper;
-
- /**
- * @var Context
- */
- protected $context;
+ private $allcartController;
/**
* @var WishlistProvider|MockObject
*/
- protected $wishlistProviderMock;
+ private $wishlistProviderMock;
/**
* @var ItemCarrier|MockObject
*/
- protected $itemCarrierMock;
+ private $itemCarrierMock;
/**
* @var Wishlist|MockObject
*/
- protected $wishlistMock;
+ private $wishlistMock;
/**
* @var Http|MockObject
*/
- protected $requestMock;
-
- /**
- * @var ResultFactory|MockObject
- */
- protected $resultFactoryMock;
+ private $requestMock;
/**
* @var Redirect|MockObject
*/
- protected $resultRedirectMock;
+ private $resultRedirectMock;
/**
* @var Forward|MockObject
*/
- protected $resultForwardMock;
+ private $resultForwardMock;
+ /**
+ * @inheritDoc
+ */
protected function setUp(): void
{
- $this->wishlistProviderMock = $this->getMockBuilder(WishlistProvider::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->itemCarrierMock = $this->getMockBuilder(ItemCarrier::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->wishlistMock = $this->getMockBuilder(Wishlist::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->requestMock = $this->getMockBuilder(Http::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->resultFactoryMock = $this->getMockBuilder(ResultFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->resultRedirectMock = $this->getMockBuilder(Redirect::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->resultForwardMock = $this->getMockBuilder(Forward::class)
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->resultFactoryMock->expects($this->any())
+ $this->wishlistProviderMock = $this->createMock(WishlistProvider::class);
+ $this->itemCarrierMock = $this->createMock(ItemCarrier::class);
+ $this->wishlistMock = $this->createMock(Wishlist::class);
+ $this->requestMock = $this->createMock(Http::class);
+ $resultFactoryMock = $this->createMock(ResultFactory::class);
+ $this->resultRedirectMock = $this->createMock(Redirect::class);
+ $this->resultForwardMock = $this->createMock(Forward::class);
+
+ $resultFactoryMock->expects($this->any())
->method('create')
->willReturnMap(
[
@@ -105,18 +83,18 @@ protected function setUp(): void
]
);
- $this->objectManagerHelper = new ObjectManagerHelper($this);
- $this->context = $this->objectManagerHelper->getObject(
+ $objectManagerHelper = new ObjectManagerHelper($this);
+ $context = $objectManagerHelper->getObject(
Context::class,
[
'request' => $this->requestMock,
- 'resultFactory' => $this->resultFactoryMock
+ 'resultFactory' => $resultFactoryMock
]
);
- $this->allcartController = $this->objectManagerHelper->getObject(
+ $this->allcartController = $objectManagerHelper->getObject(
Allcart::class,
[
- 'context' => $this->context,
+ 'context' => $context,
'wishlistProvider' => $this->wishlistProviderMock,
'itemCarrier' => $this->itemCarrierMock
]
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/CartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/CartTest.php
index 923b33ef4748b..e6a127457a6c6 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/CartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Shared/CartTest.php
@@ -8,6 +8,7 @@
namespace Magento\Wishlist\Test\Unit\Controller\Shared;
use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Exception;
use Magento\Checkout\Helper\Cart as CartHelper;
use Magento\Checkout\Model\Cart;
use Magento\Framework\App\Action\Context as ActionContext;
@@ -29,156 +30,146 @@
use PHPUnit\Framework\TestCase;
/**
+ * Test for \Magento\Wishlist\Controller\Shared\Cart.
+ *
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CartTest extends TestCase
{
- /** @var SharedCart|MockObject */
- protected $model;
-
- /** @var RequestInterface|MockObject */
- protected $request;
-
- /** @var ManagerInterface|MockObject */
- protected $messageManager;
-
- /** @var ActionContext|MockObject */
- protected $context;
-
- /** @var Cart|MockObject */
- protected $cart;
+ /**
+ * @var SharedCart|MockObject
+ */
+ private $model;
- /** @var CartHelper|MockObject */
- protected $cartHelper;
+ /**
+ * @var RequestInterface|MockObject
+ */
+ private $request;
- /** @var Quote|MockObject */
- protected $quote;
+ /**
+ * @var ManagerInterface|MockObject
+ */
+ private $messageManager;
- /** @var OptionCollection|MockObject */
- protected $optionCollection;
+ /**
+ * @var Cart|MockObject
+ */
+ private $cart;
- /** @var OptionFactory|MockObject */
- protected $optionFactory;
+ /**
+ * @var CartHelper|MockObject
+ */
+ private $cartHelper;
- /** @var Option|MockObject */
- protected $option;
+ /**
+ * @var Quote|MockObject
+ */
+ private $quote;
- /** @var ItemFactory|MockObject */
- protected $itemFactory;
+ /**
+ * @var OptionCollection|MockObject
+ */
+ private $optionCollection;
- /** @var Item|MockObject */
- protected $item;
+ /**
+ * @var Option|MockObject
+ */
+ private $option;
- /** @var Escaper|MockObject */
- protected $escaper;
+ /**
+ * @var Item|MockObject
+ */
+ private $item;
- /** @var RedirectInterface|MockObject */
- protected $redirect;
+ /**
+ * @var Escaper|MockObject
+ */
+ private $escaper;
- /** @var ResultFactory|MockObject */
- protected $resultFactory;
+ /**
+ * @var RedirectInterface|MockObject
+ */
+ private $redirect;
- /** @var Redirect|MockObject */
- protected $resultRedirect;
+ /**
+ * @var Redirect|MockObject
+ */
+ private $resultRedirect;
- /** @var Product|MockObject */
- protected $product;
+ /**
+ * @var Product|MockObject
+ */
+ private $product;
+ /**
+ * @inheritDoc
+ */
protected function setUp(): void
{
- $this->request = $this->getMockBuilder(RequestInterface::class)
- ->getMockForAbstractClass();
-
- $this->redirect = $this->getMockBuilder(RedirectInterface::class)
- ->getMockForAbstractClass();
-
- $this->messageManager = $this->getMockBuilder(ManagerInterface::class)
- ->getMockForAbstractClass();
-
- $this->resultRedirect = $this->getMockBuilder(Redirect::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->request = $this->getMockForAbstractClass(RequestInterface::class);
+ $this->redirect = $this->getMockForAbstractClass(RedirectInterface::class);
+ $this->messageManager = $this->getMockForAbstractClass(ManagerInterface::class);
+ $this->resultRedirect = $this->createMock(Redirect::class);
- $this->resultFactory = $this->getMockBuilder(ResultFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->resultFactory->expects($this->once())
+ $resultFactory = $this->createMock(ResultFactory::class);
+ $resultFactory->expects($this->once())
->method('create')
->with(ResultFactory::TYPE_REDIRECT)
->willReturn($this->resultRedirect);
- $this->context = $this->getMockBuilder(\Magento\Framework\App\Action\Context::class)
+ /** @var ActionContext|MockObject $context */
+ $context = $this->getMockBuilder(ActionContext::class)
->disableOriginalConstructor()
->getMock();
- $this->context->expects($this->any())
+ $context->expects($this->any())
->method('getRequest')
->willReturn($this->request);
- $this->context->expects($this->any())
+ $context->expects($this->any())
->method('getRedirect')
->willReturn($this->redirect);
- $this->context->expects($this->any())
+ $context->expects($this->any())
->method('getMessageManager')
->willReturn($this->messageManager);
- $this->context->expects($this->any())
+ $context->expects($this->any())
->method('getResultFactory')
- ->willReturn($this->resultFactory);
-
- $this->cart = $this->getMockBuilder(\Magento\Checkout\Model\Cart::class)
- ->disableOriginalConstructor()
- ->getMock();
+ ->willReturn($resultFactory);
- $this->cartHelper = $this->getMockBuilder(\Magento\Checkout\Helper\Cart::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->cart = $this->createMock(Cart::class);
+ $this->cartHelper = $this->createMock(CartHelper::class);
$this->quote = $this->getMockBuilder(Quote::class)
->disableOriginalConstructor()
- ->setMethods(['getHasError'])
+ ->addMethods(['getHasError'])
->getMock();
- $this->optionCollection = $this->getMockBuilder(
- \Magento\Wishlist\Model\ResourceModel\Item\Option\Collection::class
- )->disableOriginalConstructor()
- ->getMock();
+ $this->optionCollection = $this->createMock(OptionCollection::class);
$this->option = $this->getMockBuilder(Option::class)
->disableOriginalConstructor()
->getMock();
- $this->optionFactory = $this->getMockBuilder(OptionFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->optionFactory->expects($this->once())
+ /** @var OptionFactory|MockObject $optionFactory */
+ $optionFactory = $this->createMock(OptionFactory::class);
+ $optionFactory->expects($this->once())
->method('create')
->willReturn($this->option);
- $this->item = $this->getMockBuilder(Item::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->item = $this->createMock(Item::class);
- $this->itemFactory = $this->getMockBuilder(ItemFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->itemFactory->expects($this->once())
+ $itemFactory = $this->createMock(ItemFactory::class);
+ $itemFactory->expects($this->once())
->method('create')
->willReturn($this->item);
- $this->escaper = $this->getMockBuilder(Escaper::class)
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->product = $this->getMockBuilder(Product::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->escaper = $this->createMock(Escaper::class);
+ $this->product = $this->createMock(Product::class);
$this->model = new SharedCart(
- $this->context,
+ $context,
$this->cart,
- $this->optionFactory,
- $this->itemFactory,
+ $optionFactory,
+ $itemFactory,
$this->cartHelper,
$this->escaper
);
@@ -358,7 +349,7 @@ public function testExecuteProductException()
$this->option->expects($this->once())
->method('getCollection')
- ->willThrowException(new \Magento\Catalog\Model\Product\Exception(__('LocalizedException')));
+ ->willThrowException(new Exception(__('LocalizedException')));
$this->resultRedirect->expects($this->once())
->method('setUrl')
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php
index 3489585cd17d7..840c4638614c4 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/AddProductsToWishlist.php
@@ -83,7 +83,7 @@ public function resolve(
array $args = null
) {
if (!$this->wishlistConfig->isEnabled()) {
- throw new GraphQlInputException(__('The wishlist is not currently available.'));
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
}
$customerId = $context->getUserId();
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php
index cad574ef56ed2..b73afe27883dd 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlistResolver.php
@@ -54,7 +54,7 @@ public function resolve(
array $args = null
) {
if (!$this->wishlistConfig->isEnabled()) {
- throw new GraphQlInputException(__('The wishlist is not currently available.'));
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
}
if (false === $context->getExtensionAttributes()->getIsCustomer()) {
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlists.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlists.php
new file mode 100644
index 0000000000000..ad0c73691720a
--- /dev/null
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/CustomerWishlists.php
@@ -0,0 +1,102 @@
+wishlistDataMapper = $wishlistDataMapper;
+ $this->wishlistConfig = $wishlistConfig;
+ $this->wishlistCollectionFactory = $wishlistCollectionFactory;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!$this->wishlistConfig->isEnabled()) {
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
+ }
+
+ $customerId = $context->getUserId();
+
+ if (null === $customerId || 0 === $customerId) {
+ throw new GraphQlAuthorizationException(
+ __('The current user cannot perform operations on wishlist')
+ );
+ }
+
+ $currentPage = $args['currentPage'] ?? 1;
+ $pageSize = $args['pageSize'] ?? 20;
+
+ /** @var WishlistCollection $collection */
+ $collection = $this->wishlistCollectionFactory->create();
+ $collection->filterByCustomerId($customerId);
+
+ if ($currentPage > 0) {
+ $collection->setCurPage($currentPage);
+ }
+
+ if ($pageSize > 0) {
+ $collection->setPageSize($pageSize);
+ }
+
+ $wishlists = [];
+
+ /** @var Wishlist $wishList */
+ foreach ($collection->getItems() as $wishList) {
+ array_push($wishlists, $this->wishlistDataMapper->map($wishList));
+ }
+
+ return $wishlists;
+ }
+}
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php
index 65c8498fc89ad..31dd33ff2cd79 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php
@@ -7,12 +7,12 @@
namespace Magento\WishlistGraphQl\Model\Resolver;
+use Magento\Catalog\Model\Product;
use Magento\CatalogGraphQl\Model\ProductDataProvider;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
-use Magento\Wishlist\Model\Item;
/**
* Fetches the Product data according to the GraphQL schema
@@ -45,9 +45,9 @@ public function resolve(
if (!isset($value['model'])) {
throw new LocalizedException(__('Missing key "model" in Wishlist Item value data'));
}
- /** @var Item $wishlistItem */
- $wishlistItem = $value['model'];
+ /** @var Product $product */
+ $product = $value['model'];
- return $this->productDataProvider->getProductDataById((int)$wishlistItem->getProductId());
+ return $this->productDataProvider->getProductDataById((int) $product->getId());
}
}
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php
index a59c5ccdb0f70..66a6c7b86ea37 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/RemoveProductsFromWishlist.php
@@ -83,7 +83,7 @@ public function resolve(
array $args = null
) {
if (!$this->wishlistConfig->isEnabled()) {
- throw new GraphQlInputException(__('The wishlist is not currently available.'));
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
}
$customerId = $context->getUserId();
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/Type/WishlistItemType.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/Type/WishlistItemType.php
new file mode 100644
index 0000000000000..ae4a6ed2b6a64
--- /dev/null
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/Type/WishlistItemType.php
@@ -0,0 +1,59 @@
+supportedTypes = $supportedTypes;
+ }
+
+ /**
+ * Resolving wishlist item type
+ *
+ * @param array $data
+ *
+ * @return string
+ *
+ * @throws LocalizedException
+ */
+ public function resolveType(array $data): string
+ {
+ if (!$data['model'] instanceof ProductInterface) {
+ throw new LocalizedException(__('"model" should be a "%instance" instance', [
+ 'instance' => ProductInterface::class
+ ]));
+ }
+
+ $productTypeId = $data['model']->getTypeId();
+
+ if (!isset($this->supportedTypes[$productTypeId])) {
+ throw new LocalizedException(
+ __('Product "%product_type" type is not supported', ['product_type' => $productTypeId])
+ );
+ }
+
+ return $this->supportedTypes[$productTypeId];
+ }
+}
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php
index c6ede66fc2b1b..47a408d55555b 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php
@@ -83,7 +83,7 @@ public function resolve(
array $args = null
) {
if (!$this->wishlistConfig->isEnabled()) {
- throw new GraphQlInputException(__('The wishlist is not currently available.'));
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
}
$customerId = $context->getUserId();
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistById.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistById.php
new file mode 100644
index 0000000000000..1ddf91637fe90
--- /dev/null
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistById.php
@@ -0,0 +1,115 @@
+wishlistResource = $wishlistResource;
+ $this->wishlistFactory = $wishlistFactory;
+ $this->wishlistDataMapper = $wishlistDataMapper;
+ $this->wishlistConfig = $wishlistConfig;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!$this->wishlistConfig->isEnabled()) {
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
+ }
+
+ $customerId = $context->getUserId();
+
+ if (null === $customerId || 0 === $customerId) {
+ throw new GraphQlAuthorizationException(
+ __('The current user cannot perform operations on wishlist')
+ );
+ }
+
+ $wishlist = $this->getWishlist((int) $args['id'], $customerId);
+
+ if (null === $wishlist->getId() || (int) $wishlist->getCustomerId() !== $customerId) {
+ return [];
+ }
+
+ return $this->wishlistDataMapper->map($wishlist);
+ }
+
+ /**
+ * Get wishlist
+ *
+ * @param int $wishlistId
+ * @param int $customerId
+ *
+ * @return Wishlist
+ */
+ private function getWishlist(int $wishlistId, int $customerId): Wishlist
+ {
+ $wishlist = $this->wishlistFactory->create();
+
+ if ($wishlistId > 0) {
+ $this->wishlistResource->load($wishlist, $wishlistId);
+ } else {
+ $this->wishlistResource->load($wishlist, $customerId, 'customer_id');
+ }
+
+ return $wishlist;
+ }
+}
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItems.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItems.php
new file mode 100644
index 0000000000000..77ff483a60bd2
--- /dev/null
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItems.php
@@ -0,0 +1,98 @@
+wishlistItemCollectionFactory = $wishlistItemCollectionFactory;
+ $this->storeManager = $storeManager;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!isset($value['model'])) {
+ throw new LocalizedException(__('Missing key "model" in Wishlist value data'));
+ }
+ /** @var Wishlist $wishlist */
+ $wishlist = $value['model'];
+
+ $wishlistItems = $this->getWishListItems($wishlist);
+
+ $data = [];
+ foreach ($wishlistItems as $wishlistItem) {
+ $data[] = [
+ 'id' => $wishlistItem->getId(),
+ 'quantity' => $wishlistItem->getData('qty'),
+ 'description' => $wishlistItem->getDescription(),
+ 'added_at' => $wishlistItem->getAddedAt(),
+ 'model' => $wishlistItem->getProduct(),
+ 'itemModel' => $wishlistItem,
+ ];
+ }
+ return $data;
+ }
+
+ /**
+ * Get wishlist items
+ *
+ * @param Wishlist $wishlist
+ * @return Item[]
+ */
+ private function getWishListItems(Wishlist $wishlist): array
+ {
+ /** @var WishlistItemCollection $wishlistItemCollection */
+ $wishlistItemCollection = $this->wishlistItemCollectionFactory->create();
+ $wishlistItemCollection
+ ->addWishlistFilter($wishlist)
+ ->addStoreFilter(array_map(function (StoreInterface $store) {
+ return $store->getId();
+ }, $this->storeManager->getStores()))
+ ->setVisibilityFilter();
+ return $wishlistItemCollection->getItems();
+ }
+}
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php
index dfbbf6543f66f..36a03da2b79a9 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php
@@ -70,7 +70,7 @@ public function resolve(
'qty' => $wishlistItem->getData('qty'),
'description' => $wishlistItem->getDescription(),
'added_at' => $wishlistItem->getAddedAt(),
- 'model' => $wishlistItem,
+ 'model' => $wishlistItem->getProduct(),
];
}
return $data;
diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php
index 09c0a8a935a6c..f31b403a514fb 100644
--- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php
+++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php
@@ -63,7 +63,7 @@ public function resolve(
array $args = null
) {
if (!$this->wishlistConfig->isEnabled()) {
- throw new GraphQlInputException(__('The wishlist is not currently available.'));
+ throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
}
$customerId = $context->getUserId();
diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json
index 7a3fca599a4b3..58bc738bd24d6 100644
--- a/app/code/Magento/WishlistGraphQl/composer.json
+++ b/app/code/Magento/WishlistGraphQl/composer.json
@@ -5,6 +5,7 @@
"require": {
"php": "~7.3.0||~7.4.0",
"magento/framework": "*",
+ "magento/module-catalog": "*",
"magento/module-catalog-graph-ql": "*",
"magento/module-wishlist": "*",
"magento/module-store": "*"
diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls
index 430e77cc45e96..69bc45462d4c8 100644
--- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls
@@ -6,7 +6,12 @@ type Query {
}
type Customer {
- wishlist: Wishlist! @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "Contains the contents of a customer's wish lists") @cache(cacheable: false)
+ wishlists(
+ pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."),
+ currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1.")
+ ): [Wishlist!]! @doc(description: "An array of wishlists. In Magento Open Source, customers are limited to one wish list. The number of wish lists is configurable for Magento Commerce") @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlists")
+ wishlist: Wishlist! @deprecated(reason: "Use `Customer.wishlists` or `Customer.wishlist_v2`") @resolver(class:"\\Magento\\WishlistGraphQl\\Model\\Resolver\\CustomerWishlistResolver") @doc(description: "Contains a customer's wish lists") @cache(cacheable: false)
+ wishlist_v2(id: ID!): Wishlist @doc(description: "Retrieve the specified wish list") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistById")
}
type WishlistOutput @doc(description: "Deprecated: `Wishlist` type should be used instead") {
@@ -19,12 +24,22 @@ type WishlistOutput @doc(description: "Deprecated: `Wishlist` type should be use
type Wishlist {
id: ID @doc(description: "Wishlist unique identifier")
- items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "An array of items in the customer's wish list"),
- items_count: Int @doc(description: "The number of items in the wish list"),
- sharing_code: String @doc(description: "An encrypted code that Magento uses to link to the wish list"),
+ items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @deprecated(reason: "Use field `items_v2` from type `Wishlist` instead")
+ items_v2: [WishlistItemInterface] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItems") @doc(description: "An array of items in the customer's wish list")
+ items_count: Int @doc(description: "The number of items in the wish list")
+ sharing_code: String @doc(description: "An encrypted code that Magento uses to link to the wish list")
updated_at: String @doc(description: "The time of the last modification to the wish list")
}
+interface WishlistItemInterface @typeResolver(class: "Magento\\WishlistGraphQl\\Model\\Resolver\\Type\\WishlistItemType") {
+ id: ID! @doc(description: "The ID of the wish list item")
+ quantity: Float! @doc(description: "The quantity of this wish list item")
+ description: String @doc(description: "The description of the item")
+ added_at: String! @doc(description: "The date and time the item was added to the wish list")
+ product: ProductInterface @doc(description: "Product details of the wish list item") @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver")
+ customizable_options: [SelectedCustomizableOption] @doc(description: "Custom options selected for the wish list item")
+}
+
type WishlistItem {
id: Int @doc(description: "The wish list item ID")
qty: Float @doc(description: "The quantity of this wish list item"),
diff --git a/app/design/frontend/Magento/blank/web/css/source/_extends.less b/app/design/frontend/Magento/blank/web/css/source/_extends.less
index 5bdaa4c3c35a3..690b89f42b419 100644
--- a/app/design/frontend/Magento/blank/web/css/source/_extends.less
+++ b/app/design/frontend/Magento/blank/web/css/source/_extends.less
@@ -1110,7 +1110,7 @@
.abs-shopping-cart-items {
.action {
&.continue {
- border-radius: 3px;
+ border-radius: @button__border-radius;
font-weight: @font-weight__bold;
.lib-link-as-button();
.lib-button(
diff --git a/app/design/frontend/Magento/blank/web/css/source/_typography.less b/app/design/frontend/Magento/blank/web/css/source/_typography.less
index 6807c0f692af8..02ccd90d4655d 100644
--- a/app/design/frontend/Magento/blank/web/css/source/_typography.less
+++ b/app/design/frontend/Magento/blank/web/css/source/_typography.less
@@ -9,7 +9,7 @@
& when (@media-common = true) {
.lib-font-face(
- @family-name: @font-family-name__base,
+ @family-name: 'Open Sans',
@font-path: '@{baseDir}fonts/opensans/light/opensans-300',
@font-weight: 300,
@font-style: normal,
@@ -17,7 +17,7 @@
);
.lib-font-face(
- @family-name: @font-family-name__base,
+ @family-name: 'Open Sans',
@font-path: '@{baseDir}fonts/opensans/regular/opensans-400',
@font-weight: 400,
@font-style: normal,
@@ -25,7 +25,7 @@
);
.lib-font-face(
- @family-name: @font-family-name__base,
+ @family-name: 'Open Sans',
@font-path: '@{baseDir}fonts/opensans/semibold/opensans-600',
@font-weight: 600,
@font-style: normal,
@@ -33,7 +33,7 @@
);
.lib-font-face(
- @family-name: @font-family-name__base,
+ @family-name: 'Open Sans',
@font-path: '@{baseDir}fonts/opensans/bold/opensans-700',
@font-weight: 700,
@font-style: normal,
diff --git a/app/etc/di.xml b/app/etc/di.xml
index fed2e336046f9..585c88f68ff6f 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -185,6 +185,7 @@
+
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php
index a81ec701b22a8..b97cd379e4384 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddBundleProductToWishlistTest.php
@@ -16,6 +16,7 @@
use Magento\Integration\Api\CustomerTokenServiceInterface;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\GraphQlAbstract;
+use Magento\Ui\Component\Form\Element\Select;
use Magento\Wishlist\Model\Item;
use Magento\Wishlist\Model\WishlistFactory;
@@ -74,7 +75,7 @@ public function testAddBundleProductWithOptions(): void
$selection = $typeInstance->getSelectionsCollection([$option->getId()], $product)->getFirstItem();
$optionId = $option->getId();
$selectionId = $selection->getSelectionId();
- $bundleOptions = $this->generateBundleOptionIdV2((int) $optionId, (int) $selectionId, $optionQty);
+ $bundleOptions = $this->generateBundleOptionUid((int) $optionId, (int) $selectionId, $optionQty);
$query = $this->getQuery($sku, $qty, $bundleOptions);
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
@@ -88,9 +89,13 @@ public function testAddBundleProductWithOptions(): void
$this->assertEquals($wishlist->getItemsCount(), $response['items_count']);
$this->assertEquals($wishlist->getSharingCode(), $response['sharing_code']);
$this->assertEquals($wishlist->getUpdatedAt(), $response['updated_at']);
- $this->assertEquals($item->getData('qty'), $response['items'][0]['qty']);
- $this->assertEquals($item->getDescription(), $response['items'][0]['description']);
- $this->assertEquals($item->getAddedAt(), $response['items'][0]['added_at']);
+ $this->assertEquals($item->getData('qty'), $response['items_v2'][0]['quantity']);
+ $this->assertEquals($item->getDescription(), $response['items_v2'][0]['description']);
+ $this->assertEquals($item->getAddedAt(), $response['items_v2'][0]['added_at']);
+ $this->assertNotEmpty($response['items_v2'][0]['bundle_options']);
+ $bundleOptions = $response['items_v2'][0]['bundle_options'];
+ $this->assertEquals('Bundle Product Items', $bundleOptions[0]['label']);
+ $this->assertEquals(Select::NAME, $bundleOptions[0]['type']);
}
/**
@@ -149,11 +154,24 @@ private function getQuery(
sharing_code
items_count
updated_at
- items {
+ items_v2 {
id
description
- qty
+ quantity
added_at
+ ... on BundleWishlistItem {
+ bundle_options {
+ id
+ label
+ type
+ values {
+ id
+ label
+ quantity
+ price
+ }
+ }
+ }
}
}
}
@@ -169,7 +187,7 @@ private function getQuery(
*
* @return string
*/
- private function generateBundleOptionIdV2(int $optionId, int $selectionId, int $quantity): string
+ private function generateBundleOptionUid(int $optionId, int $selectionId, int $quantity): string
{
return base64_encode("bundle/$optionId/$selectionId/$quantity");
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php
index d8d44541f899d..cffc5eb6f93c1 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddConfigurableProductToWishlistTest.php
@@ -48,7 +48,7 @@ protected function setUp(): void
*
* @throws Exception
*/
- public function testAddDownloadableProductWithOptions(): void
+ public function testAddConfigurableProductWithOptions(): void
{
$product = $this->getConfigurableProductInfo();
$customerId = 1;
@@ -57,7 +57,7 @@ public function testAddDownloadableProductWithOptions(): void
$valueIndex = $product['configurable_options'][0]['values'][0]['value_index'];
$childSku = $product['variants'][0]['product']['sku'];
$parentSku = $product['sku'];
- $selectedConfigurableOptionsQuery = $this->generateSuperAttributesIdV2Query($attributeId, $valueIndex);
+ $selectedConfigurableOptionsQuery = $this->generateSuperAttributesUidQuery($attributeId, $valueIndex);
$query = $this->getQuery($parentSku, $childSku, $qty, $selectedConfigurableOptionsQuery);
@@ -66,16 +66,19 @@ public function testAddDownloadableProductWithOptions(): void
/** @var Item $wishlistItem */
$wishlistItem = $wishlist->getItemCollection()->getFirstItem();
- self::assertArrayHasKey('addProductsToWishlist', $response);
- self::assertArrayHasKey('wishlist', $response['addProductsToWishlist']);
+ $this->assertArrayHasKey('addProductsToWishlist', $response);
+ $this->assertArrayHasKey('wishlist', $response['addProductsToWishlist']);
$wishlistResponse = $response['addProductsToWishlist']['wishlist'];
- self::assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']);
- self::assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']);
- self::assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']);
- self::assertEquals($wishlistItem->getId(), $wishlistResponse['items'][0]['id']);
- self::assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items'][0]['qty']);
- self::assertEquals($wishlistItem->getDescription(), $wishlistResponse['items'][0]['description']);
- self::assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items'][0]['added_at']);
+ $this->assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']);
+ $this->assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']);
+ $this->assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']);
+ $this->assertEquals($wishlistItem->getId(), $wishlistResponse['items_v2'][0]['id']);
+ $this->assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items_v2'][0]['quantity']);
+ $this->assertEquals($wishlistItem->getDescription(), $wishlistResponse['items_v2'][0]['description']);
+ $this->assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items_v2'][0]['added_at']);
+ $this->assertNotEmpty($wishlistResponse['items_v2'][0]['configurable_options']);
+ $configurableOptions = $wishlistResponse['items_v2'][0]['configurable_options'];
+ $this->assertEquals('Test Configurable', $configurableOptions[0]['option_label']);
}
/**
@@ -135,11 +138,20 @@ private function getQuery(
sharing_code
items_count
updated_at
- items {
+ items_v2 {
id
description
- qty
+ quantity
added_at
+ ... on ConfigurableWishlistItem {
+ child_sku
+ configurable_options {
+ id
+ option_label
+ value_id
+ value_label
+ }
+ }
}
}
}
@@ -148,14 +160,14 @@ private function getQuery(
}
/**
- * Generates Id_v2 for super configurable product super attributes
+ * Generates uid for super configurable product super attributes
*
* @param int $attributeId
* @param int $valueIndex
*
* @return string
*/
- private function generateSuperAttributesIdV2Query(int $attributeId, int $valueIndex): string
+ private function generateSuperAttributesUidQuery(int $attributeId, int $valueIndex): string
{
return 'selected_options: ["' . base64_encode("configurable/$attributeId/$valueIndex") . '"]';
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php
index 489a960056f1b..0de45fb21b20b 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/AddDownloadableProductToWishlistTest.php
@@ -37,9 +37,9 @@ class AddDownloadableProductToWishlistTest extends GraphQlAbstract
private $wishlistFactory;
/**
- * @var GetCustomOptionsWithIDV2ForQueryBySku
+ * @var GetCustomOptionsWithUidForQueryBySku
*/
- private $getCustomOptionsWithIDV2ForQueryBySku;
+ private $getCustomOptionsWithUidForQueryBySku;
/**
* Set Up
@@ -49,69 +49,75 @@ protected function setUp(): void
$this->objectManager = Bootstrap::getObjectManager();
$this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class);
$this->wishlistFactory = $this->objectManager->get(WishlistFactory::class);
- $this->getCustomOptionsWithIDV2ForQueryBySku =
- $this->objectManager->get(GetCustomOptionsWithIDV2ForQueryBySku::class);
+ $this->getCustomOptionsWithUidForQueryBySku =
+ $this->objectManager->get(GetCustomOptionsWithUidForQueryBySku::class);
}
/**
- * @magentoConfigFixture default_store wishlist/general/active 1
+ * @magentoConfigFixture default_store wishlist/general/active 0
* @magentoApiDataFixture Magento/Customer/_files/customer.php
* @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php
*/
- public function testAddDownloadableProductWithOptions(): void
+ public function testAddDownloadableProductOnDisabledWishlist(): void
{
- $customerId = 1;
- $sku = 'downloadable-product-with-purchased-separately-links';
$qty = 2;
+ $sku = 'downloadable-product-with-purchased-separately-links';
$links = $this->getProductsLinks($sku);
$linkId = key($links);
- $itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku);
+ $itemOptions = $this->getCustomOptionsWithUidForQueryBySku->execute($sku);
$itemOptions['selected_options'][] = $this->generateProductLinkSelectedOptions($linkId);
- $productOptionsQuery = preg_replace(
+ $productOptionsQuery = trim(preg_replace(
'/"([^"]+)"\s*:\s*/',
'$1:',
json_encode($itemOptions)
- );
- $query = $this->getQuery($qty, $sku, trim($productOptionsQuery, '{}'));
- $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
- $wishlist = $this->wishlistFactory->create();
- $wishlist->loadByCustomerId($customerId, true);
- /** @var Item $wishlistItem */
- $wishlistItem = $wishlist->getItemCollection()->getFirstItem();
-
- self::assertArrayHasKey('addProductsToWishlist', $response);
- self::assertArrayHasKey('wishlist', $response['addProductsToWishlist']);
- $wishlistResponse = $response['addProductsToWishlist']['wishlist'];
- self::assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']);
- self::assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']);
- self::assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']);
- self::assertEquals($wishlistItem->getId(), $wishlistResponse['items'][0]['id']);
- self::assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items'][0]['qty']);
- self::assertEquals($wishlistItem->getDescription(), $wishlistResponse['items'][0]['description']);
- self::assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items'][0]['added_at']);
+ ), '{}');
+ $query = $this->getQuery($qty, $sku, $productOptionsQuery);
+ $this->expectExceptionMessage('The wishlist configuration is currently disabled.');
+ $this->graphQlMutation($query, [], '', $this->getHeaderMap());
}
/**
- * @magentoConfigFixture default_store wishlist/general/active 0
+ * @magentoConfigFixture default_store wishlist/general/active 1
* @magentoApiDataFixture Magento/Customer/_files/customer.php
* @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_custom_options.php
*/
- public function testAddDownloadableProductOnDisabledWishlist(): void
+ public function testAddDownloadableProductWithOptions(): void
{
- $qty = 2;
+ $customerId = 1;
$sku = 'downloadable-product-with-purchased-separately-links';
+ $qty = 2;
$links = $this->getProductsLinks($sku);
$linkId = key($links);
- $itemOptions = $this->getCustomOptionsWithIDV2ForQueryBySku->execute($sku);
+ $itemOptions = $this->getCustomOptionsWithUidForQueryBySku->execute($sku);
$itemOptions['selected_options'][] = $this->generateProductLinkSelectedOptions($linkId);
- $productOptionsQuery = trim(preg_replace(
+ $productOptionsQuery = preg_replace(
'/"([^"]+)"\s*:\s*/',
'$1:',
json_encode($itemOptions)
- ), '{}');
- $query = $this->getQuery($qty, $sku, $productOptionsQuery);
- $this->expectExceptionMessage('The wishlist is not currently available.');
- $this->graphQlMutation($query, [], '', $this->getHeaderMap());
+ );
+ $query = $this->getQuery($qty, $sku, trim($productOptionsQuery, '{}'));
+ $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
+ $wishlist = $this->wishlistFactory->create();
+ $wishlist->loadByCustomerId($customerId, true);
+ /** @var Item $wishlistItem */
+ $wishlistItem = $wishlist->getItemCollection()->getFirstItem();
+
+ $this->assertArrayHasKey('addProductsToWishlist', $response);
+ $this->assertArrayHasKey('wishlist', $response['addProductsToWishlist']);
+ $wishlistResponse = $response['addProductsToWishlist']['wishlist'];
+ $this->assertEquals($wishlist->getItemsCount(), $wishlistResponse['items_count']);
+ $this->assertEquals($wishlist->getSharingCode(), $wishlistResponse['sharing_code']);
+ $this->assertEquals($wishlist->getUpdatedAt(), $wishlistResponse['updated_at']);
+ $this->assertEquals($wishlistItem->getId(), $wishlistResponse['items_v2'][0]['id']);
+ $this->assertEquals($wishlistItem->getData('qty'), $wishlistResponse['items_v2'][0]['quantity']);
+ $this->assertEquals($wishlistItem->getDescription(), $wishlistResponse['items_v2'][0]['description']);
+ $this->assertEquals($wishlistItem->getAddedAt(), $wishlistResponse['items_v2'][0]['added_at']);
+ $this->assertNotEmpty($wishlistResponse['items_v2'][0]['links_v2']);
+ $wishlistItemLinks = $wishlistResponse['items_v2'][0]['links_v2'];
+ $this->assertEquals('Downloadable Product Link 1', $wishlistItemLinks[0]['title']);
+ $this->assertNotEmpty($wishlistResponse['items_v2'][0]['samples']);
+ $wishlistItemSamples = $wishlistResponse['items_v2'][0]['samples'];
+ $this->assertEquals('Downloadable Product Sample', $wishlistItemSamples[0]['title']);
}
/**
@@ -190,11 +196,23 @@ private function getQuery(
sharing_code
items_count
updated_at
- items {
+ items_v2 {
id
description
- qty
+ quantity
added_at
+ ... on DownloadableWishlistItem {
+ links_v2 {
+ id
+ title
+ sample_url
+ }
+ samples {
+ id
+ title
+ sample_url
+ }
+ }
}
}
}
@@ -203,7 +221,7 @@ private function getQuery(
}
/**
- * Generates Id_v2 for downloadable links
+ * Generates uid for downloadable links
*
* @param int $linkId
*
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php
index 0a8e1757a2ce2..04095c1679d2f 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/CustomerWishlistTest.php
@@ -131,7 +131,7 @@ public function testGuestCannotGetWishlist()
public function testCustomerCannotGetWishlistWhenDisabled()
{
$this->expectException(\Exception::class);
- $this->expectExceptionMessage('The wishlist is not currently available.');
+ $this->expectExceptionMessage('The wishlist configuration is currently disabled.');
$query =
<<customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
+ $this->wishlistCollectionFactory = Bootstrap::getObjectManager()->get(CollectionFactory::class);
+ }
+
+ /**
+ * Test fetching customer wishlist
+ *
+ * @magentoConfigFixture default_store wishlist/general/active 1
+ * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php
+ */
+ public function testCustomerWishlist(): void
+ {
+ $customerId = 1;
+ /** @var Wishlist $wishlist */
+ $collection = $this->wishlistCollectionFactory->create()->filterByCustomerId($customerId);
+ /** @var Item $wishlistItem */
+ $wishlistItem = $collection->getFirstItem();
+ $response = $this->graphQlQuery(
+ $this->getQuery(),
+ [],
+ '',
+ $this->getCustomerAuthHeaders('customer@example.com', 'password')
+ );
+ $this->assertArrayHasKey('wishlists', $response['customer']);
+ $wishlist = $response['customer']['wishlists'][0];
+ $this->assertEquals($wishlistItem->getItemsCount(), $wishlist['items_count']);
+ $this->assertEquals($wishlistItem->getSharingCode(), $wishlist['sharing_code']);
+ $this->assertEquals($wishlistItem->getUpdatedAt(), $wishlist['updated_at']);
+ $wishlistItemResponse = $wishlist['items_v2'][0];
+ $this->assertEquals('simple', $wishlistItemResponse['product']['sku']);
+ }
+
+ /**
+ * Testing fetching the wishlist when wishlist is disabled
+ *
+ * @magentoConfigFixture default_store wishlist/general/active 0
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testCustomerCannotGetWishlistWhenDisabled(): void
+ {
+ $this->expectException(Exception::class);
+ $this->expectExceptionMessage('The wishlist configuration is currently disabled.');
+ $this->graphQlQuery(
+ $this->getQuery(),
+ [],
+ '',
+ $this->getCustomerAuthHeaders('customer@example.com', 'password')
+ );
+ }
+
+ /**
+ * Test wishlist fetching for a guest customer
+ *
+ * @magentoConfigFixture default_store wishlist/general/active 1
+ */
+ public function testGuestCannotGetWishlist(): void
+ {
+ $this->expectException(Exception::class);
+ $this->expectExceptionMessage('The current customer isn\'t authorized.');
+ $this->graphQlQuery($this->getQuery());
+ }
+
+ /**
+ * Returns GraphQl query string
+ *
+ * @return string
+ */
+ private function getQuery(): string
+ {
+ return <<customerTokenService->createCustomerAccessToken($email, $password);
+
+ return ['Authorization' => 'Bearer ' . $customerToken];
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php
index ebe99289b8934..13aaecbc7b733 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/DeleteProductsFromWishlistTest.php
@@ -42,17 +42,17 @@ public function testDeleteWishlistItemFromWishlist(): void
$wishlist = $this->getWishlist();
$wishlistId = $wishlist['customer']['wishlist']['id'];
$wishlist = $wishlist['customer']['wishlist'];
- $wishlistItems = $wishlist['items'];
- self::assertEquals(1, $wishlist['items_count']);
+ $wishlistItems = $wishlist['items_v2'];
+ $this->assertEquals(1, $wishlist['items_count']);
$query = $this->getQuery((int) $wishlistId, (int) $wishlistItems[0]['id']);
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
- self::assertArrayHasKey('removeProductsFromWishlist', $response);
- self::assertArrayHasKey('wishlist', $response['removeProductsFromWishlist']);
+ $this->assertArrayHasKey('removeProductsFromWishlist', $response);
+ $this->assertArrayHasKey('wishlist', $response['removeProductsFromWishlist']);
$wishlistResponse = $response['removeProductsFromWishlist']['wishlist'];
- self::assertEquals(0, $wishlistResponse['items_count']);
- self::assertEmpty($wishlistResponse['items']);
+ $this->assertEquals(0, $wishlistResponse['items_count']);
+ $this->assertEmpty($wishlistResponse['items_v2']);
}
/**
@@ -98,10 +98,10 @@ private function getQuery(
id
sharing_code
items_count
- items {
+ items_v2 {
id
description
- qty
+ quantity
}
}
}
@@ -134,9 +134,9 @@ private function getCustomerWishlistQuery(): string
wishlist {
id
items_count
- items {
+ items_v2 {
id
- qty
+ quantity
description
}
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithIDV2ForQueryBySku.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithUidForQueryBySku.php
similarity index 94%
rename from dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithIDV2ForQueryBySku.php
rename to dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithUidForQueryBySku.php
index fcba7458f317a..4bd0c135f039a 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithIDV2ForQueryBySku.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/GetCustomOptionsWithUidForQueryBySku.php
@@ -10,9 +10,9 @@
use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface;
/**
- * Generate an array with test values for customizable options with encoded id_v2 value
+ * Generate an array with test values for customizable options with encoded uid value
*/
-class GetCustomOptionsWithIDV2ForQueryBySku
+class GetCustomOptionsWithUidForQueryBySku
{
/**
* @var ProductCustomOptionRepositoryInterface
@@ -71,7 +71,7 @@ public function execute(string $sku): array
}
/**
- * Returns id_v2 of the selected custom option
+ * Returns uid of the selected custom option
*
* @param int $optionId
* @param int $optionValueId
@@ -84,7 +84,7 @@ private function encodeSelectedOption(int $optionId, int $optionValueId): string
}
/**
- * Returns id_v2 of the entered custom option
+ * Returns uid of the entered custom option
*
* @param int $optionId
*
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php
index 9a9cd424e54ca..08273e7936640 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateProductsFromWishlistTest.php
@@ -43,18 +43,18 @@ public function testUpdateSimpleProductFromWishlist(): void
$qty = 5;
$description = 'New Description';
$wishlistId = $wishlist['customer']['wishlist']['id'];
- $wishlistItem = $wishlist['customer']['wishlist']['items'][0];
- self::assertNotEquals($description, $wishlistItem['description']);
- self::assertNotEquals($qty, $wishlistItem['qty']);
+ $wishlistItem = $wishlist['customer']['wishlist']['items_v2'][0];
+ $this->assertNotEquals($description, $wishlistItem['description']);
+ $this->assertNotEquals($qty, $wishlistItem['quantity']);
$query = $this->getQuery((int) $wishlistId, (int) $wishlistItem['id'], $qty, $description);
$response = $this->graphQlMutation($query, [], '', $this->getHeaderMap());
- self::assertArrayHasKey('updateProductsInWishlist', $response);
- self::assertArrayHasKey('wishlist', $response['updateProductsInWishlist']);
+ $this->assertArrayHasKey('updateProductsInWishlist', $response);
+ $this->assertArrayHasKey('wishlist', $response['updateProductsInWishlist']);
$wishlistResponse = $response['updateProductsInWishlist']['wishlist'];
- self::assertEquals($qty, $wishlistResponse['items'][0]['qty']);
- self::assertEquals($description, $wishlistResponse['items'][0]['description']);
+ $this->assertEquals($qty, $wishlistResponse['items_v2'][0]['quantity']);
+ $this->assertEquals($description, $wishlistResponse['items_v2'][0]['description']);
}
/**
@@ -110,10 +110,10 @@ private function getQuery(
id
sharing_code
items_count
- items {
+ items_v2 {
id
description
- qty
+ quantity
}
}
}
@@ -146,9 +146,9 @@ private function getCustomerWishlistQuery(): string
wishlist {
id
items_count
- items {
+ items_v2 {
id
- qty
+ quantity
description
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Store/Ui/Component/Listing/Column/Store/OptionsTest.php b/dev/tests/integration/testsuite/Magento/Store/Ui/Component/Listing/Column/Store/OptionsTest.php
new file mode 100644
index 0000000000000..e13c4a427464f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Store/Ui/Component/Listing/Column/Store/OptionsTest.php
@@ -0,0 +1,114 @@
+modelFactory = $objectManager->get(OptionsFactory::class);
+ $this->storeManager = $objectManager->get(StoreManagerInterface::class);
+
+ $this->websiteResource = $objectManager->get(WebsiteResource::class);
+ $this->groupResource = $objectManager->get(GroupResource::class);
+ $this->storeResource = $objectManager->get(StoreResource::class);
+ }
+
+ /**
+ * To option array test with duplicate website, store group, store view names
+ *
+ * @magentoDataFixture Magento/Store/_files/second_website_with_store_group_and_store.php
+ *
+ * @return void
+ */
+ public function testToOptionArray(): void
+ {
+ $website = $this->storeManager->getWebsite('test');
+ $this->websiteResource->save($website->setName(self::DEFAULT_WEBSITE_NAME));
+
+ $storeGroup = current($website->getGroups());
+ $this->groupResource->save($storeGroup->setName(self::DEFAULT_STORE_GROUP_NAME));
+
+ $store = current($website->getStores());
+ $this->storeResource->save($store->setName(self::DEFAULT_STORE_NAME));
+
+ $model = $this->modelFactory->create();
+ $storeIds = [$this->storeManager->getStore('default')->getId(), $store->getId()];
+
+ $this->assertEquals($this->getExpectedOptions($storeIds), $model->toOptionArray());
+ }
+
+ /**
+ * Returns expected options
+ *
+ * @param array $storeIds
+ * @return array
+ */
+ private function getExpectedOptions(array $storeIds): array
+ {
+ $expectedOptions = [];
+ foreach ($storeIds as $storeId) {
+ $expectedOptions[] = [
+ 'label' => self::DEFAULT_WEBSITE_NAME,
+ 'value' => [[
+ 'label' => str_repeat(' ', 4) . self::DEFAULT_STORE_GROUP_NAME,
+ 'value' => [[
+ 'label' => str_repeat(' ', 8) . self::DEFAULT_STORE_NAME,
+ 'value' => $storeId,
+ ]],
+ ]],
+ ];
+ }
+
+ return $expectedOptions;
+ }
+}
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/image-preview.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/image-preview.test.js
index 6a466f0c37872..a5b434d956097 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/image-preview.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/image-preview.test.js
@@ -74,6 +74,7 @@ define([
originMock = $.fn.get;
spyOn($.fn, 'get').and.returnValue(imageMock);
+ imagePreview.lastOpenedImage = jasmine.createSpy().and.returnValue(2);
imagePreview.visibleRecord = jasmine.createSpy().and.returnValue(2);
imagePreview.displayedRecord = ko.observable();
imagePreview.displayedRecord(recordMock);
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/url-filter-applier.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/url-filter-applier.test.js
index a3d49e382de51..1e63f9f61f6d1 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/url-filter-applier.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/url-filter-applier.test.js
@@ -12,7 +12,8 @@ define([
describe('Magento_Ui/js/grid/url-filter-applier', function () {
var urlFilterApplierObj,
filterComponentMock = {
- setData: jasmine.createSpy(),
+ set: jasmine.createSpy(),
+ get: jasmine.createSpy(),
apply: jasmine.createSpy()
};
@@ -64,11 +65,14 @@ define([
it('applies url filter on filter component', function () {
urlFilterApplierObj.searchString = '?filters[name]=test&filters[qty]=1';
urlFilterApplierObj.apply();
- expect(urlFilterApplierObj.filterComponent().setData).toHaveBeenCalledWith({
- 'name': 'test',
- 'qty': '1'
- }, false);
- expect(urlFilterApplierObj.filterComponent().apply).toHaveBeenCalled();
+ expect(urlFilterApplierObj.filterComponent().get).toHaveBeenCalled();
+ expect(urlFilterApplierObj.filterComponent().set).toHaveBeenCalledWith(
+ 'applied',
+ {
+ 'name': 'test',
+ 'qty': '1'
+ }
+ );
});
});
});
diff --git a/lib/internal/Magento/Framework/Registry.php b/lib/internal/Magento/Framework/Registry.php
index e798b28e1e1b2..b5944729fd1a1 100644
--- a/lib/internal/Magento/Framework/Registry.php
+++ b/lib/internal/Magento/Framework/Registry.php
@@ -9,7 +9,7 @@
* Registry model. Used to manage values in registry
*
* Registry usage as a shared service introduces temporal, hard to detect coupling into system.
- * It's usage should be avoid. Use service classes or data providers instead.
+ * Its usage should be avoided. Use service classes or data providers instead.
*
* @api
* @deprecated 102.0.0
diff --git a/lib/web/mage/translate-inline.js b/lib/web/mage/translate-inline.js
index 56acef5a49a42..2407a64e5e0d1 100644
--- a/lib/web/mage/translate-inline.js
+++ b/lib/web/mage/translate-inline.js
@@ -6,9 +6,10 @@
define([
'jquery',
'mage/template',
- 'jquery-ui-modules/dialog',
- 'mage/translate'
-], function ($, mageTemplate) {
+ 'mage/utils/misc',
+ 'mage/translate',
+ 'jquery-ui-modules/dialog'
+], function ($, mageTemplate, miscUtils) {
'use strict';
$.widget('mage.translateInline', $.ui.dialog, {
@@ -59,11 +60,12 @@ define([
* Open.
*/
open: function () {
- var topMargin;
+ var $uiDialog = $(this).closest('.ui-dialog'),
+ topMargin = $uiDialog.children('.ui-dialog-titlebar').outerHeight() + 45;
- $(this).closest('.ui-dialog').addClass('ui-dialog-active');
- topMargin = jQuery(this).closest('.ui-dialog').children('.ui-dialog-titlebar').outerHeight() + 45;
- jQuery(this).closest('.ui-dialog').css('margin-top', topMargin);
+ $uiDialog
+ .addClass('ui-dialog-active')
+ .css('margin-top', topMargin);
},
/**
@@ -79,11 +81,15 @@ define([
* @protected
*/
_create: function () {
+ var $translateArea = $(this.options.translateArea);
+
+ if (!$translateArea.length) {
+ $translateArea = $('body');
+ }
+ $translateArea.on('edit.editTrigger', $.proxy(this._onEdit, this));
+
this.tmpl = mageTemplate(this.options.translateForm.template);
- (this.options.translateArea && $(this.options.translateArea).length ?
- $(this.options.translateArea) :
- this.element.closest('body'))
- .on('edit.editTrigger', $.proxy(this._onEdit, this));
+
this._super();
},
@@ -95,7 +101,7 @@ define([
_prepareContent: function (templateData) {
var data = $.extend({
items: templateData,
- escape: $.mage.escapeHTML
+ escape: miscUtils.escape
}, this.options.translateForm.data);
this.data = data;
@@ -131,12 +137,11 @@ define([
* @protected
*/
_formSubmit: function () {
- var parameters;
+ var parameters = $.param({
+ area: this.options.area
+ }) + '&' + $('#' + this.options.translateForm.data.id).serialize();
this.formIsSubmitted = true;
- parameters = $.param({
- area: this.options.area
- }) + '&' + $('#' + this.options.translateForm.data.id).serialize();
$.ajax({
url: this.options.ajaxUrl,
@@ -162,11 +167,13 @@ define([
* @private
*/
_updatePlaceholder: function (newValue) {
- var target = jQuery(this.target);
+ var $target = $(this.target),
+ translateObject = $target.data('translate')[0];
+
+ translateObject.shown = newValue;
+ translateObject.translated = newValue;
- target.data('translate')[0].shown = newValue;
- target.data('translate')[0].translated = newValue;
- target.html(newValue);
+ $target.html(newValue);
},
/**
@@ -177,20 +184,6 @@ define([
this._super();
}
});
- // @TODO move the "escapeHTML" method into the file with global utility functions
- $.extend(true, $, {
- mage: {
- /**
- * @param {String} str
- * @return {Boolean}
- */
- escapeHTML: function (str) {
- return str ?
- jQuery('').text(str).html().replace(/"/g, '"') :
- false;
- }
- }
- });
return $.mage.translateInline;
});
diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js
index 3829f5ed467e2..b1c0c33324c28 100644
--- a/lib/web/mage/utils/misc.js
+++ b/lib/web/mage/utils/misc.js
@@ -6,8 +6,8 @@
define([
'underscore',
'jquery',
- 'FormData'
-], function (_, $) {
+ 'mage/utils/objects'
+], function (_, $, utils) {
'use strict';
var defaultAttributes,
@@ -120,7 +120,7 @@ define([
*/
submit: function (options, attrs) {
var form = document.createElement('form'),
- data = this.serialize(options.data),
+ data = utils.serialize(options.data),
attributes = _.extend({}, defaultAttributes, attrs || {});
if (!attributes.action) {
@@ -205,11 +205,11 @@ define([
if (type === 'default') {
formData = new FormData();
- _.each(this.serialize(data), function (val, name) {
+ _.each(utils.serialize(data), function (val, name) {
formData.append(name, val);
});
} else if (type === 'simple') {
- formData = this.serialize(data);
+ formData = utils.serialize(data);
}
return formData;
@@ -242,6 +242,16 @@ define([
return data;
},
+ /**
+ * Replaces special characters with their corresponding HTML entities.
+ *
+ * @param {String} string - Text to escape.
+ * @returns {String} Escaped text.
+ */
+ escape: function (string) {
+ return string ? $('').text(string).html().replace(/"/g, '"') : string;
+ },
+
/**
* Replaces symbol codes with their unescaped counterparts.
*
diff --git a/lib/web/mage/utils/objects.js b/lib/web/mage/utils/objects.js
index 83711c43d2d1b..82866c0f2a6ad 100644
--- a/lib/web/mage/utils/objects.js
+++ b/lib/web/mage/utils/objects.js
@@ -5,8 +5,9 @@
define([
'ko',
'jquery',
- 'underscore'
-], function (ko, $, _) {
+ 'underscore',
+ 'mage/utils/strings'
+], function (ko, $, _, stringUtils) {
'use strict';
var primitives = [
@@ -217,7 +218,7 @@ define([
data = this.flatten(data);
_.each(data, function (value, keys) {
- keys = this.serializeName(keys);
+ keys = stringUtils.serializeName(keys);
value = _.isUndefined(value) ? '' : value;
result[keys] = value;
diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php
index e864a81ffcc0e..4a3a02b37a6ab 100644
--- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php
+++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php
@@ -40,7 +40,7 @@ class Session implements ConfigOptionsListInterface
const INPUT_KEY_SESSION_REDIS_SENTINEL_SERVERS = 'session-save-redis-sentinel-servers';
const INPUT_KEY_SESSION_REDIS_SENTINEL_MASTER = 'session-save-redis-sentinel-master';
const INPUT_KEY_SESSION_REDIS_SENTINEL_VERIFY_MASTER = 'session-save-redis-sentinel-verify-master';
- const INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES = 'session-save-redis-sentinel-connect-retires';
+ const INPUT_KEY_SESSION_REDIS_SENTINEL_CONNECT_RETRIES = 'session-save-redis-sentinel-connect-retries';
const CONFIG_PATH_SESSION_REDIS = 'session/redis';
const CONFIG_PATH_SESSION_REDIS_HOST = 'session/redis/host';