diff --git a/app/code/Magento/Analytics/Model/ExportDataHandler.php b/app/code/Magento/Analytics/Model/ExportDataHandler.php index 4dbc316d0901a..dabe6b05ffd71 100644 --- a/app/code/Magento/Analytics/Model/ExportDataHandler.php +++ b/app/code/Magento/Analytics/Model/ExportDataHandler.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Archive; +use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\WriteInterface; @@ -89,8 +90,7 @@ public function __construct( public function prepareExportData() { try { - $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); - + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::TMP); $this->prepareDirectory($tmpDirectory, $this->getTmpFilesDirRelativePath()); $this->reportWriter->write($tmpDirectory, $this->getTmpFilesDirRelativePath()); @@ -106,8 +106,10 @@ public function prepareExportData() $this->cryptographer->encode($tmpDirectory->readFile($this->getArchiveRelativePath())) ); } finally { - $tmpDirectory->delete($this->getTmpFilesDirRelativePath()); - $tmpDirectory->delete($this->getArchiveRelativePath()); + if (isset($tmpDirectory)) { + $tmpDirectory->delete($this->getTmpFilesDirRelativePath()); + $tmpDirectory->delete($this->getArchiveRelativePath()); + } } return true; diff --git a/app/code/Magento/Analytics/README.md b/app/code/Magento/Analytics/README.md index 454ae72d1fd40..a7f7d87b650ea 100644 --- a/app/code/Magento/Analytics/README.md +++ b/app/code/Magento/Analytics/README.md @@ -1,6 +1,6 @@ # Magento_Analytics module -The Magento_Analytics module integrates your Magento instance with the [Magento Business Intelligence (MBI)](https://magento.com/products/business-intelligence) to use [Advanced Reporting](https://devdocs.magento.com/guides/v2.4/advanced-reporting/modules.html) functionality. +The Magento_Analytics module integrates your Magento instance with the [Magento Business Intelligence (MBI)](https://business.adobe.com/products/magento/business-intelligence.html) to use [Advanced Reporting](https://devdocs.magento.com/guides/v2.4/advanced-reporting/modules.html) functionality. The module implements the following functionality: diff --git a/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php b/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php index b3038197b1410..f3c6afdb7ac3a 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php @@ -15,7 +15,7 @@ use Magento\Framework\Archive; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\WriteInterface; -use Magento\Framework\Filesystem\DirectoryList; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -127,7 +127,7 @@ public function testPrepareExportData($isArchiveSourceDirectory) $this->filesystemMock ->expects($this->once()) ->method('getDirectoryWrite') - ->with(DirectoryList::SYS_TMP) + ->with(DirectoryList::TMP) ->willReturn($this->directoryMock); $this->directoryMock ->expects($this->exactly(4)) @@ -228,7 +228,7 @@ public function testPrepareExportDataWithLocalizedException() $this->filesystemMock ->expects($this->once()) ->method('getDirectoryWrite') - ->with(DirectoryList::SYS_TMP) + ->with(DirectoryList::TMP) ->willReturn($this->directoryMock); $this->reportWriterMock ->expects($this->once()) diff --git a/app/code/Magento/Backend/etc/menu.xsd b/app/code/Magento/Backend/etc/menu.xsd index 4b408e8e86a17..349a32abf6931 100644 --- a/app/code/Magento/Backend/etc/menu.xsd +++ b/app/code/Magento/Backend/etc/menu.xsd @@ -85,7 +85,7 @@ - Item id attribute can has only [a-z0-9/_]. Minimal length 3 symbol. Case insensitive. + Item id attribute can have only [a-z0-9/_]. Minimal length 3 characters. Case insensitive. @@ -96,7 +96,7 @@ - Item action attribute can has only [a-zA-Z0-9/_]. Minimal length 3 symbol + Item action attribute can have only [a-zA-Z0-9/_]. Minimal length 3 characters. @@ -107,7 +107,7 @@ - Item title attribute minimal length 3 symbol + Item title attribute minimal length 3 characters. @@ -119,7 +119,7 @@ - Item module attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive. + Item module attribute can have only [a-z0-9_]. Minimal length 3 characters. Case insensitive. @@ -130,7 +130,7 @@ - Item resource attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive. + Item resource attribute can have only [a-z0-9_]. Minimal length 3 characters. Case insensitive. @@ -141,7 +141,7 @@ - Item resource attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive. + Item dependsOnConfig attribute can have only [a-z0-9_]. Minimal length 3 characters. Case insensitive. diff --git a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php index 121ff2a5db9b2..fc56a93d793a6 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php @@ -11,9 +11,9 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface as OptionRepository; use Magento\Catalog\Model\Product\Option; +use Magento\Catalog\Model\ResourceModel\Product\Relation; use Magento\Framework\App\ObjectManager; use Magento\Framework\EntityManager\Operation\ExtensionInterface; -use Magento\Catalog\Model\ResourceModel\Product\Relation; use Magento\Framework\Exception\CouldNotSaveException; /** @@ -26,12 +26,12 @@ class SaveHandler implements ExtensionInterface /** * @var string[] */ - private $compositeProductTypes = ['grouped', 'configurable', 'bundle']; + private array $compositeProductTypes = ['grouped', 'configurable', 'bundle']; /** * @var OptionRepository */ - protected $optionRepository; + protected OptionRepository $optionRepository; /** * @var Relation @@ -44,7 +44,7 @@ class SaveHandler implements ExtensionInterface */ public function __construct( OptionRepository $optionRepository, - ?Relation $relation = null + ?Relation $relation = null ) { $this->optionRepository = $optionRepository; $this->relation = $relation ?: ObjectManager::getInstance()->get(Relation::class); @@ -57,6 +57,7 @@ public function __construct( * @param array $arguments * @return ProductInterface|object * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws CouldNotSaveException */ public function execute($entity, $arguments = []) { @@ -122,12 +123,11 @@ private function processOptionsSaving(array $options, bool $hasChangedSku, Produ private function isProductHasRelations(ProductInterface $product): bool { $result = true; - if (!in_array($product->getId(), $this->compositeProductTypes) + if (!in_array($product->getTypeId(), $this->compositeProductTypes) && $this->relation->getRelationsByChildren([$product->getId()]) ) { $result = false; } - return $result; } } diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml index 6ac8400825b64..3575bf020a87a 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml @@ -86,6 +86,7 @@ $_helper = $block->getData('outputHelper');
getData('viewModel')->getOptionsData($_product); ?> @@ -161,13 +162,4 @@ $_helper = $block->getData('outputHelper'); getChildBlock('toolbar')->setIsBottom(true)->toHtml() ?> - 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 f1ef00daaf527..495c117962fc8 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 @@ -53,6 +53,7 @@ define([ isCustomerLoggedIn: customer.isLoggedIn, forgotPasswordUrl: window.checkoutConfig.forgotPasswordUrl, emailCheckTimeout: 0, + emailInputId: '#customer-email', /** * Initializes regular properties of instance. @@ -108,6 +109,8 @@ define([ checkEmailAvailability: function () { this.validateRequest(); this.isEmailCheckComplete = $.Deferred(); + // Clean up errors on email + $(this.emailInputId).removeClass('mage-error').parent().find('.mage-error').remove(); this.isLoading(true); this.checkRequest = checkEmailAvailability(this.isEmailCheckComplete, this.email()); diff --git a/app/code/Magento/CustomerGraphQl/etc/graphql/events.xml b/app/code/Magento/CustomerGraphQl/etc/graphql/events.xml new file mode 100644 index 0000000000000..ccf3ae9915a99 --- /dev/null +++ b/app/code/Magento/CustomerGraphQl/etc/graphql/events.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/app/code/Magento/Indexer/Console/Command/IndexerResetStateCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerResetStateCommand.php index 75ea1f6b27f66..5cfe0205429fe 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerResetStateCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerResetStateCommand.php @@ -10,6 +10,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Magento\Framework\Indexer\ConfigInterface; +use Magento\Framework\Console\Cli; /** * Command for invalidating indexers. @@ -17,7 +18,7 @@ class IndexerResetStateCommand extends AbstractIndexerManageCommand { /** - * {@inheritdoc} + * Configures the current command. */ protected function configure() { @@ -29,16 +30,18 @@ protected function configure() } /** - * {@inheritdoc} + * Invalidate / reset the indexer + * + * @param InputInterface $input + * @param OutputInterface $output + * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { $indexers = $this->getIndexers($input); foreach ($indexers as $indexer) { try { - $indexer->getState() - ->setStatus(\Magento\Framework\Indexer\StateInterface::STATUS_INVALID) - ->save(); + $indexer->invalidate(); $output->writeln($indexer->getTitle() . ' indexer has been invalidated.'); } catch (LocalizedException $e) { $output->writeln($e->getMessage()); @@ -47,5 +50,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln($e->getMessage()); } } + return Cli::RETURN_SUCCESS; } } diff --git a/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerResetStateCommandTest.php b/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerResetStateCommandTest.php index 433a32c04426f..4bc1972488b46 100644 --- a/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerResetStateCommandTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerResetStateCommandTest.php @@ -22,32 +22,17 @@ class IndexerResetStateCommandTest extends AbstractIndexerCommandCommonSetup */ private $command; - protected function setUp(): void - { - parent::setUp(); - $this->stateMock->expects($this->once())->method('setAreaCode')->with(FrontNameResolver::AREA_CODE); - } - public function testExecute() { $this->configureAdminArea(); $indexerOne = $this->getIndexerMock( - ['getState'], + ['invalidate'], ['indexer_id' => 'indexer_1', 'title' => 'Title_indexerOne'] ); $this->initIndexerCollectionByItems([$indexerOne]); - $stateMock = $this->createMock(State::class); - $stateMock->expects($this->exactly(1)) - ->method('setStatus') - ->with(StateInterface::STATUS_INVALID)->willReturnSelf(); - - $stateMock->expects($this->exactly(1)) - ->method('save'); - $indexerOne->expects($this->once()) - ->method('getState') - ->willReturn($stateMock); + ->method('invalidate'); $this->command = new IndexerResetStateCommand($this->objectManagerFactory); $commandTester = new CommandTester($this->command); diff --git a/app/code/Magento/NewRelicReporting/etc/adminhtml/system.xml b/app/code/Magento/NewRelicReporting/etc/adminhtml/system.xml index 60c52164021d9..ee1d1f8bfead7 100644 --- a/app/code/Magento/NewRelicReporting/etc/adminhtml/system.xml +++ b/app/code/Magento/NewRelicReporting/etc/adminhtml/system.xml @@ -68,9 +68,9 @@ - + Magento\Config\Model\Config\Source\Yesno - In addition to the main app (which includes all PHP execution), separate apps for adminhtml and frontend will be created. Requires New Relic Application Name to be set. + In addition to the main app (which includes all PHP execution), separate apps for each Magento area code (adminhtml, frontend, ...) will be created. Requires New Relic Application Name to be set. 1 diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php index 429fda816efd3..b20bbe0e00660 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SelectedShippingMethod.php @@ -3,15 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + declare(strict_types=1); namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; -use Magento\Directory\Model\Currency; 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\Quote\Model\Cart\ShippingMethodConverter; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Address\Rate; @@ -20,6 +21,19 @@ */ class SelectedShippingMethod implements ResolverInterface { + /** + * @var ShippingMethodConverter + */ + private $shippingMethodConverter; + + /** + * @param ShippingMethodConverter $shippingMethodConverter + */ + public function __construct(ShippingMethodConverter $shippingMethodConverter) + { + $this->shippingMethodConverter = $shippingMethodConverter; + } + /** * @inheritdoc */ @@ -31,8 +45,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /** @var Address $address */ $address = $value['model']; $rates = $address->getAllShippingRates(); - $carrierTitle = ''; - $methodTitle = ''; if (!count($rates) || empty($address->getShippingMethod())) { return null; @@ -42,26 +54,36 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /** @var Rate $rate */ foreach ($rates as $rate) { - if ($rate->getCode() == $address->getShippingMethod()) { - $carrierTitle = $rate->getCarrierTitle(); - $methodTitle = $rate->getMethodTitle(); + if ($rate->getCode() === $address->getShippingMethod()) { break; } } - $data = [ + $cart = $address->getQuote(); + $selectedShippingMethod = $this->shippingMethodConverter->modelToDataObject( + $rate, + $cart->getQuoteCurrencyCode() + ); + + return [ 'carrier_code' => $carrierCode, 'method_code' => $methodCode, - 'carrier_title' => $carrierTitle, - 'method_title' => $methodTitle, + 'carrier_title' => $selectedShippingMethod->getCarrierTitle() ?? '', + 'method_title' => $selectedShippingMethod->getMethodTitle() ?? '', 'amount' => [ 'value' => $address->getShippingAmount(), - 'currency' => $address->getQuote()->getQuoteCurrencyCode(), + 'currency' => $cart->getQuoteCurrencyCode(), + ], + 'price_excl_tax' => [ + 'value' => $selectedShippingMethod->getPriceExclTax(), + 'currency' => $cart->getQuoteCurrencyCode(), + ], + 'price_incl_tax' => [ + 'value' => $selectedShippingMethod->getPriceInclTax(), + 'currency' => $cart->getQuoteCurrencyCode(), ], /** @deprecated The field should not be used on the storefront */ 'base_amount' => null, ]; - - return $data; } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 1dc66531fbac6..eba02ff8972fc 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -267,6 +267,8 @@ type SelectedShippingMethod @doc(description: "Contains details about the select method_title: String! @doc(description: "The label for the method code.") amount: Money! @doc(description: "The cost of shipping using this shipping method.") base_amount: Money @deprecated(reason: "The field should not be used on the storefront.") + price_excl_tax: Money! @doc(description: "The cost of shipping using this shipping method, excluding tax.") + price_incl_tax: Money! @doc(description: "The cost of shipping using this shipping method, including tax.") } type AvailableShippingMethod @doc(description: "Contains details about the possible shipping methods and carriers.") { diff --git a/app/code/Magento/Sales/Model/Service/OrderService.php b/app/code/Magento/Sales/Model/Service/OrderService.php index fcdf297c22144..12ff4adcc4d6a 100644 --- a/app/code/Magento/Sales/Model/Service/OrderService.php +++ b/app/code/Magento/Sales/Model/Service/OrderService.php @@ -267,7 +267,7 @@ public function setState( $this->eventManager->dispatch( 'sales_order_state_change_before', - ['order' => $this, 'transport' => $transport] + ['order' => $this, 'transport' => $transport, 'order_object' => $order] ); $status = $transport->getStatus(); $order->setData('state', $transport->getState()); diff --git a/app/code/Magento/Tax/Model/Config.php b/app/code/Magento/Tax/Model/Config.php index 201158eae25dd..646da1441f225 100644 --- a/app/code/Magento/Tax/Model/Config.php +++ b/app/code/Magento/Tax/Model/Config.php @@ -23,109 +23,111 @@ class Config /** * Tax notifications */ - const XML_PATH_TAX_NOTIFICATION_IGNORE_DISCOUNT = 'tax/notification/ignore_discount'; + public const XML_PATH_TAX_NOTIFICATION_IGNORE_DISCOUNT = 'tax/notification/ignore_discount'; - const XML_PATH_TAX_NOTIFICATION_IGNORE_PRICE_DISPLAY = 'tax/notification/ignore_price_display'; + public const XML_PATH_TAX_NOTIFICATION_IGNORE_PRICE_DISPLAY = 'tax/notification/ignore_price_display'; - const XML_PATH_TAX_NOTIFICATION_IGNORE_APPLY_DISCOUNT = 'tax/notification/ignore_apply_discount'; + public const XML_PATH_TAX_NOTIFICATION_IGNORE_APPLY_DISCOUNT = 'tax/notification/ignore_apply_discount'; - const XML_PATH_TAX_NOTIFICATION_INFO_URL = 'tax/notification/info_url'; + public const XML_PATH_TAX_NOTIFICATION_INFO_URL = 'tax/notification/info_url'; // tax classes - const CONFIG_XML_PATH_SHIPPING_TAX_CLASS = 'tax/classes/shipping_tax_class'; + public const CONFIG_XML_PATH_SHIPPING_TAX_CLASS = 'tax/classes/shipping_tax_class'; // tax calculation - const CONFIG_XML_PATH_PRICE_INCLUDES_TAX = 'tax/calculation/price_includes_tax'; + public const CONFIG_XML_PATH_PRICE_INCLUDES_TAX = 'tax/calculation/price_includes_tax'; - const CONFIG_XML_PATH_SHIPPING_INCLUDES_TAX = 'tax/calculation/shipping_includes_tax'; + public const CONFIG_XML_PATH_SHIPPING_INCLUDES_TAX = 'tax/calculation/shipping_includes_tax'; - const CONFIG_XML_PATH_BASED_ON = 'tax/calculation/based_on'; + public const CONFIG_XML_PATH_BASED_ON = 'tax/calculation/based_on'; - const CONFIG_XML_PATH_APPLY_ON = 'tax/calculation/apply_tax_on'; + public const CONFIG_XML_PATH_APPLY_ON = 'tax/calculation/apply_tax_on'; - const CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT = 'tax/calculation/apply_after_discount'; + public const CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT = 'tax/calculation/apply_after_discount'; - const CONFIG_XML_PATH_DISCOUNT_TAX = 'tax/calculation/discount_tax'; + public const CONFIG_XML_PATH_DISCOUNT_TAX = 'tax/calculation/discount_tax'; - const XML_PATH_ALGORITHM = 'tax/calculation/algorithm'; + public const XML_PATH_ALGORITHM = 'tax/calculation/algorithm'; - const CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED = 'tax/calculation/cross_border_trade_enabled'; + public const CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED = 'tax/calculation/cross_border_trade_enabled'; // tax defaults - const CONFIG_XML_PATH_DEFAULT_COUNTRY = 'tax/defaults/country'; + public const CONFIG_XML_PATH_DEFAULT_COUNTRY = 'tax/defaults/country'; - const CONFIG_XML_PATH_DEFAULT_REGION = 'tax/defaults/region'; + public const CONFIG_XML_PATH_DEFAULT_REGION = 'tax/defaults/region'; - const CONFIG_XML_PATH_DEFAULT_POSTCODE = 'tax/defaults/postcode'; + public const CONFIG_XML_PATH_DEFAULT_POSTCODE = 'tax/defaults/postcode'; /** * Prices display settings */ - const CONFIG_XML_PATH_PRICE_DISPLAY_TYPE = 'tax/display/type'; + public const CONFIG_XML_PATH_PRICE_DISPLAY_TYPE = 'tax/display/type'; - const CONFIG_XML_PATH_DISPLAY_SHIPPING = 'tax/display/shipping'; + public const CONFIG_XML_PATH_DISPLAY_SHIPPING = 'tax/display/shipping'; /** * Shopping cart display settings */ - const XML_PATH_DISPLAY_CART_PRICE = 'tax/cart_display/price'; + public const XML_PATH_DISPLAY_CART_PRICE = 'tax/cart_display/price'; - const XML_PATH_DISPLAY_CART_SUBTOTAL = 'tax/cart_display/subtotal'; + public const XML_PATH_DISPLAY_CART_SUBTOTAL = 'tax/cart_display/subtotal'; - const XML_PATH_DISPLAY_CART_SHIPPING = 'tax/cart_display/shipping'; + public const XML_PATH_DISPLAY_CART_SHIPPING = 'tax/cart_display/shipping'; /** * Tax cart display discount * * @deprecated + * @see MC-22931 */ - const XML_PATH_DISPLAY_CART_DISCOUNT = 'tax/cart_display/discount'; + public const XML_PATH_DISPLAY_CART_DISCOUNT = 'tax/cart_display/discount'; - const XML_PATH_DISPLAY_CART_GRANDTOTAL = 'tax/cart_display/grandtotal'; + public const XML_PATH_DISPLAY_CART_GRANDTOTAL = 'tax/cart_display/grandtotal'; - const XML_PATH_DISPLAY_CART_FULL_SUMMARY = 'tax/cart_display/full_summary'; + public const XML_PATH_DISPLAY_CART_FULL_SUMMARY = 'tax/cart_display/full_summary'; - const XML_PATH_DISPLAY_CART_ZERO_TAX = 'tax/cart_display/zero_tax'; + public const XML_PATH_DISPLAY_CART_ZERO_TAX = 'tax/cart_display/zero_tax'; /** * Shopping cart display settings */ - const XML_PATH_DISPLAY_SALES_PRICE = 'tax/sales_display/price'; + public const XML_PATH_DISPLAY_SALES_PRICE = 'tax/sales_display/price'; - const XML_PATH_DISPLAY_SALES_SUBTOTAL = 'tax/sales_display/subtotal'; + public const XML_PATH_DISPLAY_SALES_SUBTOTAL = 'tax/sales_display/subtotal'; - const XML_PATH_DISPLAY_SALES_SHIPPING = 'tax/sales_display/shipping'; + public const XML_PATH_DISPLAY_SALES_SHIPPING = 'tax/sales_display/shipping'; /** * Tax sales display discount * * @deprecated + * @see MC-22931 */ - const XML_PATH_DISPLAY_SALES_DISCOUNT = 'tax/sales_display/discount'; + public const XML_PATH_DISPLAY_SALES_DISCOUNT = 'tax/sales_display/discount'; - const XML_PATH_DISPLAY_SALES_GRANDTOTAL = 'tax/sales_display/grandtotal'; + public const XML_PATH_DISPLAY_SALES_GRANDTOTAL = 'tax/sales_display/grandtotal'; - const XML_PATH_DISPLAY_SALES_FULL_SUMMARY = 'tax/sales_display/full_summary'; + public const XML_PATH_DISPLAY_SALES_FULL_SUMMARY = 'tax/sales_display/full_summary'; - const XML_PATH_DISPLAY_SALES_ZERO_TAX = 'tax/sales_display/zero_tax'; + public const XML_PATH_DISPLAY_SALES_ZERO_TAX = 'tax/sales_display/zero_tax'; - const CALCULATION_STRING_SEPARATOR = '|'; + public const CALCULATION_STRING_SEPARATOR = '|'; - const DISPLAY_TYPE_EXCLUDING_TAX = 1; + public const DISPLAY_TYPE_EXCLUDING_TAX = 1; - const DISPLAY_TYPE_INCLUDING_TAX = 2; + public const DISPLAY_TYPE_INCLUDING_TAX = 2; - const DISPLAY_TYPE_BOTH = 3; + public const DISPLAY_TYPE_BOTH = 3; /** * Price conversion constant for positive */ - const PRICE_CONVERSION_PLUS = 1; + public const PRICE_CONVERSION_PLUS = 1; /** * Price conversion constant for negative */ - const PRICE_CONVERSION_MINUS = 2; + public const PRICE_CONVERSION_MINUS = 2; /** * @var bool|null @@ -506,6 +508,7 @@ public function displayCartShippingBoth($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174 */ public function displayCartDiscountInclTax($store = null) { @@ -522,6 +525,7 @@ public function displayCartDiscountInclTax($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174s */ public function displayCartDiscountExclTax($store = null) { @@ -538,6 +542,7 @@ public function displayCartDiscountExclTax($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174 */ public function displayCartDiscountBoth($store = null) { @@ -734,6 +739,7 @@ public function displaySalesShippingBoth($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174 */ public function displaySalesDiscountInclTax($store = null) { @@ -750,6 +756,7 @@ public function displaySalesDiscountInclTax($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174 */ public function displaySalesDiscountExclTax($store = null) { @@ -766,6 +773,7 @@ public function displaySalesDiscountExclTax($store = null) * @param null|string|bool|int|Store $store * @return bool * @deprecated 100.1.3 + * @see MAGETWO-71174 */ public function displaySalesDiscountBoth($store = null) { @@ -912,7 +920,9 @@ public function getInfoUrl($store = null) public function needPriceConversion($store = null) { $res = false; - $priceIncludesTax = $this->priceIncludesTax($store) || $this->getNeedUseShippingExcludeTax(); + $priceIncludesTax = $this->priceIncludesTax($store) + || $this->getNeedUseShippingExcludeTax() + || $this->shippingPriceIncludesTax($store); if ($priceIncludesTax) { switch ($this->getPriceDisplayType($store)) { case self::DISPLAY_TYPE_EXCLUDING_TAX: diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index 06e17f76d3c7c..28495b628cd32 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -39,7 +39,8 @@ var config = { 'jquery-ui-modules/progressbar': 'jquery/ui-modules/widgets/progressbar', 'jquery-ui-modules/resizable': 'jquery/ui-modules/widgets/resizable', 'jquery-ui-modules/selectable': 'jquery/ui-modules/widgets/selectable', - 'jquery-ui-modules/slider': 'jquery/ui-modules/widgets/selectmenu', + 'jquery-ui-modules/selectmenu': 'jquery/ui-modules/widgets/selectmenu', + 'jquery-ui-modules/slider': 'jquery/ui-modules/widgets/slider', 'jquery-ui-modules/sortable': 'jquery/ui-modules/widgets/sortable', 'jquery-ui-modules/spinner': 'jquery/ui-modules/widgets/spinner', 'jquery-ui-modules/tabs': 'jquery/ui-modules/widgets/tabs', diff --git a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml index db19f7b17aecd..ed75808dc8cf7 100644 --- a/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml +++ b/app/code/Magento/User/view/adminhtml/layout/adminhtml_user_grid_block.xml @@ -76,6 +76,13 @@ email + + + Last Logged in + datetime + logdate + + Role diff --git a/app/code/Magento/WishlistGraphQl/README.md b/app/code/Magento/WishlistGraphQl/README.md index c635417f3a6ec..49c5aaa70f9d4 100644 --- a/app/code/Magento/WishlistGraphQl/README.md +++ b/app/code/Magento/WishlistGraphQl/README.md @@ -31,11 +31,11 @@ Extension developers can interact with the Magento_WishlistGraphQl module. For m For more information about the Magento_WishlistGraphQl [Queries](#queries) and [Mutations](#mutations) see below: -### Queries {#queries} +### Queries - [`wishlist`](https://devdocs.magento.com/guides/v2.4/graphql/queries/wishlist.html) -### Mutations {#mutations} +### Mutations - [`addProductsToWishlist`](https://devdocs.magento.com/guides/v2.4/graphql/mutations/add-products-to-wishlist.html) - [`removeProductsFromWishlist`](https://devdocs.magento.com/guides/v2.4/graphql/mutations/remove-products-from-wishlist.html) diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less index cc25fc80b2536..e8d6472ce0b4b 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less @@ -41,7 +41,6 @@ .admin__data-grid-wrap { margin-bottom: 2rem; max-width: 100%; - overflow-x: auto; padding-bottom: 1rem; padding-top: @data-grid-header-row__indent; } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php index 6a5f49e30d7ae..671e6359d4162 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php @@ -7,6 +7,11 @@ namespace Magento\GraphQl\Customer; +use Magento\Customer\Model\Log; +use Magento\Customer\Model\Logger; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -14,17 +19,28 @@ */ class GenerateCustomerTokenTest extends GraphQlAbstract { + /** + * @var Logger + */ + private $logger; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + $this->logger = Bootstrap::getObjectManager()->get(Logger::class); + } + /** * Verify customer token with valid credentials * * @magentoApiDataFixture Magento/Customer/_files/customer.php */ - public function testGenerateCustomerValidToken() + public function testGenerateCustomerValidToken(): void { - $email = 'customer@example.com'; - $password = 'password'; - - $mutation = $this->getQuery($email, $password); + $mutation = $this->getQuery(); $response = $this->graphQlMutation($mutation); $this->assertArrayHasKey('generateCustomerToken', $response); @@ -41,7 +57,7 @@ public function testGenerateCustomerValidToken() * @param string $password * @param string $message */ - public function testGenerateCustomerTokenInvalidData(string $email, string $password, string $message) + public function testGenerateCustomerTokenInvalidData(string $email, string $password, string $message): void { $this->expectException(\Exception::class); @@ -55,12 +71,9 @@ public function testGenerateCustomerTokenInvalidData(string $email, string $pass * * @magentoApiDataFixture Magento/Customer/_files/customer.php */ - public function testRegenerateCustomerToken() + public function testRegenerateCustomerToken(): void { - $email = 'customer@example.com'; - $password = 'password'; - - $mutation = $this->getQuery($email, $password); + $mutation = $this->getQuery(); $response1 = $this->graphQlMutation($mutation); $token1 = $response1['generateCustomerToken']['token']; @@ -110,7 +123,7 @@ public function dataProviderInvalidCustomerInfo(): array * @param string $password * @return string */ - private function getQuery(string $email, string $password) : string + private function getQuery(string $email = 'customer@example.com', string $password = 'password'): string { return <<getQuery($email, $password); $this->expectException(\Exception::class); $this->expectExceptionMessage('GraphQL response contains errors: Specify the "email" value.'); @@ -152,25 +155,51 @@ public function testGenerateCustomerTokenWithEmptyEmail() /** * Verify customer with empty password */ - public function testGenerateCustomerTokenWithEmptyPassword() + public function testGenerateCustomerTokenWithEmptyPassword(): void { $email = 'customer@example.com'; $password = ''; - $mutation - = <<getQuery($email, $password); $this->expectException(\Exception::class); $this->expectExceptionMessage('GraphQL response contains errors: Specify the "password" value.'); $this->graphQlMutation($mutation); } + + /** + * Verify customer log after generate customer token + * + * @magentoApiDataFixture Magento/Customer/_files/customer.php + */ + public function testCustomerLogAfterGenerateCustomerToken(): void + { + $response = $this->graphQlMutation($this->getQuery()); + $this->assertArrayHasKey('generateCustomerToken', $response); + $this->assertIsArray($response['generateCustomerToken']); + + /** @var Log $log */ + $log = $this->logger->get(1); + $this->assertNotEmpty($log->getLastLoginAt()); + } + + /** + * Ensure that customer log record is deleted. + * + * @return void + */ + protected function tearDown(): void + { + if ($this->logger->get(1)->getLastLoginAt()) { + /** @var ResourceConnection $resource */ + $resource = Bootstrap::getObjectManager()->get(ResourceConnection::class); + /** @var AdapterInterface $connection */ + $connection = $resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); + $connection->delete( + $resource->getTableName('customer_log'), + ['customer_id' => 1] + ); + } + parent::tearDown(); + } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php index 590290ffc4e9d..66e39a7860f39 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedShippingMethodTest.php @@ -7,6 +7,7 @@ namespace Magento\GraphQl\Quote\Customer; +use Magento\Framework\Exception\AuthenticationException; use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\TestFramework\Helper\Bootstrap; @@ -38,14 +39,19 @@ protected function setUp(): void } /** + * @magentoConfigFixture default_store tax/calculation/shipping_includes_tax 1 + * @magentoConfigFixture default_store tax/cart_display/shipping 2 + * @magentoConfigFixture default_store tax/classes/shipping_tax_class 2 + * @magentoConfigFixture default_store tax/display/shipping 2 * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/Tax/_files/tax_rule_region_1_al.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php */ - public function testGetSelectedShippingMethod() + public function testGetSelectedShippingMethodWithTax(): void { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); @@ -78,6 +84,149 @@ public function testGetSelectedShippingMethod() self::assertEquals(10, $amount['value']); self::assertArrayHasKey('currency', $amount); self::assertEquals('USD', $amount['currency']); + + self::assertArrayHasKey('price_excl_tax', $shippingAddress['selected_shipping_method']); + $priceExclTax = $shippingAddress['selected_shipping_method']['price_excl_tax']; + + self::assertArrayHasKey('value', $priceExclTax); + self::assertEquals(10, $priceExclTax['value']); + self::assertArrayHasKey('currency', $priceExclTax); + self::assertEquals('USD', $priceExclTax['currency']); + + self::assertArrayHasKey('amount', $shippingAddress['selected_shipping_method']); + $priceInclTax = $shippingAddress['selected_shipping_method']['price_incl_tax']; + + self::assertArrayHasKey('value', $priceInclTax); + self::assertEquals(10.75, $priceInclTax['value']); + self::assertArrayHasKey('currency', $priceInclTax); + self::assertEquals('USD', $priceInclTax['currency']); + } + + /** + * @magentoConfigFixture default_store tax/calculation/shipping_includes_tax 1 + * @magentoConfigFixture default_store tax/cart_display/shipping 2 + * @magentoConfigFixture default_store tax/classes/shipping_tax_class 2 + * @magentoConfigFixture default_store tax/display/shipping 2 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/Tax/_files/tax_rule_region_1_al.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_canada_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php + */ + public function testGetSelectedShippingMethodWithAddressWithoutTax(): void + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('cart', $response); + self::assertArrayHasKey('shipping_addresses', $response['cart']); + self::assertCount(1, $response['cart']['shipping_addresses']); + + $shippingAddress = current($response['cart']['shipping_addresses']); + self::assertArrayHasKey('selected_shipping_method', $shippingAddress); + + self::assertArrayHasKey('carrier_code', $shippingAddress['selected_shipping_method']); + self::assertEquals('flatrate', $shippingAddress['selected_shipping_method']['carrier_code']); + + self::assertArrayHasKey('method_code', $shippingAddress['selected_shipping_method']); + self::assertEquals('flatrate', $shippingAddress['selected_shipping_method']['method_code']); + + self::assertArrayHasKey('carrier_title', $shippingAddress['selected_shipping_method']); + self::assertEquals('Flat Rate', $shippingAddress['selected_shipping_method']['carrier_title']); + + self::assertArrayHasKey('method_title', $shippingAddress['selected_shipping_method']); + self::assertEquals('Fixed', $shippingAddress['selected_shipping_method']['method_title']); + + self::assertArrayHasKey('amount', $shippingAddress['selected_shipping_method']); + $amount = $shippingAddress['selected_shipping_method']['amount']; + + self::assertArrayHasKey('value', $amount); + self::assertEquals(10, $amount['value']); + self::assertArrayHasKey('currency', $amount); + self::assertEquals('USD', $amount['currency']); + + self::assertArrayHasKey('price_excl_tax', $shippingAddress['selected_shipping_method']); + $priceExclTax = $shippingAddress['selected_shipping_method']['price_excl_tax']; + + self::assertArrayHasKey('value', $priceExclTax); + self::assertEquals(10, $priceExclTax['value']); + self::assertArrayHasKey('currency', $priceExclTax); + self::assertEquals('USD', $priceExclTax['currency']); + + self::assertArrayHasKey('amount', $shippingAddress['selected_shipping_method']); + $priceInclTax = $shippingAddress['selected_shipping_method']['price_incl_tax']; + + self::assertArrayHasKey('value', $priceInclTax); + self::assertEquals(10, $priceInclTax['value']); + self::assertArrayHasKey('currency', $priceInclTax); + self::assertEquals('USD', $priceInclTax['currency']); + } + + /** + * @magentoConfigFixture default_store tax/calculation/shipping_includes_tax 0 + * @magentoConfigFixture default_store tax/cart_display/shipping 1 + * @magentoConfigFixture default_store tax/classes/shipping_tax_class 0 + * @magentoConfigFixture default_store tax/display/shipping 1 + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php + */ + public function testGetSelectedShippingMethodWithoutTax(): void + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = $this->getQuery($maskedQuoteId); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('cart', $response); + self::assertArrayHasKey('shipping_addresses', $response['cart']); + self::assertCount(1, $response['cart']['shipping_addresses']); + + $shippingAddress = current($response['cart']['shipping_addresses']); + self::assertArrayHasKey('selected_shipping_method', $shippingAddress); + + self::assertArrayHasKey('carrier_code', $shippingAddress['selected_shipping_method']); + self::assertEquals('flatrate', $shippingAddress['selected_shipping_method']['carrier_code']); + + self::assertArrayHasKey('method_code', $shippingAddress['selected_shipping_method']); + self::assertEquals('flatrate', $shippingAddress['selected_shipping_method']['method_code']); + + self::assertArrayHasKey('carrier_title', $shippingAddress['selected_shipping_method']); + self::assertEquals('Flat Rate', $shippingAddress['selected_shipping_method']['carrier_title']); + + self::assertArrayHasKey('method_title', $shippingAddress['selected_shipping_method']); + self::assertEquals('Fixed', $shippingAddress['selected_shipping_method']['method_title']); + + self::assertArrayHasKey('amount', $shippingAddress['selected_shipping_method']); + $amount = $shippingAddress['selected_shipping_method']['amount']; + + self::assertArrayHasKey('value', $amount); + self::assertEquals(10, $amount['value']); + self::assertArrayHasKey('currency', $amount); + self::assertEquals('USD', $amount['currency']); + + self::assertArrayHasKey('price_excl_tax', $shippingAddress['selected_shipping_method']); + $priceExclTax = $shippingAddress['selected_shipping_method']['price_excl_tax']; + + self::assertArrayHasKey('value', $priceExclTax); + self::assertEquals(10, $priceExclTax['value']); + self::assertArrayHasKey('currency', $priceExclTax); + self::assertEquals('USD', $priceExclTax['currency']); + + self::assertArrayHasKey('amount', $shippingAddress['selected_shipping_method']); + $priceInclTax = $shippingAddress['selected_shipping_method']['price_incl_tax']; + + self::assertArrayHasKey('value', $priceInclTax); + self::assertEquals(10, $priceInclTax['value']); + self::assertArrayHasKey('currency', $priceInclTax); + self::assertEquals('USD', $priceInclTax['currency']); } /** @@ -87,7 +236,7 @@ public function testGetSelectedShippingMethod() * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php */ - public function testGetSelectedShippingMethodBeforeSet() + public function testGetSelectedShippingMethodBeforeSet(): void { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); @@ -112,7 +261,7 @@ public function testGetSelectedShippingMethodBeforeSet() * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php */ - public function testGetSelectedShippingMethodFromGuestCart() + public function testGetSelectedShippingMethodFromGuestCart(): void { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); $query = $this->getQuery($maskedQuoteId); @@ -132,7 +281,7 @@ public function testGetSelectedShippingMethodFromGuestCart() * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php */ - public function testGetSelectedShippingMethodFromAnotherCustomerCart() + public function testGetSelectedShippingMethodFromAnotherCustomerCart(): void { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); $query = $this->getQuery($maskedQuoteId); @@ -150,7 +299,7 @@ public function testGetSelectedShippingMethodFromAnotherCustomerCart() * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php */ - public function testGetGetSelectedShippingMethodIfShippingMethodIsNotSet() + public function testGetGetSelectedShippingMethodIfShippingMethodIsNotSet(): void { $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); $query = $this->getQuery($maskedQuoteId); @@ -170,7 +319,7 @@ public function testGetGetSelectedShippingMethodIfShippingMethodIsNotSet() * @magentoApiDataFixture Magento/Customer/_files/customer.php * */ - public function testGetGetSelectedShippingMethodOfNonExistentCart() + public function testGetGetSelectedShippingMethodOfNonExistentCart(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('Could not find a cart with ID "non_existent_masked_id"'); @@ -185,12 +334,12 @@ public function testGetGetSelectedShippingMethodOfNonExistentCart() * @param string $username * @param string $password * @return array + * @throws AuthenticationException */ private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); - $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; - return $headerMap; + return ['Authorization' => 'Bearer ' . $customerToken]; } /** @@ -216,6 +365,14 @@ private function getQuery(string $maskedQuoteId): string value currency } + price_excl_tax { + value + currency + } + price_incl_tax { + value + currency + } } } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd index 2fbab18161925..8cdc91f8da3d9 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd @@ -78,7 +78,7 @@ - Table definition. Here we can found column, constraints and indexes + Table definition. Here we can find column, constraints and indexes diff --git a/lib/internal/Magento/Framework/View/Helper/SecureHtmlRenderer.php b/lib/internal/Magento/Framework/View/Helper/SecureHtmlRenderer.php index 332d7c44c5410..6fd6274dc6031 100644 --- a/lib/internal/Magento/Framework/View/Helper/SecureHtmlRenderer.php +++ b/lib/internal/Magento/Framework/View/Helper/SecureHtmlRenderer.php @@ -158,15 +158,20 @@ public function renderStyleAsTag(string $style, string $selector): string $exploded[1] = join('', array_slice($exploded, 1)); } $styleValue = str_replace('\'', '\\\'', trim($exploded[1])); - $stylesAssignments .= "$elementVariable.style.$styleAttribute = '$styleValue';\n"; + $stylesAssignments .= "element.style.$styleAttribute = '$styleValue';\n"; } - return $this->renderTag( - 'script', - ['type' => 'text/javascript'], - "var $elementVariable = document.querySelector('$selector');\n" - . "if ($elementVariable) {\n{$stylesAssignments}}", - false - ); + $script = <<