Skip to content

Commit

Permalink
[bug] RepositoryProxy::findOneBy() with $orderBy checks inner repo
Browse files Browse the repository at this point in the history
ObjectRepository::findOneBy() does not declare an $orderBy parameter
but some implementations (ie `Doctrine\ORM\EntityRepository`) add this.
When passed, it is ensured the wrapped repository has this parameter. If
not, a `\RuntimeException` is thrown instead of silently not ordering.

Fixes #65
  • Loading branch information
kbond committed Oct 21, 2020
1 parent 9302855 commit 537b2fd
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/RepositoryProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,22 @@ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $
}

/**
* @param array|null $orderBy Doctrine\ORM\EntityRepository adds this optional parameter
* @param array|null $orderBy Some ObjectRepository's (ie Doctrine\ORM\EntityRepository) add this optional parameter
*
* @return Proxy|object|null
*
* @throws \RuntimeException if the wrapped ObjectRepository does not have the $orderBy parameter
*/
public function findOneBy(array $criteria, ?array $orderBy = null): ?Proxy
{
if (\is_array($orderBy)) {
$wrappedParams = (new \ReflectionClass($this->repository))->getMethod('findOneBy')->getParameters();

if (!isset($wrappedParams[1]) || 'orderBy' !== $wrappedParams[1]->getName() || !$wrappedParams[1]->isArray()) {
throw new \RuntimeException(\sprintf('Wrapped repository\'s (%s) findOneBy method does not have an $orderBy parameter.', \get_class($this->repository)));
}
}

return $this->proxyResult($this->repository->findOneBy(self::normalizeCriteria($criteria), $orderBy));
}

Expand Down
117 changes: 117 additions & 0 deletions tests/Unit/RepositoryProxyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

namespace Zenstruck\Foundry\Tests\Unit;

use Doctrine\Persistence\ObjectRepository;
use PHPUnit\Framework\TestCase;
use Zenstruck\Foundry\RepositoryProxy;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class RepositoryProxyTest extends TestCase
{
/**
* @test
* @dataProvider objectRepositoryWithoutFindOneByOrderBy
*/
public function calling_find_one_by_with_order_by_when_wrapped_repo_does_not_have_throws_exception(ObjectRepository $inner): void
{
$proxy = new RepositoryProxy($inner);

$this->expectException(\RuntimeException::class);

$proxy->findOneBy([], ['id' => 'DESC']);
}

public static function objectRepositoryWithoutFindOneByOrderBy(): iterable
{
yield [new RepositoryProxy(new class() implements ObjectRepository {
public function find($id)
{
}

public function findAll()
{
}

public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
{
}

public function findOneBy(array $criteria)
{
}

public function getClassName()
{
}
})];

yield [new RepositoryProxy(new class() implements ObjectRepository {
public function find($id)
{
}

public function findAll()
{
}

public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
{
}

public function findOneBy(array $criteria, ?array $foo = null)
{
}

public function getClassName()
{
}
})];

yield [new RepositoryProxy(new class() implements ObjectRepository {
public function find($id)
{
}

public function findAll()
{
}

public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
{
}

public function findOneBy(array $criteria, $orderBy = null)
{
}

public function getClassName()
{
}
})];

yield [new RepositoryProxy(new class() implements ObjectRepository {
public function find($id)
{
}

public function findAll()
{
}

public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
{
}

public function findOneBy(array $criteria, ?string $orderBy = null)
{
}

public function getClassName()
{
}
})];
}
}

0 comments on commit 537b2fd

Please sign in to comment.