Skip to content

Commit c7d6759

Browse files
merge magento/2.4-develop into magento-arcticfoxes/B2B-284-271
2 parents 03d92d7 + d95cea6 commit c7d6759

File tree

39 files changed

+1108
-560
lines changed

39 files changed

+1108
-560
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/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>

app/code/Magento/Config/Model/Config/Structure/Element/Dependency/Field.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
* @api
1010
* @since 100.0.2
1111
*/
12+
13+
/**
14+
* Class Field
15+
*
16+
* Fields are used to describe possible values for a type/interface.
17+
*/
1218
class Field
1319
{
1420
/**
@@ -41,7 +47,7 @@ public function __construct(array $fieldData = [], $fieldPrefix = "")
4147
if (isset($fieldData['separator'])) {
4248
$this->_values = explode($fieldData['separator'], $fieldData['value']);
4349
} else {
44-
$this->_values = [$fieldData['value']];
50+
$this->_values = [isset($fieldData['value']) ? $fieldData['value'] : ''];
4551
}
4652
$fieldId = $fieldPrefix . (isset(
4753
$fieldData['dependPath']

app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/Dependency/FieldTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class FieldTest extends \PHPUnit\Framework\TestCase
1212
*/
1313
const SIMPLE_VALUE = 'someValue';
1414

15+
const EMPTY_VALUE = '';
16+
1517
const COMPLEX_VALUE1 = 'value_1';
1618

1719
const COMPLEX_VALUE2 = 'value_2';
@@ -150,8 +152,19 @@ public function getValuesDataProvider()
150152
return [
151153
[$this->_getSimpleData(), true, [self::SIMPLE_VALUE]],
152154
[$this->_getSimpleData(), false, [self::SIMPLE_VALUE]],
155+
[$this->_getSimpleEmptyData(), false, [static::EMPTY_VALUE]],
153156
[$this->_getComplexData(), true, $complexDataValues],
154157
[$this->_getComplexData(), false, $complexDataValues]
155158
];
156159
}
160+
161+
/**
162+
* Providing a field data with no field value
163+
*
164+
* @return array
165+
*/
166+
protected function _getSimpleEmptyData(): array
167+
{
168+
return ['dependPath' => ['section_2', 'group_3', 'field_4']];
169+
}
157170
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminCheckDataForImportProductActionGroup">
12+
<arguments>
13+
<argument name="behavior" type="string" defaultValue="Add/Update"/>
14+
<argument name="importFile" type="string"/>
15+
</arguments>
16+
<amOnPage url="{{AdminImportIndexPage.url}}" stepKey="goToImportIndexPage"/>
17+
<waitForPageLoad stepKey="adminImportMainSectionLoad"/>
18+
<selectOption selector="{{AdminImportMainSection.entityType}}" userInput="Products" stepKey="selectProductsOption"/>
19+
<waitForElementVisible selector="{{AdminImportMainSection.importBehavior}}" stepKey="waitForImportBehaviorElementVisible"/>
20+
<selectOption selector="{{AdminImportMainSection.importBehavior}}" userInput="{{behavior}}" stepKey="selectImportBehaviorOption"/>
21+
<attachFile selector="{{AdminImportMainSection.selectFileToImport}}" userInput="{{importFile}}" stepKey="attachFileForImport"/>
22+
<click selector="{{AdminImportHeaderSection.checkDataButton}}" stepKey="clickCheckDataButton"/>
23+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/>
24+
</actionGroup>
25+
</actionGroups>

app/code/Magento/ImportExport/Test/Mftf/ActionGroup/AdminImportProductsActionGroup.xml

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,4 @@
3636
<see selector="{{AdminImportValidationMessagesSection.notice}}" userInput="{{importNoticeMessage}}" stepKey="seeNoticeMessage"/>
3737
<see selector="{{AdminImportValidationMessagesSection.messageByType(importMessageType)}}" userInput="{{importMessage}}" stepKey="seeImportMessage"/>
3838
</actionGroup>
39-
40-
<actionGroup name="AdminImportProductsWithCheckValidationResultActionGroup" extends="AdminImportProductsActionGroup">
41-
<arguments>
42-
<argument name="validationNoticeMessage" type="string"/>
43-
<argument name="validationMessage" type="string" defaultValue="File is valid! To start import process press &quot;Import&quot; button"/>
44-
</arguments>
45-
<waitForElementVisible selector="{{AdminImportValidationMessagesSection.notice}}" after="clickCheckDataButton" stepKey="waitForValidationNoticeMessage"/>
46-
<see selector="{{AdminImportValidationMessagesSection.notice}}" userInput="{{validationNoticeMessage}}" after="waitForValidationNoticeMessage" stepKey="seeValidationNoticeMessage"/>
47-
<see selector="{{AdminImportValidationMessagesSection.success}}" userInput="{{validationMessage}}" after="seeValidationNoticeMessage" stepKey="seeValidationMessage"/>
48-
</actionGroup>
49-
<actionGroup name="AdminCheckDataForImportProductActionGroup">
50-
<arguments>
51-
<argument name="behavior" type="string" defaultValue="Add/Update"/>
52-
<argument name="importFile" type="string"/>
53-
</arguments>
54-
<amOnPage url="{{AdminImportIndexPage.url}}" stepKey="goToImportIndexPage"/>
55-
<waitForPageLoad stepKey="adminImportMainSectionLoad"/>
56-
<selectOption selector="{{AdminImportMainSection.entityType}}" userInput="Products" stepKey="selectProductsOption"/>
57-
<waitForElementVisible selector="{{AdminImportMainSection.importBehavior}}" stepKey="waitForImportBehaviorElementVisible"/>
58-
<selectOption selector="{{AdminImportMainSection.importBehavior}}" userInput="{{behavior}}" stepKey="selectImportBehaviorOption"/>
59-
<attachFile selector="{{AdminImportMainSection.selectFileToImport}}" userInput="{{importFile}}" stepKey="attachFileForImport"/>
60-
<click selector="{{AdminImportHeaderSection.checkDataButton}}" stepKey="clickCheckDataButton"/>
61-
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/>
62-
</actionGroup>
6339
</actionGroups>

0 commit comments

Comments
 (0)