Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue
- fix unit test - now it can test also not only full batches, but partial as well (139 images with batch size 100);
  • Loading branch information
vpodorozh committed Oct 27, 2018
1 parent 466daaa commit f6b0a2a
Showing 1 changed file with 109 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

class ImageTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
*/
protected $objectManager;

/**
* @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject
*/
Expand All @@ -31,41 +36,14 @@ class ImageTest extends \PHPUnit\Framework\TestCase
*/
protected $resourceMock;

/**
* @var Image
*/
protected $imageModel;

/**
* @var int
*/
protected $imagesCount = 50;

/**
* @var int
*/
protected $batchSize = 10;

protected function setUp(): void
{
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);

$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->connectionMock = $this->createMock(AdapterInterface::class);

$this->resourceMock = $this->createMock(ResourceConnection::class);
$this->resourceMock->method('getConnection')->willReturn($this->connectionMock);
$this->resourceMock->method('getTableName')->willReturnArgument(0);

$this->generatorMock = $this->createMock(Generator::class);

$this->imageModel = $objectManager->getObject(
Image::class,
[
'generator' => $this->generatorMock,
'resourceConnection' => $this->resourceMock,
'batchSize' => $this->batchSize
]
);
}

/**
Expand Down Expand Up @@ -93,7 +71,11 @@ protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_M
return $selectMock;
}

public function testGetCountAllProductImages(): void
/**
* @param int $imagesCount
* @dataProvider dataProvider
*/
public function testGetCountAllProductImages(int $imagesCount): void
{
$selectMock = $this->getVisibleImagesSelectMock();
$selectMock->expects($this->exactly(2))
Expand All @@ -113,59 +95,125 @@ public function testGetCountAllProductImages(): void
$this->connectionMock->expects($this->once())
->method('fetchOne')
->with($selectMock)
->willReturn($this->imagesCount);
->willReturn($imagesCount);

$imageModel = $this->objectManager->getObject(
Image::class,
[
'generator' => $this->generatorMock,
'resourceConnection' => $this->resourceMock
]
);

$this->assertSame($this->imagesCount, $this->imageModel->getCountAllProductImages());
$this->assertSame($imagesCount, $imageModel->getCountAllProductImages());
}

public function testGetAllProductImages(): void
/**
* @param int $imagesCount
* @param int $batchSize
* @dataProvider dataProvider
*/
public function testGetAllProductImages(int $imagesCount, int $batchSize): void
{
$getBatchIteratorMock = function ($selectMock, $imagesCount, $batchSize): array {
$result = [];
$count = $imagesCount / $batchSize;
while ($count) {
$count--;
$result[$count] = $selectMock;
}

return $result;
};

$getFetchResults = function ($batchSize): array {
$result = [];
$count = $batchSize;
while ($count) {
$count--;
$result[$count] = $count;
}

return $result;
};

$this->connectionMock->expects($this->once())
->method('select')
->willReturn($this->getVisibleImagesSelectMock());

$fetchResult = $getFetchResults($this->batchSize);
$this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize))
$batchCount = (int)ceil($imagesCount / $batchSize);
$fetchResultsCallback = $this->getFetchResultCallbackForBatches($imagesCount, $batchSize);
$this->connectionMock->expects($this->exactly($batchCount))
->method('fetchAll')
->willReturn($fetchResult);
->will($this->returnCallback($fetchResultsCallback));

/** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */
$selectMock = $this->getMockBuilder(Select::class)
->disableOriginalConstructor()
->getMock();

$batchIteratorMock = $getBatchIteratorMock($selectMock, $this->imagesCount, $this->batchSize);
$this->generatorMock->expects($this->once())
->method('generate')
->with(
'value_id',
$selectMock,
$this->batchSize,
$batchSize,
\Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR
)->willReturn($batchIteratorMock);
)->will($this->returnCallback($this->getBatchIteratorCallback($selectMock, $batchCount)));

$this->assertCount($this->imagesCount, $this->imageModel->getAllProductImages());
$imageModel = $this->objectManager->getObject(
Image::class,
[
'generator' => $this->generatorMock,
'resourceConnection' => $this->resourceMock,
'batchSize' => $batchSize
]
);

$this->assertCount($imagesCount, $imageModel->getAllProductImages());
}

/**
* @param int $imagesCount
* @param int $batchSize
* @return \Closure
*/
protected function getFetchResultCallbackForBatches(int $imagesCount, int $batchSize): \Closure
{
$fetchResultsCallback = function () use (&$imagesCount, $batchSize) {
$batchSize = ($imagesCount >= $batchSize) ? $batchSize : $imagesCount;
$imagesCount -= $batchSize;

$getFetchResults = function ($batchSize): array {
$result = [];
$count = $batchSize;
while ($count) {
$count--;
$result[$count] = $count;
}

return $result;
};

return $getFetchResults($batchSize);
};

return $fetchResultsCallback;
}

/**
* @param Select | \PHPUnit_Framework_MockObject_MockObject $selectMock
* @param int $batchCount
* @return \Closure
*/
protected function getBatchIteratorCallback(
\PHPUnit_Framework_MockObject_MockObject $selectMock,
int $batchCount
): \Closure
{
$getBatchIteratorCallback = function () use ($batchCount, $selectMock): array {
$result = [];
$count = $batchCount;
while ($count) {
$count--;
$result[$count] = $selectMock;
}

return $result;
};

return $getBatchIteratorCallback;
}

/**
* Data Provider
* @return array
*/
public function dataProvider(): array
{
return [
[300, 100],
[139, 100],
[67, 10],
[154, 47]
];
}
}

0 comments on commit f6b0a2a

Please sign in to comment.