Skip to content

Commit 45cbf9b

Browse files
authored
Merge pull request #10109 from adobe-commerce-tier-4/PR_2025_09_15_muntianu
[Support Tier-4 muntianu] 09-15-2025 Regular delivery of bugfixes and improvements
2 parents 4baea6d + c7f16fb commit 45cbf9b

File tree

58 files changed

+2652
-372
lines changed

Some content is hidden

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

58 files changed

+2652
-372
lines changed

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,18 @@ private function prepareData(array $provider, WriteInterface $directory, string
104104
$stream = $directory->openFile($fileFullPath, 'w+');
105105
$stream->lock();
106106

107-
$headers = [];
108107
if ($providerObject instanceof \Magento\Analytics\ReportXml\BatchReportProviderInterface) {
108+
$writeHeaders = true;
109109
$fileData = $providerObject->getBatchReport(...array_values($provider['parameters']));
110110
do {
111-
$this->doWrite($fileData, $stream, $headers);
111+
$this->doWrite($fileData, $stream, $writeHeaders);
112+
$writeHeaders = false;
112113
$fileData = $providerObject->getBatchReport(...array_values($provider['parameters']));
113114
$fileData->rewind();
114115
} while ($fileData->valid());
115116
} else {
116117
$fileData = $providerObject->getReport(...array_values($provider['parameters']));
117-
$this->doWrite($fileData, $stream, $headers);
118+
$this->doWrite($fileData, $stream);
118119
}
119120

120121
$stream->unlock();
@@ -126,15 +127,16 @@ private function prepareData(array $provider, WriteInterface $directory, string
126127
*
127128
* @param \Traversable $fileData
128129
* @param FileWriteInterface $stream
129-
* @param array $headers
130+
* @param bool $writeHeaders
130131
* @return void
131132
*/
132-
private function doWrite(\Traversable $fileData, FileWriteInterface $stream, array $headers)
133+
private function doWrite(\Traversable $fileData, FileWriteInterface $stream, bool $writeHeaders = true): void
133134
{
134135
foreach ($fileData as $row) {
135-
if (!$headers) {
136+
if ($writeHeaders) {
136137
$headers = array_keys($row);
137138
$stream->writeCsv($headers);
139+
$writeHeaders = false;
138140
}
139141
$stream->writeCsv($this->prepareRow($row));
140142
}

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

Lines changed: 74 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Magento\Analytics\ReportXml\ReportProvider;
1515
use Magento\Framework\Filesystem\Directory\WriteInterface as DirectoryWriteInterface;
1616
use Magento\Framework\Filesystem\File\WriteInterface as FileWriteInterface;
17-
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
17+
use PHPUnit\Framework\Attributes\TestWith;
1818
use PHPUnit\Framework\MockObject\MockObject;
1919
use PHPUnit\Framework\TestCase;
2020

@@ -43,11 +43,6 @@ class ReportWriterTest extends TestCase
4343
*/
4444
private $reportProviderMock;
4545

46-
/**
47-
* @var ObjectManagerHelper
48-
*/
49-
private $objectManagerHelper;
50-
5146
/**
5247
* @var DirectoryWriteInterface|MockObject
5348
*/
@@ -58,111 +53,107 @@ class ReportWriterTest extends TestCase
5853
*/
5954
private $reportWriter;
6055

61-
/**
62-
* @var string
63-
*/
64-
private static $reportName = 'testReport';
65-
66-
/**
67-
* @var string
68-
*/
69-
private static $providerName = 'testProvider';
70-
71-
/**
72-
* @var string
73-
*/
74-
private static $providerClass = 'Magento\Analytics\Provider';
75-
76-
/**
77-
* @return void
78-
*/
7956
protected function setUp(): void
8057
{
81-
$this->configInterfaceMock = $this->getMockBuilder(ConfigInterface::class)
82-
->getMockForAbstractClass();
58+
$this->configInterfaceMock = $this->createMock(ConfigInterface::class);
8359
$this->reportValidatorMock = $this->createMock(ReportValidator::class);
8460
$this->providerFactoryMock = $this->createMock(ProviderFactory::class);
8561
$this->reportProviderMock = $this->createMock(ReportProvider::class);
86-
$this->directoryMock = $this->getMockBuilder(DirectoryWriteInterface::class)
87-
->getMockForAbstractClass();
88-
$this->objectManagerHelper = new ObjectManagerHelper($this);
62+
$this->directoryMock = $this->createMock(DirectoryWriteInterface::class);
8963

90-
$this->reportWriter = $this->objectManagerHelper->getObject(
91-
ReportWriter::class,
92-
[
93-
'config' => $this->configInterfaceMock,
94-
'reportValidator' => $this->reportValidatorMock,
95-
'providerFactory' => $this->providerFactoryMock
96-
]
64+
$this->reportWriter = new ReportWriter(
65+
$this->configInterfaceMock,
66+
$this->reportValidatorMock,
67+
$this->providerFactoryMock,
9768
);
9869
}
9970

10071
/**
101-
* @param array $configData
10272
* @param array $fileData
10373
* @param array $expectedFileData
104-
* @return void
105-
*
106-
* @dataProvider writeDataProvider
10774
*/
108-
public function testWrite(array $configData, array $fileData, array $expectedFileData): void
75+
#[
76+
TestWith([
77+
[[['number' => 1, 'type' => 'Shoes\"" Usual\\\\"']]],
78+
[['number' => 1, 'type' => 'Shoes"" Usual"']],
79+
]),
80+
TestWith([
81+
[[['number' => 1, 'type' => 'hello "World"']]],
82+
[['number' => 1, 'type' => 'hello "World"']],
83+
]),
84+
TestWith([
85+
[[['number' => 1, 'type' => 'hello \"World\"']]],
86+
[['number' => 1, 'type' => 'hello "World"']],
87+
]),
88+
TestWith([
89+
[[['number' => 1, 'type' => 'hello \\"World\\"']]],
90+
[['number' => 1, 'type' => 'hello "World"']],
91+
]),
92+
TestWith([
93+
[[['number' => 1, 'type' => 'hello \\\"World\\\"']]],
94+
[['number' => 1, 'type' => 'hello "World"']],
95+
]),
96+
TestWith([
97+
[
98+
[['number' => 1, 'type' => 'hello World 1']],
99+
[['number' => 2, 'type' => 'hello World 2']],
100+
],
101+
[
102+
['number' => 1, 'type' => 'hello World 1'],
103+
['number' => 2, 'type' => 'hello World 2'],
104+
],
105+
]),
106+
]
107+
public function testWrite(array $fileData, array $expectedFileData): void
109108
{
110-
$fileData = new \IteratorIterator(new \ArrayIterator($fileData));
111-
$emptyFileData = new \IteratorIterator(new \ArrayIterator([]));
112-
$errors = [];
113-
$this->configInterfaceMock
114-
->expects($this->once())
115-
->method('get')
116-
->with()
117-
->willReturn([$configData]);
118-
$this->providerFactoryMock
119-
->expects($this->once())
109+
$fileData[] = [];
110+
$dataBatches = array_map(fn (array $batch) => new \IteratorIterator(new \ArrayIterator($batch)), $fileData);
111+
array_unshift($expectedFileData, ['number', 'type']);
112+
113+
$configData = [];
114+
$providerClass = 'Magento\Analytics\Provider';
115+
$configData['providers'] = [
116+
[
117+
'name' => 'testProvider',
118+
'class' => $providerClass,
119+
'parameters' => ['name' => 'testReport'],
120+
],
121+
];
122+
123+
$this->configInterfaceMock->expects($this->once())->method('get')->with()->willReturn([$configData]);
124+
$this->providerFactoryMock->expects($this->once())
120125
->method('create')
121-
->with(self::$providerClass)
126+
->with($providerClass)
122127
->willReturn($this->reportProviderMock);
123128
$parameterName = isset(reset($configData)[0]['parameters']['name'])
124129
? reset($configData)[0]['parameters']['name']
125130
: '';
126-
$this->reportProviderMock->expects($this->exactly(2))
131+
$this->reportProviderMock->expects($this->exactly(count($dataBatches)))
127132
->method('getBatchReport')
128133
->with($parameterName ?: null)
129-
->willReturnOnConsecutiveCalls($fileData, $emptyFileData);
130-
$errorStreamMock = $this->getMockBuilder(
131-
FileWriteInterface::class
132-
)->getMockForAbstractClass();
133-
$errorStreamMock
134-
->expects($this->once())
135-
->method('lock')
136-
->with();
137-
$errorStreamMock
138-
->expects($this->exactly(2))
134+
->willReturnOnConsecutiveCalls(...$dataBatches);
135+
$errorStreamMock = $this->createMock(FileWriteInterface::class);
136+
$errorStreamMock->expects($this->once())->method('lock')->with()->willReturn(true);
137+
$errorStreamMock->expects($this->exactly(count($dataBatches))) //count of batches - empty batch + headers
139138
->method('writeCsv')
140-
->willReturnCallback(function (...$args) use ($expectedFileData) {
139+
->willReturnCallback(function (array $row) use ($expectedFileData) {
141140
static $index = 0;
142-
$expectedArgs = [
143-
[array_keys($expectedFileData[0])],
144-
[$expectedFileData[0]]
145-
];
146-
$index++;
147-
return $args === $expectedArgs[$index - 1] ? null : null;
141+
$this->assertEquals($expectedFileData[$index++], $row);
142+
return true;
148143
});
149144

150145
$errorStreamMock->expects($this->once())->method('unlock');
151146
$errorStreamMock->expects($this->once())->method('close');
152147
if ($parameterName) {
153-
$this->reportValidatorMock
154-
->expects($this->once())
148+
$this->reportValidatorMock->expects($this->once())
155149
->method('validate')
156150
->with($parameterName)
157-
->willReturn($errors);
151+
->willReturn([]);
158152
}
159-
$this->directoryMock
160-
->expects($this->once())
153+
$this->directoryMock->expects($this->once())
161154
->method('openFile')
162-
->with(
163-
$this->stringContains('/var/tmp' . $parameterName ?: $this->reportName),
164-
'w+'
165-
)->willReturn($errorStreamMock);
155+
->with($this->stringContains('/var/tmp' . $parameterName), 'w+')
156+
->willReturn($errorStreamMock);
166157
$this->assertTrue($this->reportWriter->write($this->directoryMock, '/var/tmp'));
167158
}
168159

@@ -176,9 +167,7 @@ public function testWriteErrorFile(array $configData): void
176167
{
177168
$errors = ['orders', 'SQL Error: test'];
178169
$this->configInterfaceMock->expects($this->once())->method('get')->willReturn([$configData]);
179-
$errorStreamMock = $this->getMockBuilder(
180-
FileWriteInterface::class
181-
)->getMockForAbstractClass();
170+
$errorStreamMock = $this->createMock(FileWriteInterface::class);
182171
$errorStreamMock->expects($this->once())->method('lock');
183172
$errorStreamMock->expects($this->once())->method('writeCsv')->with($errors);
184173
$errorStreamMock->expects($this->once())->method('unlock');
@@ -200,71 +189,6 @@ public function testWriteEmptyReports(): void
200189
$this->assertTrue($this->reportWriter->write($this->directoryMock, '/var/tmp'));
201190
}
202191

203-
/**
204-
* @return array
205-
*/
206-
public static function writeDataProvider(): array
207-
{
208-
$configData = [
209-
'providers' => [
210-
[
211-
'name' => self::$providerName,
212-
'class' => self::$providerClass,
213-
'parameters' => [
214-
'name' => self::$reportName
215-
],
216-
]
217-
]
218-
];
219-
return [
220-
[
221-
'configData' => $configData,
222-
'fileData' => [
223-
['number' => 1, 'type' => 'Shoes\"" Usual\\\\"']
224-
],
225-
'expectedFileData' => [
226-
['number' => 1, 'type' => 'Shoes"" Usual"']
227-
]
228-
],
229-
[
230-
'configData' => $configData,
231-
'fileData' => [
232-
['number' => 1, 'type' => 'hello "World"']
233-
],
234-
'expectedFileData' => [
235-
['number' => 1, 'type' => 'hello "World"']
236-
]
237-
],
238-
[
239-
'configData' => $configData,
240-
'fileData' => [
241-
['number' => 1, 'type' => 'hello \"World\"']
242-
],
243-
'expectedFileData' => [
244-
['number' => 1, 'type' => 'hello "World"']
245-
]
246-
],
247-
[
248-
'configData' => $configData,
249-
'fileData' => [
250-
['number' => 1, 'type' => 'hello \\"World\\"']
251-
],
252-
'expectedFileData' => [
253-
['number' => 1, 'type' => 'hello "World"']
254-
]
255-
],
256-
[
257-
'configData' => $configData,
258-
'fileData' => [
259-
['number' => 1, 'type' => 'hello \\\"World\\\"']
260-
],
261-
'expectedFileData' => [
262-
['number' => 1, 'type' => 'hello "World"']
263-
]
264-
],
265-
];
266-
}
267-
268192
/**
269193
* @return array
270194
*/
@@ -275,11 +199,9 @@ public static function writeErrorFileDataProvider(): array
275199
'configData' => [
276200
'providers' => [
277201
[
278-
'name' => self::$providerName,
279-
'class' => self::$providerClass,
280-
'parameters' => [
281-
'name' => self::$reportName
282-
],
202+
'name' => 'testProvider',
203+
'class' => 'Magento\Analytics\Provider',
204+
'parameters' => ['name' => 'testReport'],
283205
]
284206
]
285207
],

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
use Magento\Store\Model\Store;
2727
use Magento\Catalog\Model\ResourceModel\Category;
2828
use Zend_Db_Expr;
29-
use Magento\Catalog\Model\ResourceModel\Product\Gallery;
3029

3130
/**
3231
* Product collection
@@ -723,6 +722,10 @@ protected function _afterLoad()
723722
$this->_prepareUrlDataObject();
724723
$this->prepareStoreId();
725724

725+
if (isset($this->_selectAttributes['media_gallery'])) {
726+
$this->addMediaGalleryData();
727+
}
728+
726729
if (count($this)) {
727730
$this->_eventManager->dispatch('catalog_product_collection_load_after', ['collection' => $this]);
728731
}

0 commit comments

Comments
 (0)