Skip to content

Commit 7f442d1

Browse files
merge magento/2.4-develop into magento-qwerty/MC-23177
2 parents b1ea000 + d95cea6 commit 7f442d1

File tree

47 files changed

+1323
-604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1323
-604
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Backend\Test\Unit\Helper;
9+
10+
use Magento\Backend\Helper\Js;
11+
use PHPUnit\Framework\TestCase;
12+
13+
/**
14+
* Class JsTest
15+
*
16+
* Testing decoding serialized grid data
17+
*/
18+
class JsTest extends TestCase
19+
{
20+
/**
21+
* @var Js
22+
*/
23+
private $helper;
24+
25+
/**
26+
* Set Up
27+
*/
28+
protected function setUp()
29+
{
30+
$this->helper = new Js();
31+
}
32+
33+
/**
34+
* Test decoding the serialized input
35+
*
36+
* @dataProvider getEncodedDataProvider
37+
*
38+
* @param string $encoded
39+
* @param array $expected
40+
*/
41+
public function testDecodeGridSerializedInput(string $encoded, array $expected)
42+
{
43+
$this->assertEquals($expected, $this->helper->decodeGridSerializedInput($encoded));
44+
}
45+
46+
/**
47+
* Get serialized grid input
48+
*
49+
* @return array
50+
*/
51+
public function getEncodedDataProvider(): array
52+
{
53+
return [
54+
'Decoding empty serialized string' => [
55+
'',
56+
[]
57+
],
58+
'Decoding a simplified serialized string' => [
59+
'1&2&3&4',
60+
[1, 2, 3, 4]
61+
],
62+
'Decoding encoded serialized string' => [
63+
'2=dGVzdC1zdHJpbmc=',
64+
[
65+
2 => [
66+
'test-string' => ''
67+
]
68+
]
69+
],
70+
'Decoding multiple encoded serialized strings' => [
71+
'2=dGVzdC1zdHJpbmc=&3=bmV3LXN0cmluZw==',
72+
[
73+
2 => [
74+
'test-string' => ''
75+
],
76+
3 => [
77+
'new-string' => ''
78+
]
79+
]
80+
]
81+
];
82+
}
83+
}

app/code/Magento/Catalog/view/frontend/templates/product/list.phtml

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ use Magento\Framework\App\Action\Action;
1313
* Product list template
1414
*
1515
* @var $block \Magento\Catalog\Block\Product\ListProduct
16+
* @var \Magento\Framework\Escaper $escaper
1617
*/
1718
?>
1819
<?php
1920
$_productCollection = $block->getLoadedProductCollection();
21+
/** @var \Magento\Catalog\Helper\Output $_helper */
2022
$_helper = $this->helper(Magento\Catalog\Helper\Output::class);
2123
?>
2224
<?php if (!$_productCollection->count()) :?>
23-
<div class="message info empty"><div><?= $block->escapeHtml(__('We can\'t find products matching the selection.')) ?></div></div>
25+
<div class="message info empty"><div><?= $escaper->escapeHtml(__('We can\'t find products matching the selection.')) ?></div></div>
2426
<?php else :?>
2527
<?= $block->getToolbarHtml() ?>
2628
<?= $block->getAdditionalHtml() ?>
@@ -55,7 +57,7 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
5557
}
5658
?>
5759
<?php // Product Image ?>
58-
<a href="<?= $block->escapeUrl($_product->getProductUrl()) ?>"
60+
<a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>"
5961
class="product photo product-item-photo"
6062
tabindex="-1">
6163
<?= $productImage->toHtml() ?>
@@ -66,7 +68,7 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
6668
?>
6769
<strong class="product name product-item-name">
6870
<a class="product-item-link"
69-
href="<?= $block->escapeUrl($_product->getProductUrl()) ?>">
71+
href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>">
7072
<?= /* @noEscape */ $_helper->productAttribute($_product, $_product->getName(), 'name') ?>
7173
</a>
7274
</strong>
@@ -77,13 +79,13 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
7779
<?php endif; ?>
7880

