Skip to content

Commit e3eb76e

Browse files
authored
Merge pull request #5856 from magento-tsg-csl3/2.3-develop-pr51
[TSG-CSL3] For 2.3|1.1 (pr51)
2 parents eff5524 + 7228147 commit e3eb76e

File tree

12 files changed

+325
-43
lines changed

12 files changed

+325
-43
lines changed

app/code/Magento/Analytics/Model/ReportWriter.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
/**
1212
* Writes reports in files in csv format
13-
* @inheritdoc
1413
*/
1514
class ReportWriter implements ReportWriterInterface
1615
{
@@ -54,7 +53,7 @@ public function __construct(
5453
}
5554

5655
/**
57-
* {@inheritdoc}
56+
* @inheritdoc
5857
*/
5958
public function write(WriteInterface $directory, $path)
6059
{
@@ -81,7 +80,7 @@ public function write(WriteInterface $directory, $path)
8180
$headers = array_keys($row);
8281
$stream->writeCsv($headers);
8382
}
84-
$stream->writeCsv($row);
83+
$stream->writeCsv($this->prepareRow($row));
8584
}
8685
$stream->unlock();
8786
$stream->close();
@@ -98,4 +97,18 @@ public function write(WriteInterface $directory, $path)
9897

9998
return true;
10099
}
100+
101+
/**
102+
* Replace wrong symbols in row
103+
*
104+
* @param array $row
105+
* @return array
106+
*/
107+
private function prepareRow(array $row): array
108+
{
109+
$row = preg_replace('/(?<!\\\\)"/', '\\"', $row);
110+
$row = preg_replace('/[\\\\]+/', '\\', $row);
111+
112+
return $row;
113+
}
101114
}

app/code/Magento/Analytics/Test/Unit/Model/ReportWriterTest.php

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,43 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Analytics\Test\Unit\Model;
79

810
use Magento\Analytics\Model\ConfigInterface;
911
use Magento\Analytics\Model\ProviderFactory;
1012
use Magento\Analytics\Model\ReportWriter;
1113
use Magento\Analytics\ReportXml\DB\ReportValidator;
1214
use Magento\Analytics\ReportXml\ReportProvider;
13-
use Magento\Framework\Filesystem\Directory\WriteInterface;
15+
use Magento\Framework\Filesystem\Directory\WriteInterface as DirectoryWriteInterface;
16+
use Magento\Framework\Filesystem\File\WriteInterface as FileWriteInterface;
1417
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
1520

