Passed
Pull Request — master (#2)
by Alex
07:15
created

testFilterWillApplyIsNotEqualFiltering()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 58
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

140
            $this->typecaster->/** @scrutinizer ignore-call */ 
141
                               expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
141
                ->method('typecast')
142
                ->with($this->metadata, $fieldName, $criteria['value'])
143
                ->willReturn($criteria['value']);
144
145
            $this->queryBuilder->expects($this->once())
146
                ->method('setParameter')
147
                ->with($this->callback(static function ($argument) {
148
                    return is_string($argument);
149
                }), $criteria['value']);
150
        }
151
152
        $filter->filter($this->queryBuilder, $this->metadata, $criteria);
153
    }
154
}
155