Commit 323278ff authored by Адлан Шамавов's avatar Адлан Шамавов
Browse files

feat|tests: Добавлен фильтр Range и тесты

parent dd5de52a
Loading
Loading
Loading
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;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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();
    }
+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);
    }
}