1621
/**
1722
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1823
*/
19-
class ReportWriterTest extends \PHPUnit\Framework\TestCase
24+
class ReportWriterTest extends TestCase
2025
{
2126
/**
22-
* @var ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
27+
* @var ConfigInterface|MockObject
2328
*/
2429
private $configInterfaceMock;
2530

2631
/**
27-
* @var ReportValidator|\PHPUnit_Framework_MockObject_MockObject
32+
* @var ReportValidator|MockObject
2833
*/
2934
private $reportValidatorMock;
3035

3136
/**
32-
* @var ProviderFactory|\PHPUnit_Framework_MockObject_MockObject
37+
* @var ProviderFactory|MockObject
3338
*/
3439
private $providerFactoryMock;
3540

3641
/**
37-
* @var ReportProvider|\PHPUnit_Framework_MockObject_MockObject
42+
* @var ReportProvider|MockObject
3843
*/
3944
private $reportProviderMock;
4045

@@ -44,7 +49,7 @@ class ReportWriterTest extends \PHPUnit\Framework\TestCase
4449
private $objectManagerHelper;
4550

4651
/**
47-
* @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
52+
* @var DirectoryWriteInterface|MockObject
4853
*/
4954
private $directoryMock;
5055

@@ -80,7 +85,7 @@ protected function setUp()
8085
->disableOriginalConstructor()->getMock();
8186
$this->reportProviderMock = $this->getMockBuilder(ReportProvider::class)
8287
->disableOriginalConstructor()->getMock();
83-
$this->directoryMock = $this->getMockBuilder(WriteInterface::class)->getMockForAbstractClass();
88+
$this->directoryMock = $this->getMockBuilder(DirectoryWriteInterface::class)->getMockForAbstractClass();
8489
$this->objectManagerHelper = new ObjectManagerHelper($this);
8590

8691
$this->reportWriter = $this->objectManagerHelper->getObject(
@@ -95,16 +100,15 @@ protected function setUp()
95100

96101
/**
97102
* @param array $configData
103+
* @param array $fileData
104+
* @param array $expectedFileData
98105
* @return void
99106
*
100107
* @dataProvider configDataProvider
101108
*/
102-
public function testWrite(array $configData)
109+
public function testWrite(array $configData, array $fileData, array $expectedFileData)
103110
{
104111
$errors = [];
105-
$fileData = [
106-
['number' => 1, 'type' => 'Shoes Usual']
107-
];
108112
$this->configInterfaceMock
109113
->expects($this->once())
110114
->method('get')
@@ -123,7 +127,7 @@ public function testWrite(array $configData)
123127
->with($parameterName ?: null)
124128
->willReturn($fileData);
125129
$errorStreamMock = $this->getMockBuilder(
126-
\Magento\Framework\Filesystem\File\WriteInterface::class
130+
FileWriteInterface::class
127131
)->getMockForAbstractClass();
128132
$errorStreamMock
129133
->expects($this->once())
@@ -133,8 +137,8 @@ public function testWrite(array $configData)
133137
->expects($this->exactly(2))
134138
->method('writeCsv')
135139
->withConsecutive(
136-
[array_keys($fileData[0])],
137-
[$fileData[0]]
140+
[array_keys($expectedFileData[0])],
141+
[$expectedFileData[0]]
138142
);
139143
$errorStreamMock->expects($this->once())->method('unlock');
140144
$errorStreamMock->expects($this->once())->method('close');
@@ -166,7 +170,7 @@ public function testWriteErrorFile($configData)
166170
$errors = ['orders', 'SQL Error: test'];
167171
$this->configInterfaceMock->expects($this->once())->method('get')->willReturn([$configData]);
168172
$errorStreamMock = $this->getMockBuilder(
169-
\Magento\Framework\Filesystem\File\WriteInterface::class
173+
FileWriteInterface::class
170174
)->getMockForAbstractClass();
171175
$errorStreamMock->expects($this->once())->method('lock');
172176
$errorStreamMock->expects($this->once())->method('writeCsv')->with($errors);
@@ -196,7 +200,7 @@ public function configDataProvider()
196200
{
197201
return [
198202
'reportProvider' => [
199-
[
203+
'configData' => [
200204
'providers' => [
201205
[
202206
'name' => $this->providerName,
@@ -206,6 +210,12 @@ public function configDataProvider()
206210
],
207211
]
208212
]
213+
],
214+
'fileData' => [
215+
['number' => 1, 'type' => 'Shoes\"" Usual\\\\"']
216+
],
217+
'expectedFileData' => [
218+
['number' => 1, 'type' => 'Shoes\"\" Usual\\"']
209219
]
210220
],
211221
];

app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ define(
9191
})
9292
.then(function (hostedFieldsInstance) {
9393
self.hostedFieldsInstance = hostedFieldsInstance;
94-
self.isPlaceOrderActionAllowed(false);
94+
95+
if ($('#billing-address-same-as-shipping-braintree').is(':checked')) {
96+
self.isPlaceOrderActionAllowed(true);
97+
} else {
98+
self.isPlaceOrderActionAllowed(false);
99+
}
95100
self.initFormValidationEvents(hostedFieldsInstance);
96101

97102
return self.hostedFieldsInstance;

app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
<?php
2-
32
/**
4-
* Import entity of bundle product type
5-
*
63
* Copyright © Magento, Inc. All rights reserved.
74
* See COPYING.txt for license details.
85
*/
6+
declare(strict_types=1);
7+
98
namespace Magento\BundleImportExport\Model\Import\Product\Type;
109

1110
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
@@ -19,13 +18,15 @@
1918
use Magento\Store\Model\StoreManagerInterface;
2019

2120
/**
22-
* Class Bundle
21+
* Import entity of bundle product type
2322
*
24-
* @package Magento\BundleImportExport\Model\Import\Product\Type
2523
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
2624
*/
2725
class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType
2826
{
27+
/**
28+
* phpcs:disable Magento2.Commenting.ConstantsPHPDocFormatting
29+
*/
2930

3031
/**
3132
* Delimiter before product option value.
@@ -62,6 +63,10 @@ class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\Abst
6263
*/
6364
const SELECTION_PRICE_TYPE_PERCENT = 1;
6465

66+
/**
67+
* phpcs:enable Magento2.Commenting.ConstantsPHPDocFormatting
68+
*/
69+
6570
/**
6671
* Array of cached options.
6772
*
@@ -616,6 +621,7 @@ protected function populateInsertOptionValues(array $optionIds): array
616621
if ($assoc['position'] == $this->_cachedOptions[$entityId][$key]['index']
617622
&& $assoc['parent_id'] == $entityId) {
618623
$option['parent_id'] = $entityId;
624+
//phpcs:ignore Magento2.Performance.ForeachArrayMerge
619625
$optionValues = array_merge(
620626
$optionValues,
621627
$this->populateOptionValueTemplate($option, $optionId)
@@ -675,10 +681,7 @@ private function insertParentChildRelations()
675681
$childIds = [];
676682
foreach ($options as $option) {
677683
foreach ($option['selections'] as $selection) {
678-
if (!isset($selection['parent_product_id'])) {
679-
if (!isset($this->_cachedSkuToProducts[$selection['sku']])) {
680-
continue;
681-
}
684+
if (isset($this->_cachedSkuToProducts[$selection['sku']])) {
682685
$childIds[] = $this->_cachedSkuToProducts[$selection['sku']];
683686
}
684687
}
@@ -717,6 +720,8 @@ protected function _initAttributes()
717720
}
718721
}
719722
}
723+
724+
return $this;
720725
}
721726

722727
/**
@@ -786,7 +791,7 @@ private function getStoreIdByCode(string $storeCode): int
786791
if (!isset($this->storeCodeToId[$storeCode])) {
787792
/** @var $store \Magento\Store\Model\Store */
788793
foreach ($this->storeManager->getStores() as $store) {
789-
$this->storeCodeToId[$store->getCode()] = $store->getId();
794+
$this->storeCodeToId[$store->getCode()] = (int)$store->getId();
790795
}
791796
}
792797

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="UpdateBundleProductViaImportTest">
12+
<annotations>
13+
<stories value="Update Bundle product via import"/>
14+
<features value="Import/Export"/>
15+
<title value="Bundle relations is removed when products are re-imported"/>
16+
<description value="Bundle relations is removed when products are re-imported"/>
17+
<severity value="MAJOR"/>
18+
<testCaseId value="MC-35605"/>
19+
<useCaseId value="MC-35484"/>
20+
<group value="importExport"/>
21+
</annotations>
22+
<before>
23+
<actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/>
24+
</before>
25+
<after>
26+
<!-- Delete products created via import -->
27+
<actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteBundleProduct">
28+
<argument name="sku" value="Bundle"/>
29+
</actionGroup>
30+
<actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteSimpleProduct">
31+
<argument name="sku" value="Simple"/>
32+
</actionGroup>
33+
<actionGroup ref="logout" stepKey="logoutFromAdmin"/>
34+
</after>
35+
36+
<!-- Create Bundle product via import -->
37+
<actionGroup ref="AdminImportProductsActionGroup" stepKey="adminImportProductsCreate">
38+
<argument name="behavior" value="Add/Update"/>
39+
<argument name="importFile" value="catalog_product_import_bundle.csv"/>
40+
<argument name="importNoticeMessage" value="Created: 2, Updated: 0, Deleted: 0"/>
41+
</actionGroup>
42+
<magentoCLI command="cache:flush" arguments="full_page" stepKey="flushCacheAfterCreate"/>
43+
<magentoCLI command="indexer:reindex" stepKey="indexerReindexAfterCreate"/>
44+
45+
<!-- Check Bundle product is visible on the storefront-->
46+
<actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPageAfterCreation">
47+
<argument name="categoryName" value="New"/>
48+
</actionGroup>
49+
<actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup"
50+
stepKey="assertBundleProductInStockAfterCreation">
51+
<argument name="productName" value="Bundle"/>
52+
</actionGroup>
53+
54+
<!-- Update Bundle product via import -->
55+
<actionGroup ref="AdminImportProductsActionGroup" stepKey="adminImportProductsUpdate">
56+
<argument name="behavior" value="Add/Update"/>
57+
<argument name="importFile" value="catalog_product_import_bundle.csv"/>
58+
<argument name="importNoticeMessage" value="Created: 0, Updated: 2, Deleted: 0"/>
59+
</actionGroup>
60+
<magentoCLI command="cache:flush" arguments="full_page" stepKey="flushCacheAfterUpdate"/>
61+
<magentoCLI command="indexer:reindex" stepKey="indexerReindexAfterUpdate"/>
62+
63+
<!-- Check Bundle product is still visible on the storefront-->
64+
<actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPageAfterUpdate">
65+
<argument name="categoryName" value="New"/>
66+
</actionGroup>
67+
<actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup"
68+
stepKey="assertBundleProductInStockAfterUpdate">
69+
<argument name="productName" value="Bundle"/>
70+
</actionGroup>
71+
</test>
72+
</tests>

0 commit comments

Comments
 (0)