Skip to content

Commit

Permalink
Use ModelManagerInteface::addIdentifiersToQuery()
Browse files Browse the repository at this point in the history
  • Loading branch information
phansys committed Sep 28, 2020
1 parent d02a65a commit f57b683
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 40 deletions.
6 changes: 4 additions & 2 deletions src/Form/DataTransformer/ModelToIdPropertyTransformer.php
Expand Up @@ -112,9 +112,11 @@ public function reverseTransform($value)
return '_labels' !== $key;
}, ARRAY_FILTER_USE_KEY);

$singleIdentifierFieldName = $this->modelManager->getIdentifierFieldNames($this->className)[0];
$query = $this->modelManager->createQuery($this->className);
$this->modelManager->addIdentifiersToQuery($this->className, $query, $ids);
$result = $this->modelManager->executeQuery($query);

foreach ($this->modelManager->findBy($this->className, [$singleIdentifierFieldName => $ids]) as $model) {
foreach ($result as $model) {
$collection->add($model);
}

Expand Down
13 changes: 5 additions & 8 deletions src/Form/DataTransformer/ModelsToArrayTransformer.php
Expand Up @@ -168,24 +168,21 @@ public function reverseTransform($value)
throw new UnexpectedTypeException($value, 'array');
}

/** @phpstan-var ArrayCollection<array-key, T> $collection */
$collection = $this->modelManager->getModelCollectionInstance($this->class);
$singleIdentifierFieldName = $this->modelManager->getIdentifierFieldNames($this->class)[0];
$result = $this->modelManager->findBy($this->class, [$singleIdentifierFieldName => $value]);
$query = $this->modelManager->createQuery($this->class);
$this->modelManager->addIdentifiersToQuery($this->class, $query, $value);
$result = $this->modelManager->executeQuery($query);

$diffCount = \count($value) - \count($result);

if (0 !== $diffCount) {
throw new TransformationFailedException(sprintf(
'%u keys could not be found in the provided values: "%s"',
'%u keys could not be found in the provided values: "%s".',
$diffCount,
implode('", "', $value)
));
}

return [];

return $collection;
return new ArrayCollection($result);
}

