Passed
Push — master ( 676de8...b86364 )
by Alex
57s queued 12s
created

IsEqualTest::testFilterWillApplyIsEqualFiltering()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 53
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 36
c 1
b 0
f 0
dl 0
loc 53
rs 9.344
cc 4
nc 8
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\DoctrineQueryFilter\Filter;
6
7
use Arp\DoctrineQueryFilter\Constant\WhereType;
8
use Arp\DoctrineQueryFilter\Filter\Exception\InvalidArgumentException;
9
use Arp\DoctrineQueryFilter\Filter\FilterInterface;
10
use Arp\DoctrineQueryFilter\Filter\IsEqual;
11
use Arp\DoctrineQueryFilter\Metadata\MetadataInterface;
12
use Arp\DoctrineQueryFilter\QueryBuilderInterface;
13
use Arp\DoctrineQueryFilter\QueryFilterManager;
14
use Doctrine\ORM\Query\Expr;
15
use PHPUnit\Framework\MockObject\MockObject;
16
use PHPUnit\Framework\TestCase;
17
18
/**
19
 * @author  Alex Patterson <[email protected]>
20
 * @package ArpTest\DoctrineQueryFilter\Filter
21
 */
22
final class IsEqualTest extends TestCase
23
{
24
    /**
25
     * @var QueryFilterManager|MockObject
26
     */
27
    private $queryFilterManager;
28
29
    /**
30
     * @var MetadataInterface|MockObject
31
     */
32
    private $metadata;
33
34
    /**
35
     * @var QueryBuilderInterface|MockObject
36
     */
37
    private $queryBuilder;
38
39
    /**
40
     * Prepare the test case dependencies
41
     */
42
    public function setUp(): void
43
    {
44
        $this->queryFilterManager = $this->createMock(QueryFilterManager::class);
45
46
        $this->metadata = $this->createMock(MetadataInterface::class);
47
48
        $this->queryBuilder = $this->createMock(QueryBuilderInterface::class);
49
    }
50
51
    /**
52
     * Assert that IsEqual implement FilterInterface
53
     */
54
    public function testImplementsFilterInterface(): void
55
    {
56
        $filter = new IsEqual($this->queryFilterManager);
57
58
        $this->assertInstanceOf(FilterInterface::class, $filter);
59
    }
60
61
    /**
62
     * @throws InvalidArgumentException
63
     */
64
    public function testFilterWillThrowInvalidArgumentExceptionIfTheRequiredFieldNameCriteriaIsMissing(): void
65
    {
66
        $filter = new IsEqual($this->queryFilterManager);
67
68
        $criteria = [
69
            // No field 'name' will raise exception
70
        ];
71
72
        $this->expectException(InvalidArgumentException::class);
73
        $this->expectExceptionMessage(
74
            sprintf(
75
                'The required \'field\' criteria value is missing for filter \'%s\'',
76
                IsEqual::class
77
            )
78
        );
79
80
        $filter->filter($this->queryBuilder, $this->metadata, $criteria);
81
    }
82
83
    /**
84
     * Assert that the IsEqual query filter can be applied with the provided $criteria
85
     *
86
     * @throws InvalidArgumentException
87
     */
88
    public function testFilterWillApplyIsEqualFiltering(): void
89
    {
90
        $filter = new IsEqual($this->queryFilterManager);
91
92
        $fieldName = 'FieldNameTest';
93
        $criteria = [
94
            'field'  => $fieldName,
95
            'alias'  => 'test',
96
            'where'  => WhereType::AND,
97
            'value'  => 123,
98
            'format' => null,
99
        ];
100
101
        $this->metadata->expects($this->once())
102
            ->method('hasField')
103
            ->with($fieldName)
104
            ->willReturn(true);
105
106
        /** @var Expr|MockObject $expr */
107
        $expr = $this->createMock(Expr::class);
108
109
        $this->queryBuilder->expects($this->once())
110
            ->method('expr')
111
            ->willReturn($expr);
112
113
        /** @var Expr\Comparison|MockObject $eq */
114
        $eq = $this->createMock(Expr\Comparison::class);
115
116
        $isEqualString = $criteria['alias'] . '.' . $fieldName . '=' . ':param_name';
117
        $expr->expects($this->once())
118
            ->method('eq')
119
            ->with($criteria['alias'] . '.' . $fieldName, $this->stringStartsWith(':'))
120
            ->willReturn($eq);
121
122
        $eq->expects($this->once())
123
            ->method('__toString')
124
            ->willReturn($isEqualString);
125
126
        $methodName = (!isset($criteria['where']) || WhereType::AND === $criteria['where'])
127
            ? 'andWhere'
128
            : 'orWhere';
129
130
        $this->queryBuilder->expects($this->once())->method($methodName);
131
132
        if (array_key_exists('value', $criteria)) {
133
            $this->queryBuilder->expects($this->once())
134
                ->method('setParameter')
135
                ->with($this->callback(static function ($argument) {
136
                    return is_string($argument);
137
                }), $criteria['value']);
138
        }
139
140
        $filter->filter($this->queryBuilder, $this->metadata, $criteria);
141
    }
142
}
143