7981
<div class="product-item-inner">
80-
<div class="product actions product-item-actions"<?= strpos($pos, $viewMode . '-actions') ? $block->escapeHtmlAttr($position) : '' ?>>
81-
<div class="actions-primary"<?= strpos($pos, $viewMode . '-primary') ? $block->escapeHtmlAttr($position) : '' ?>>
82+
<div class="product actions product-item-actions"<?= strpos($pos, $viewMode . '-actions') ? $escaper->escapeHtmlAttr($position) : '' ?>>
83+
<div class="actions-primary"<?= strpos($pos, $viewMode . '-primary') ? $escaper->escapeHtmlAttr($position) : '' ?>>
8284
<?php if ($_product->isSaleable()) :?>
8385
<?php $postParams = $block->getAddToCartPostParams($_product); ?>
8486
<form data-role="tocart-form"
85-
data-product-sku="<?= $block->escapeHtml($_product->getSku()) ?>"
86-
action="<?= $block->escapeUrl($postParams['action']) ?>"
87+
data-product-sku="<?= $escaper->escapeHtml($_product->getSku()) ?>"
88+
action="<?= $escaper->escapeUrl($postParams['action']) ?>"
8789
method="post">
8890
<input type="hidden"
8991
name="product"
@@ -92,20 +94,20 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
9294
value="<?= /* @noEscape */ $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>">
9395
<?= $block->getBlockHtml('formkey') ?>
9496
<button type="submit"
95-
title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>"
97+
title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
9698
class="action tocart primary">
97-
<span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
99+
<span><?= $escaper->escapeHtml(__('Add to Cart')) ?></span>
98100
</button>
99101
</form>
100102
<?php else :?>
101103
<?php if ($_product->isAvailable()) :?>
102-
<div class="stock available"><span><?= $block->escapeHtml(__('In stock')) ?></span></div>
104+
<div class="stock available"><span><?= $escaper->escapeHtml(__('In stock')) ?></span></div>
103105
<?php else :?>
104-
<div class="stock unavailable"><span><?= $block->escapeHtml(__('Out of stock')) ?></span></div>
106+
<div class="stock unavailable"><span><?= $escaper->escapeHtml(__('Out of stock')) ?></span></div>
105107
<?php endif; ?>
106108
<?php endif; ?>
107109
</div>
108-
<div data-role="add-to-links" class="actions-secondary"<?= strpos($pos, $viewMode . '-secondary') ? $block->escapeHtmlAttr($position) : '' ?>>
110+
<div data-role="add-to-links" class="actions-secondary"<?= strpos($pos, $viewMode . '-secondary') ? $escaper->escapeHtmlAttr($position) : '' ?>>
109111
<?php if ($addToBlock = $block->getChildBlock('addto')) :?>
110112
<?= $addToBlock->setProduct($_product)->getChildHtml() ?>
111113
<?php endif; ?>
@@ -114,9 +116,9 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
114116
<?php if ($showDescription) :?>
115117
<div class="product description product-item-description">
116118
<?= /* @noEscape */ $_helper->productAttribute($_product, $_product->getShortDescription(), 'short_description') ?>
117-
<a href="<?= $block->escapeUrl($_product->getProductUrl()) ?>"
119+
<a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>"
118120
title="<?= /* @noEscape */ $_productNameStripped ?>"
119-
class="action more"><?= $block->escapeHtml(__('Learn More')) ?></a>
121+
class="action more"><?= $escaper->escapeHtml(__('Learn More')) ?></a>
120122
</div>
121123
<?php endif; ?>
122124
</div>
@@ -132,7 +134,7 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class);
132134
{
133135
"[data-role=tocart-form], .form.map.checkout": {
134136
"catalogAddToCart": {
135-
"product_sku": "<?= $block->escapeJs($_product->getSku()) ?>"
137+
"product_sku": "<?= $escaper->escapeJs($_product->getSku()) ?>"
136138
}
137139
}
138140
}

