Skip to content

Commit

Permalink
Add tests to ModelManager and DateFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
franmomu committed Jun 21, 2020
1 parent 7b8913f commit eb321c2
Show file tree
Hide file tree
Showing 15 changed files with 632 additions and 23 deletions.
44 changes: 36 additions & 8 deletions src/Filter/AbstractDateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Sonata\AdminBundle\Form\Type\Filter\DateTimeRangeType;
use Sonata\AdminBundle\Form\Type\Filter\DateTimeType;
use Sonata\AdminBundle\Form\Type\Filter\DateType;
use Sonata\AdminBundle\Form\Type\Operator\DateOperatorType;

abstract class AbstractDateFilter extends Filter
{
Expand Down Expand Up @@ -49,43 +50,47 @@ public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data)
$data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateType::TYPE_EQUAL : $data['type'];

// Some types do not require a value to be set (NULL, NOT NULL).
if (!$this->typeRequiresValue($data['type']) && !$data['value']) {
if (!isset($data['value']) && $this->typeDoesRequireValue($data['type'])) {
return;
}

switch ($data['type']) {
case DateType::TYPE_EQUAL:
$this->active = true;

$this->applyTypeIsEqual($queryBuilder, $field, $data);

return;

case DateType::TYPE_GREATER_THAN:
if (!\array_key_exists('value', $data) || !$data['value']) {
return;
}
$this->active = true;

$this->applyTypeIsGreaterThan($queryBuilder, $field, $data);

return;

case DateType::TYPE_LESS_EQUAL:
if (!\array_key_exists('value', $data) || !$data['value']) {
return;
}
$this->active = true;

$this->applyTypeIsLessEqual($queryBuilder, $field, $data);

return;

case DateType::TYPE_NULL:
case DateType::TYPE_NOT_NULL:
$this->active = true;

$this->applyType($queryBuilder, $this->getOperator($data['type']), $field, null);

return;

case DateType::TYPE_GREATER_EQUAL:
case DateType::TYPE_LESS_THAN:
$this->active = true;

$this->applyType($queryBuilder, $this->getOperator($data['type']), $field, $data['value']);

return;
}
}

Expand Down Expand Up @@ -119,26 +124,41 @@ public function getRenderSettings()
]];
}

abstract protected function applyTypeIsLessEqual(ProxyQueryInterface $queryBuilder, string $field, array $data);

abstract protected function applyTypeIsGreaterThan(ProxyQueryInterface $queryBuilder, string $field, array $data);

abstract protected function applyTypeIsEqual(ProxyQueryInterface $queryBuilder, string $field, array $data);

/**
* @param string $operation
* @param string $field
* @param \DateTime $datetime
*/
protected function applyType(ProxyQueryInterface $queryBuilder, $operation, $field, \DateTime $datetime = null)
protected function applyType(ProxyQueryInterface $queryBuilder, $operation, $field, ?\DateTime $datetime = null)
{
$queryBuilder->field($field)->$operation($datetime);
$this->active = true;
}

/**
* NEXT_MAJOR: Remove this method.
*
* Returns if the filter type requires a value to be set.
*
* @param int $type
*
* @deprecated since sonata-project/doctrine-mongodb-admin-bundle 3.x, to be removed in 4.0.'.
*
* @return bool
*/
protected function typeRequiresValue($type)
{
@trigger_error(
'"'.__METHOD__.'()" is deprecated since sonata-project/doctrine-mongodb-admin-bundle 3.x and will be removed in version 4.0.',
E_USER_DEPRECATED
);

return \in_array($type, [
DateType::TYPE_NULL,
DateType::TYPE_NOT_NULL,
Expand Down Expand Up @@ -166,4 +186,12 @@ protected function getOperator($type)

return $choices[(int) $type];
}

private function typeDoesRequireValue(int $type): bool
{
return !\in_array($type, [
DateOperatorType::TYPE_NULL,
DateOperatorType::TYPE_NOT_NULL,
], true);
}
}
6 changes: 6 additions & 0 deletions src/Filter/DateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
namespace Sonata\DoctrineMongoDBAdminBundle\Filter;

use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Symfony\Component\Form\Extension\Core\Type\DateType;

class DateFilter extends AbstractDateFilter
{
public function getFieldType(): string
{
return $this->getOption('field_type', DateType::class);
}

/**
* @param string $field
* @param array $data
Expand Down
6 changes: 6 additions & 0 deletions src/Filter/DateTimeFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Sonata\DoctrineMongoDBAdminBundle\Filter;

use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;

class DateTimeFilter extends AbstractDateFilter
{
Expand All @@ -24,6 +25,11 @@ class DateTimeFilter extends AbstractDateFilter
*/
protected $time = true;

public function getFieldType(): string
{
return $this->getOption('field_type', DateTimeType::class);
}

/**
* @param string $field
* @param array $data
Expand Down
18 changes: 14 additions & 4 deletions src/Model/ModelManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use Sonata\DoctrineMongoDBAdminBundle\Datagrid\ProxyQuery;
use Sonata\Exporter\Source\DoctrineODMQuerySourceIterator;
use Symfony\Bridge\Doctrine\ManagerRegistry;
use Symfony\Component\Form\Exception\PropertyAccessDeniedException;

class ModelManager implements ModelManagerInterface
{
Expand Down Expand Up @@ -363,6 +362,17 @@ public function getExportFields($class)
*/
public function getModelInstance($class)
{
$r = new \ReflectionClass($class);
if ($r->isAbstract()) {
throw new \InvalidArgumentException(sprintf('Cannot initialize abstract class: %s', $class));
}

$constructor = $r->getConstructor();

if (null !== $constructor && (!$constructor->isPublic() || $constructor->getNumberOfRequiredParameters() > 0)) {
return $r->newInstanceWithoutConstructor();
}

return new $class();
}

Expand Down Expand Up @@ -449,7 +459,7 @@ public function modelReverseTransform($class, array $array = [])

if ($reflClass->hasMethod($setter)) {
if (!$reflClass->getMethod($setter)->isPublic()) {
throw new PropertyAccessDeniedException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName()));
throw new \BadMethodCallException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName()));
}

