From 323278ff5e77f6a7cabdedb249852b0861beff11 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Mon, 3 Mar 2025 10:58:33 +0500 Subject: [PATCH] =?UTF-8?q?feat|tests:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80=20Ran?= =?UTF-8?q?ge=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Filter/Range.php | 21 ++++ tests/Entity/Post.php | 5 + tests/FilterByRangeTest.php | 192 ++++++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 src/Filter/Range.php create mode 100644 tests/FilterByRangeTest.php diff --git a/src/Filter/Range.php b/src/Filter/Range.php new file mode 100644 index 0000000..77e4e49 --- /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 9983d38..50c2c0e 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 0000000..4ac9fb7 --- /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); + } +} -- GitLab