Loading src/Filter/Range.php 0 → 100644 +21 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace IQDEV\Packages\DoctrineHttpFilter\Filter; use Doctrine\ORM\QueryBuilder; use IQDEV\Packages\DoctrineHttpFilter\HttpFilter; final class Range extends HttpFilter { public function addToQuery(QueryBuilder $queryBuilder): QueryBuilder { $queryBuilder->where( $this->getColumn() . '>= ' . $this->getHttpValue()['min'] . ' AND ' . $this->getColumn() . ' <= ' . $this->getHttpValue()['max'], ); return $queryBuilder; } } tests/Entity/Post.php +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ class Post #[ORM\Column(name: 'updated_at', type: 'datetime_immutable', nullable: true)] public ?\DateTimeImmutable $updatedAt = null; #[ORM\Column(type: 'integer', nullable: true)] public ?int $countOfViews = null; #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post')] public Collection $comments; Loading @@ -41,12 +44,14 @@ class Post ?bool $moderated, ?\DateTimeImmutable $createdAt, ?\DateTimeImmutable $updatedAt = null, ?int $countOfViews = null ) { $this->title = $title; $this->content = $content; $this->moderated = $moderated; $this->createdAt = $createdAt; $this->updatedAt = $updatedAt; $this->countOfViews = $countOfViews; $this->comments = new ArrayCollection(); } Loading tests/FilterByRangeTest.php 0 → 100644 +192 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace IQDEV\Tests\Packages\DoctrineHttpFilter; use DateTimeImmutable; use IQDEV\Packages\DoctrineHttpFilter\Filter\DateRange; use IQDEV\Packages\DoctrineHttpFilter\Filter\Range; use IQDEV\Packages\DoctrineHttpFilter\HttpFilter; use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Post; use IQDEV\Tests\Packages\DoctrineHttpFilter\Repository\PostRepository; use Symfony\Component\HttpFoundation\Request; class FilterByRangeTest extends TestCase { public function testSuccessFilterRangeWithOneResult(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $countOfViews = 20; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $countOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 0, 'max' => 40, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(1, $result); } public function testSuccessFilterRangeWithSeveralResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 20; $secondCountOfViews = 35; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 10, 'max' => 40, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(2, $result); } public function testSuccessFilterRangeWithBoundaryResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 10; $secondCountOfViews = 15; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => $firstCountOfViews, 'max' => $secondCountOfViews, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(2, $result); } public function testSuccessFilterRangeWithoutResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 25; $secondCountOfViews = 35; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'createdAt' => DateRange::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 100, ], ], ])) ->getQuery() ->getResult(); $this->assertEmpty($result); } } Loading
src/Filter/Range.php 0 → 100644 +21 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace IQDEV\Packages\DoctrineHttpFilter\Filter; use Doctrine\ORM\QueryBuilder; use IQDEV\Packages\DoctrineHttpFilter\HttpFilter; final class Range extends HttpFilter { public function addToQuery(QueryBuilder $queryBuilder): QueryBuilder { $queryBuilder->where( $this->getColumn() . '>= ' . $this->getHttpValue()['min'] . ' AND ' . $this->getColumn() . ' <= ' . $this->getHttpValue()['max'], ); return $queryBuilder; } }
tests/Entity/Post.php +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ class Post #[ORM\Column(name: 'updated_at', type: 'datetime_immutable', nullable: true)] public ?\DateTimeImmutable $updatedAt = null; #[ORM\Column(type: 'integer', nullable: true)] public ?int $countOfViews = null; #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post')] public Collection $comments; Loading @@ -41,12 +44,14 @@ class Post ?bool $moderated, ?\DateTimeImmutable $createdAt, ?\DateTimeImmutable $updatedAt = null, ?int $countOfViews = null ) { $this->title = $title; $this->content = $content; $this->moderated = $moderated; $this->createdAt = $createdAt; $this->updatedAt = $updatedAt; $this->countOfViews = $countOfViews; $this->comments = new ArrayCollection(); } Loading
tests/FilterByRangeTest.php 0 → 100644 +192 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace IQDEV\Tests\Packages\DoctrineHttpFilter; use DateTimeImmutable; use IQDEV\Packages\DoctrineHttpFilter\Filter\DateRange; use IQDEV\Packages\DoctrineHttpFilter\Filter\Range; use IQDEV\Packages\DoctrineHttpFilter\HttpFilter; use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Post; use IQDEV\Tests\Packages\DoctrineHttpFilter\Repository\PostRepository; use Symfony\Component\HttpFoundation\Request; class FilterByRangeTest extends TestCase { public function testSuccessFilterRangeWithOneResult(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $countOfViews = 20; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $countOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 0, 'max' => 40, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(1, $result); } public function testSuccessFilterRangeWithSeveralResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 20; $secondCountOfViews = 35; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 10, 'max' => 40, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(2, $result); } public function testSuccessFilterRangeWithBoundaryResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 10; $secondCountOfViews = 15; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'countOfViews' => Range::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => $firstCountOfViews, 'max' => $secondCountOfViews, ], ], ])) ->getQuery() ->getResult(); $this->assertNotEmpty($result); $this->assertCount(2, $result); } public function testSuccessFilterRangeWithoutResults(): void { /** @var PostRepository $postRepository */ $postRepository = $this->em->getRepository(Post::class); $firstCountOfViews = 25; $secondCountOfViews = 35; $post = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $firstCountOfViews ); $post2 = new Post( $this->faker->name(), $this->faker->text(), $this->faker->boolean(), DateTimeImmutable::createFromInterface($this->faker->dateTime()), countOfViews: $secondCountOfViews ); $this->em->persist($post); $this->em->persist($post2); $this->em->flush(); $result = $postRepository->createQueryByFilter([ 'createdAt' => DateRange::class, ], new Request([ HttpFilter::REQUEST_FILTER_KEY => [ 'countOfViews' => [ 'min' => 100, ], ], ])) ->getQuery() ->getResult(); $this->assertEmpty($result); } }