app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99

1010
<meta property="og:type" content="product" />
1111
<meta property="og:title"
12-
content="<?= /* @noEscape */ $block->stripTags($block->getProduct()->getName()) ?>" />
12+
content="<?= $block->escapeHtmlAttr($block->stripTags($block->getProduct()->getName())) ?>" />
1313
<meta property="og:image"
1414
content="<?= $block->escapeUrl($block->getImage($block->getProduct(), 'product_base_image')->getImageUrl()) ?>" />
1515
<meta property="og:description"
16-
content="<?= /* @noEscape */ $block->stripTags($block->getProduct()->getShortDescription()) ?>" />
16+
content="<?= $block->escapeHtmlAttr($block->stripTags($block->getProduct()->getShortDescription())) ?>" />
1717
<meta property="og:url" content="<?= $block->escapeUrl($block->getProduct()->getProductUrl()) ?>" />
18-
<?php if ($priceAmount = $block->getProduct()->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)->getAmount()) :?>
18+
<?php if ($priceAmount = $block->getProduct()
19+
->getPriceInfo()
20+
->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
21+
->getAmount()):?>
1922
<meta property="product:price:amount" content="<?= $block->escapeHtmlAttr($priceAmount) ?>"/>
2023
<?= $block->getChildHtml('meta.currency') ?>
2124
<?php endif;?>
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Checkout\Test\Unit\CustomerData;
10+
11+
use Magento\Checkout\CustomerData\DirectoryData;
12+
use Magento\Directory\Helper\Data as HelperData;
13+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
14+
use Magento\Directory\Model\Country;
15+
use PHPUnit\Framework\TestCase;
16+
17+
class DirectoryDataTest extends TestCase
18+
{
19+
/**
20+
* @var DirectoryData
21+
*/
22+
private $model;
23+
24+
/**
25+
* @var HelperData|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
private $directoryHelperMock;
28+
29+
/**
30+
* @var ObjectManagerHelper
31+
*/
32+
private $objectManager;
33+
34+
/**
35+
* Setup environment for testing
36+
*/
37+
protected function setUp()
38+
{
39+
$this->objectManager = new ObjectManagerHelper($this);
40+
$this->directoryHelperMock = $this->createMock(HelperData::class);
41+
42+
$this->model = $this->objectManager->getObject(
43+
DirectoryData::class,
44+
[
45+
'directoryHelper' => $this->directoryHelperMock
46+
]
47+
);
48+
}
49+
50+
/**
51+
* Test getSectionData() function
52+
*/
53+
public function testGetSectionData()
54+
{
55+
$regions = [
56+
'US' => [
57+
'TX' => [
58+
'code' => 'TX',
59+
'name' => 'Texas'
60+
]
61+
]
62+
];
63+
64+
$testCountryInfo = $this->objectManager->getObject(Country::class);
65+
$testCountryInfo->setData('country_id', 'US');
66+
$testCountryInfo->setData('iso2_code', 'US');
67+
$testCountryInfo->setData('iso3_code', 'USA');
68+
$testCountryInfo->setData('name_default', 'United States of America');
69+
$testCountryInfo->setData('name_en_US', 'United States of America');
70+
$countries = ['US' => $testCountryInfo];
71+
72+
$this->directoryHelperMock->expects($this->any())
73+
->method('getRegionData')
74+
->willReturn($regions);
75+
76+
$this->directoryHelperMock->expects($this->any())
77+
->method('getCountryCollection')
78+
->willReturn($countries);
79+
80+
/* Assert result */
81+
$this->assertEquals(
82+
[
83+
'US' => [
84+
'name' => 'United States of America',
85+
'regions' => [
86+
'TX' => [
87+
'code' => 'TX',
88+
'name' => 'Texas'
89+
]
90+
]
91+
]
92+
],
93+
$this->model->getSectionData()
94+
);
95+
}
96+
}