$instance->$setter($value);
Expand All @@ -458,7 +468,7 @@ public function modelReverseTransform($class, array $array = [])
$instance->$property = $value;
} elseif ($reflClass->hasProperty($property)) {
if (!$reflClass->getProperty($property)->isPublic()) {
throw new PropertyAccessDeniedException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property)));
throw new \BadMethodCallException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property)));
}

$instance->$property = $value;
Expand Down Expand Up @@ -519,7 +529,7 @@ public function collectionRemoveElement(&$collection, &$element)
*/
protected function camelize($property)
{
return preg_replace(['/(^|_)+(.)/e', '/\.(.)/e'], ["strtoupper('\\2')", "'_'.strtoupper('\\1')"], $property);
return str_replace(' ', '', ucwords(str_replace('_', ' ', $property)));
}

private function isFieldAlreadySorted(FieldDescriptionInterface $fieldDescription, DatagridInterface $datagrid): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Util/ObjectAclManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ObjectAclManipulator extends BaseObjectAclManipulator
/**
* {@inheritdoc}
*/
public function batchConfigureAcls(OutputInterface $output, AdminInterface $admin, UserSecurityIdentity $securityIdentity = null)
public function batchConfigureAcls(OutputInterface $output, AdminInterface $admin, ?UserSecurityIdentity $securityIdentity = null)
{
$securityHandler = $admin->getSecurityHandler();
if (!$securityHandler instanceof AclSecurityHandlerInterface) {
Expand Down
81 changes: 81 additions & 0 deletions tests/Filter/DateTimeFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Filter;

use Sonata\AdminBundle\Form\Type\Filter\DateType;
use Sonata\DoctrineMongoDBAdminBundle\Datagrid\ProxyQuery;
use Sonata\DoctrineMongoDBAdminBundle\Filter\DateTimeFilter;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;

final class DateTimeFilterTest extends FilterWithQueryBuilderTest
{
public function testEmpty(): void
{
$filter = new DateTimeFilter();
$filter->initialize('field_name', ['field_options' => ['class' => 'FooBar']]);

$builder = new ProxyQuery($this->getQueryBuilder());

$builder->getQueryBuilder()
->expects($this->never())
->method('field')
;

$filter->filter($builder, 'alias', 'field', null);
$filter->filter($builder, 'alias', 'field', '');
$filter->filter($builder, 'alias', 'field', []);

$this->assertFalse($filter->isActive());
}

public function testGetType(): void
{
$this->assertSame(DateTimeType::class, (new DateTimeFilter())->getFieldType());
}

/**
* @dataProvider getExamples
*/
public function testFilter(array $data, string $method): void
{
$filter = new DateTimeFilter();
$filter->initialize('field_name', ['field_options' => ['class' => 'FooBar']]);

$builder = new ProxyQuery($this->getQueryBuilder());

$builder->getQueryBuilder()
->expects($this->once())
->method($method)
->with($data['value'] ?? null)
;

$filter->filter($builder, 'alias', 'field', $data);

$this->assertTrue($filter->isActive());
}

public function getExamples(): array
{
return [
[['type' => DateType::TYPE_EQUAL, 'value' => new \DateTime('now')], 'range'],
[['type' => DateType::TYPE_GREATER_EQUAL, 'value' => new \DateTime('now')], 'gte'],
[['type' => DateType::TYPE_GREATER_THAN, 'value' => new \DateTime('now')], 'gt'],
[['type' => DateType::TYPE_LESS_EQUAL, 'value' => new \DateTime('now')], 'lte'],
[['type' => DateType::TYPE_LESS_THAN, 'value' => new \DateTime('now')], 'lt'],
[['type' => DateType::TYPE_NULL], 'equals'],
[['type' => DateType::TYPE_NOT_NULL], 'notEqual'],
[['value' => new \DateTime('now')], 'range'],
];
}
}
2 changes: 1 addition & 1 deletion tests/Filter/FilterWithQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract class FilterWithQueryBuilderTest extends TestCase
private $queryBuilder;
private $expr;

public function setUp(): void
protected function setUp(): void
{
$this->queryBuilder = $this->createMock(Builder::class);
$this->queryBuilder
Expand Down
16 changes: 16 additions & 0 deletions tests/Fixtures/Document/AbstractDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document;

abstract class AbstractDocument
{
}
29 changes: 29 additions & 0 deletions tests/Fixtures/Document/AssociatedDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document;

class AssociatedDocument
{
private $plainField;
private $embeddedDocument;

public function __construct(int $plainField, EmbeddedDocument $embeddedDocument)
{
$this->plainField = $plainField;
$this->embeddedDocument = $embeddedDocument;
}

public function getPlainField(): int
{
return $this->plainField;
}
}
30 changes: 30 additions & 0 deletions tests/Fixtures/Document/ContainerDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document;

class ContainerDocument
{
private $plainField;
private $associatedDocument;
private $embeddedDocument;

public function __construct(AssociatedDocument $associatedDocument, EmbeddedDocument $embeddedDocument)
{
$this->associatedDocument = $associatedDocument;
$this->embeddedDocument = $embeddedDocument;
}

public function getAssociatedDocument(): AssociatedDocument
{
return $this->associatedDocument;
}
}
Loading

0 comments on commit eb321c2

Please sign in to comment.