1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Tools\Pagination;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\Name\UnquotedIdentifierFolding;
use Doctrine\ORM\Decorator\EntityManagerDecorator;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\QueryException;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Tests\OrmTestCase;
use PHPUnit\Framework\Attributes\RequiresPhpunit;
use PHPUnit\Framework\MockObject\MockObject;
use function enum_exists;
#[RequiresPhpunit('< 12')]
class PaginatorTest extends OrmTestCase
{
private Connection&MockObject $connection;
private EntityManagerInterface&MockObject $em;
private AbstractHydrator&MockObject $hydrator;
protected function setUp(): void
{
$platform = $this->getMockBuilder(AbstractPlatform::class)
->setConstructorArgs(enum_exists(UnquotedIdentifierFolding::class) ? [UnquotedIdentifierFolding::UPPER] : [])
->onlyMethods(['supportsIdentityColumns'])
->getMockForAbstractClass();
$platform->method('supportsIdentityColumns')
->willReturn(true);
$driver = $this->createMock(Driver::class);
$driver->method('getDatabasePlatform')
->willReturn($platform);
$this->connection = $this->getMockBuilder(Connection::class)
->onlyMethods(['executeQuery'])
->setConstructorArgs([[], $driver])
->getMock();
$this->em = $this->getMockBuilder(EntityManagerDecorator::class)
->onlyMethods(['newHydrator'])
->setConstructorArgs([$this->createTestEntityManagerWithConnection($this->connection)])
->getMock();
$this->hydrator = $this->createMock(AbstractHydrator::class);
$this->em->method('newHydrator')->willReturn($this->hydrator);
}
public function testExtraParametersAreStrippedWhenWalkerRemovingOriginalSelectElementsIsUsed(): void
{
$paramInWhere = 1;
$paramInSubSelect = 2;
$returnedIds = [10];
$this->hydrator->method('hydrateAll')->willReturn([$returnedIds]);
$query = new Query($this->em);
$query->setDQL(
'SELECT u,
(
SELECT MAX(a.version)
FROM Doctrine\\Tests\\Models\\CMS\\CmsArticle a
WHERE a.user = u AND 1 = :paramInSubSelect
) AS HIDDEN max_version
FROM Doctrine\\Tests\\Models\\CMS\\CmsUser u
WHERE u.id = :paramInWhere',
);
$query->setParameters(['paramInWhere' => $paramInWhere, 'paramInSubSelect' => $paramInSubSelect]);
$query->setMaxResults(1);
$paginator = (new Paginator($query, true))->setUseOutputWalkers(false);
$receivedParams = [];
$resultMock = $this->createMock(Result::class);
$this->connection
->method('executeQuery')
->willReturnCallback(static function (string $sql, array $params) use (&$receivedParams, $resultMock): Result {
$receivedParams[] = $params;
return $resultMock;
});
$paginator->count();
$paginator->getIterator();
self::assertSame([
[$paramInWhere],
[$paramInWhere],
[$paramInSubSelect, $paramInWhere, $returnedIds],
], $receivedParams);
}
public function testPaginatorNotCaringAboutExtraParametersWithoutOutputWalkers(): void
{
$result = $this->getMockBuilder(Result::class)->disableOriginalConstructor()->getMock();
$this->connection->expects(self::exactly(3))->method('executeQuery')->willReturn($result);
$this->createPaginatorWithExtraParametersWithoutOutputWalkers([])->count();
$this->createPaginatorWithExtraParametersWithoutOutputWalkers([[10]])->count();
$this->createPaginatorWithExtraParametersWithoutOutputWalkers([])->getIterator();
}
public function testgetIteratorDoesCareAboutExtraParametersWithoutOutputWalkersWhenResultIsNotEmpty(): void
{
$result = $this->getMockBuilder(Result::class)->disableOriginalConstructor()->getMock();
$this->connection->expects(self::exactly(1))->method('executeQuery')->willReturn($result);
$this->expectException(QueryException::class);
$this->expectExceptionMessage('Too many parameters: the query defines 1 parameters and you bound 2');
$this->createPaginatorWithExtraParametersWithoutOutputWalkers([[10]])->getIterator();
}
/** @param int[][] $willReturnRows */
private function createPaginatorWithExtraParametersWithoutOutputWalkers(array $willReturnRows): Paginator
{
$this->hydrator->method('hydrateAll')->willReturn($willReturnRows);
$this->connection->method('executeQuery')->with(self::anything(), []);
$query = new Query($this->em);
$query->setDQL('SELECT u FROM Doctrine\\Tests\\Models\\CMS\\CmsUser u');
$query->setParameters(['paramInWhere' => 1]);
$query->setMaxResults(1);
return (new Paginator($query, true))->setUseOutputWalkers(false);
}
}
|