diff --git a/src/Filter/Range.php b/src/Filter/Range.php new file mode 100644 index 0000000000000000000000000000000000000000..77e4e49029ff9c9ed27b1eb4ff06056f7fe2dee2 --- /dev/null +++ b/src/Filter/Range.php @@ -0,0 +1,21 @@ +where( + $this->getColumn() . '>= ' . $this->getHttpValue()['min'] . ' AND ' . + $this->getColumn() . ' <= ' . $this->getHttpValue()['max'], + ); + + return $queryBuilder; + } +} diff --git a/tests/Entity/Post.php b/tests/Entity/Post.php index 9983d381a9fbaa3ce25274ea341a7547d526af6c..50c2c0e85632bfdcf0600ac0667c0d4350831d65 100644 --- a/tests/Entity/Post.php +++ b/tests/Entity/Post.php @@ -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; @@ -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(); } diff --git a/tests/FilterByRangeTest.php b/tests/FilterByRangeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4ac9fb76c59c36c0e3c2bbf93029af71cb75714a --- /dev/null +++ b/tests/FilterByRangeTest.php @@ -0,0 +1,192 @@ +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); + } +}