/**
Expand Down
53 changes: 23 additions & 30 deletions tests/Form/DataTransformer/ModelToIdPropertyTransformerTest.php
Expand Up @@ -14,7 +14,9 @@
namespace Sonata\AdminBundle\Tests\Form\DataTransformer;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use PHPUnit\Framework\TestCase;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Form\DataTransformer\ModelToIdPropertyTransformer;
use Sonata\AdminBundle\Model\ModelManagerInterface;
use Sonata\AdminBundle\Tests\Fixtures\Entity\Foo;
Expand Down Expand Up @@ -58,50 +60,43 @@ public function testReverseTransform(): void
*/
public function testReverseTransformMultiple(array $expected, $params, Foo $entity1, Foo $entity2, Foo $entity3): void
{
$transformer = new ModelToIdPropertyTransformer($this->modelManager, Foo::class, 'bar', true);

$this->modelManager
$modelManager = $this->createMock(ModelManagerInterface::class);
$transformer = new ModelToIdPropertyTransformer($modelManager, Foo::class, 'bar', true);
$proxyQuery = $this->createMock(ProxyQueryInterface::class);
$modelManager
->expects($this->exactly($params ? 1 : 0))
->method('getIdentifierFieldNames')
->willReturn(['id']);

$this->modelManager
->method('createQuery')
->with($this->equalTo(Foo::class))
->willReturn($proxyQuery);
$modelManager
->expects($this->exactly($params ? 1 : 0))
->method('findBy')
->willReturnCallback(static function (string $className, array $criteria) use ($entity1, $entity2, $entity3): array {
->method('executeQuery')
->with($this->equalTo($proxyQuery))
->willReturnCallback(static function (ProxyQueryInterface $query) use ($params, $entity1, $entity2, $entity3): array {
$collection = [];

if (Foo::class !== $className || !isset($criteria['id'])) {
return $collection;
}

if (\in_array(123, $criteria['id'], true)) {
if (\in_array(123, $params, true)) {
$collection[] = $entity1;
}

if (\in_array(456, $criteria['id'], true)) {
if (\in_array(456, $params, true)) {
$collection[] = $entity2;
}

if (\in_array(789, $criteria['id'], true)) {
if (\in_array(789, $params, true)) {
$collection[] = $entity3;
}

return $collection;
});

$collection = new ArrayCollection();
$this->modelManager
->method('getModelCollectionInstance')
->with($this->equalTo(Foo::class))
->willReturn($collection);

$result = $transformer->reverseTransform($params);
$this->assertInstanceOf(ArrayCollection::class, $result);
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(\count($expected), $result);
$this->assertSame($expected, $result->getValues());
}

public function getReverseTransformMultipleTests()
public function getReverseTransformMultipleTests(): iterable
{
$entity1 = new Foo();
$entity1->setBaz(123);
Expand All @@ -115,12 +110,10 @@ public function getReverseTransformMultipleTests()
$entity3->setBaz(789);
$entity3->setBar('example3');

return [
[[], null, $entity1, $entity2, $entity3],
[[], false, $entity1, $entity2, $entity3],
[[$entity1], [123, '_labels' => ['example']], $entity1, $entity2, $entity3],
[[$entity1, $entity2, $entity3], [123, 456, 789, '_labels' => ['example', 'example2', 'example3']], $entity1, $entity2, $entity3],
];
yield [[], null, $entity1, $entity2, $entity3];
yield [[], false, $entity1, $entity2, $entity3];
yield [[$entity1], [123, '_labels' => ['example']], $entity1, $entity2, $entity3];
yield [[$entity1, $entity2, $entity3], [123, 456, 789, '_labels' => ['example', 'example2', 'example3']], $entity1, $entity2, $entity3];
}

/**
Expand Down
87 changes: 87 additions & 0 deletions tests/Form/DataTransformer/ModelsToArrayTransformerTest.php
Expand Up @@ -13,11 +13,15 @@

namespace Sonata\AdminBundle\Tests\Form\DataTransformer;

use Doctrine\Common\Collections\Collection;
use PHPUnit\Framework\TestCase;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceLoader;
use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
use Sonata\AdminBundle\Model\ModelManagerInterface;
use Sonata\AdminBundle\Tests\Fixtures\Entity\Foo;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;

class ModelsToArrayTransformerTest extends TestCase
{
Expand All @@ -44,4 +48,87 @@ public function testLegacyConstructor(): void

$this->assertInstanceOf(ModelsToArrayTransformer::class, $transformer);
}

/**
* @dataProvider reverseTransformProvider
*/
public function testReverseTransform(?array $value): void
{
$modelManager = $this->createStub(ModelManagerInterface::class);

if (null !== $value) {
$proxyQuery = $this->createStub(ProxyQueryInterface::class);
$modelManager
->method('createQuery')
->with($this->equalTo(Foo::class))
->willReturn($proxyQuery);
$modelManager
->method('executeQuery')
->with($this->equalTo($proxyQuery))
->willReturn($value);
}

$transformer = new ModelsToArrayTransformer(
$modelManager,
Foo::class
);

$result = $transformer->reverseTransform($value);

if (null === $value) {
$this->assertNull($result);
} else {
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(\count($value), $result);
}
}

public function reverseTransformProvider(): iterable
{
yield [['a']];
yield [['a', 'b', 3]];
yield [null];
}

public function testReverseTransformUnexpectedType(): void
{
$value = 'unexpected';
$modelManager = $this->createStub(ModelManagerInterface::class);

$transformer = new ModelsToArrayTransformer(
$modelManager,
Foo::class
);

$this->expectException(UnexpectedTypeException::class);
$this->expectExceptionMessage('Expected argument of type "array", "string" given');

$transformer->reverseTransform($value);
}

public function testReverseTransformFailed(): void
{
$value = ['a', 'b'];
$reverseTransformCollection = ['a'];
$modelManager = $this->createStub(ModelManagerInterface::class);
$proxyQuery = $this->createStub(ProxyQueryInterface::class);
$modelManager
->method('createQuery')
->with($this->equalTo(Foo::class))
->willReturn($proxyQuery);
$modelManager
->method('executeQuery')
->with($this->equalTo($proxyQuery))
->willReturn($reverseTransformCollection);

$transformer = new ModelsToArrayTransformer(
$modelManager,
Foo::class
);

$this->expectException(TransformationFailedException::class);
$this->expectExceptionMessage('1 keys could not be found in the provided values: "a", "b".');

$transformer->reverseTransform($value);
}
}

0 comments on commit f57b683

Please sign in to comment.