app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ define([
6060
template: 'Magento_Checkout/shipping',
6161
shippingFormTemplate: 'Magento_Checkout/shipping-address/form',
6262
shippingMethodListTemplate: 'Magento_Checkout/shipping-address/shipping-method-list',
63-
shippingMethodItemTemplate: 'Magento_Checkout/shipping-address/shipping-method-item'
63+
shippingMethodItemTemplate: 'Magento_Checkout/shipping-address/shipping-method-item',
64+
imports: {
65+
countryOptions: '${ $.parentName }.shippingAddress.shipping-address-fieldset.country_id:indexedOptions'
66+
}
6467
},
6568
visible: ko.observable(!quote.isVirtual()),
6669
errorValidationMessage: ko.observable(false),
@@ -276,9 +279,7 @@ define([
276279
loginFormSelector = 'form[data-role=email-with-possible-login]',
277280
emailValidationResult = customer.isLoggedIn(),
278281
field,
279-
country = registry.get(this.parentName + '.shippingAddress.shipping-address-fieldset.country_id'),
280-
countryIndexedOptions = country.indexedOptions,
281-
option = countryIndexedOptions[quote.shippingAddress().countryId],
282+
option = _.isObject(this.countryOptions) && this.countryOptions[quote.shippingAddress().countryId],
282283
messageContainer = registry.get('checkout.errors').messageContainer;
283284

284285
if (!quote.shippingMethod()) {

app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Block/SaveTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,58 @@ public function testSaveAndClose()
373373
$this->assertSame($this->resultRedirect, $this->saveController->execute());
374374
}
375375

376+
public function testSaveActionWithMarginalSpace()
377+
{
378+
$postData = [
379+
'title' => 'unique_title_123',
380+
'identifier' => ' unique_title_123',
381+
'stores' => ['0'],
382+
'is_active' => true,
383+
'content' => '',
384+
'back' => 'continue'
385+
];
386+
387+
$this->requestMock->expects($this->any())->method('getPostValue')->willReturn($postData);
388+
$this->requestMock->expects($this->atLeastOnce())
389+
->method('getParam')
390+
->willReturnMap(
391+
[
392+
['block_id', null, 1],
393+
['back', null, true],
394+
]
395+
);
396+
397+
$this->blockFactory->expects($this->atLeastOnce())
398+
->method('create')
399+
->willReturn($this->blockMock);
400+
401+
$this->blockRepository->expects($this->once())
402+
->method('getById')
403+
->with($this->blockId)
404+
->willReturn($this->blockMock);
405+
406+
$this->blockMock->expects($this->once())->method('setData');
407+
$this->blockRepository->expects($this->once())->method('save')
408+
->with($this->blockMock)
409+
->willThrowException(new \Exception('No marginal white space please.'));
410+
411+
$this->messageManagerMock->expects($this->never())
412+
->method('addSuccessMessage');
413+
$this->messageManagerMock->expects($this->once())
414+
->method('addExceptionMessage');
415+
416+
$this->dataPersistorMock->expects($this->any())
417+
->method('set')
418+
->with('cms_block', array_merge($postData, ['block_id' => null]));
419+
420+
$this->resultRedirect->expects($this->atLeastOnce())
421+
->method('setPath')
422+
->with('*/*/edit', ['block_id' => $this->blockId])
423+
->willReturnSelf();
424+
425+
$this->assertSame($this->resultRedirect, $this->saveController->execute());
426+
}
427+
376428
public function testSaveActionThrowsException()
377429
{
378430
$postData = [

app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_form.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
<settings>
106106
<validation>
107107
<rule name="required-entry" xsi:type="boolean">true</rule>
108+
<rule name="no-marginal-whitespace" xsi:type="boolean">true</rule>
108109
</validation>
109110
<dataType>text</dataType>
110111
<label translate="true">Identifier</label>

0 commit comments

Comments
 (0)