Completed
Push — master ( 6b2632...1706e7 )
by
unknown
07:57 queued 10s
created

ChoiceFilterTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 267
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 5 1
A testFilterNullData() 0 6 1
A testFilterEmptyArrayData() 0 6 1
A testFilterEmptyArrayDataSpecifiedType() 0 6 1
A getMeaninglessValues() 0 11 1
A testFilterEmptyArrayDataWithMeaninglessValue() 0 5 1
A getFilters() 0 8 1
A testFilterSwitch() 0 14 1
B getFiltersMultiple() 0 154 1
A testFilterMultipleSwitch() 0 31 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrinePHPCRAdminBundle\Tests\Unit\Filter;
15
16
use Sonata\AdminBundle\Form\Type\Filter\ChoiceType;
17
use Sonata\DoctrinePHPCRAdminBundle\Filter\ChoiceFilter;
18
19
class ChoiceFilterTest extends BaseTestCase
20
{
21
    public function setUp(): void
22
    {
23
        parent::setUp();
24
        $this->filter = new ChoiceFilter();
0 ignored issues
show
Bug introduced by
The property filter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
25
    }
26
27
    public function testFilterNullData(): void
28
    {
29
        $res = $this->filter->filter($this->proxyQuery, null, 'somefield', null);
30
        $this->assertNull($res);
31
        $this->assertFalse($this->filter->isActive());
32
    }
33
34
    public function testFilterEmptyArrayData(): void
35
    {
36
        $res = $this->filter->filter($this->proxyQuery, null, 'somefield', []);
37
        $this->assertNull($res);
38
        $this->assertFalse($this->filter->isActive());
39
    }
40
41
    public function testFilterEmptyArrayDataSpecifiedType(): void
42
    {
43
        $res = $this->filter->filter($this->proxyQuery, null, 'somefield', ['type' => ChoiceType::TYPE_EQUAL]);
44
        $this->assertNull($res);
45
        $this->assertFalse($this->filter->isActive());
46
    }
47
48
    public function getMeaninglessValues()
49
    {
50
        return [
51
            ['  '],
52
            [null],
53
            [false],
54
            ['all'],
55
            [[]],
56
            [['', 'all']],
57
        ];
58
    }
59
60
    /**
61
     * @dataProvider getMeaninglessValues
62
     */
63
    public function testFilterEmptyArrayDataWithMeaninglessValue($value): void
64
    {
65
        $this->filter->filter($this->proxyQuery, null, 'somefield', ['type' => ChoiceType::TYPE_EQUAL, 'value' => $value]);
66
        $this->assertFalse($this->filter->isActive());
67
    }
68
69
    public function getFilters()
70
    {
71
        return [
72
            ['eq', ChoiceType::TYPE_EQUAL],
73
            ['textSearch', ChoiceType::TYPE_NOT_CONTAINS, '* -somevalue'],
74
            ['like', ChoiceType::TYPE_CONTAINS, '%somevalue%'],
75
        ];
76
    }
77
78
    /**
79
     * @dataProvider getFilters
80
     */
81
    public function testFilterSwitch($operatorMethod, $choiceType, $expectedValue = 'somevalue'): void
0 ignored issues
show
Unused Code introduced by
The parameter $operatorMethod is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expectedValue is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
82
    {
83
        $this->proxyQuery->expects($this->once())
0 ignored issues
show
Documentation Bug introduced by
The method expects does not exist on object<Sonata\DoctrinePH...le\Datagrid\ProxyQuery>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
84
            ->method('getQueryBuilder')
85
            ->willReturn($this->qb);
86
87
        $this->filter->filter(
88
            $this->proxyQuery,
89
            null,
90
            'somefield',
91
            ['type' => $choiceType, 'value' => 'somevalue']
92
        );
93
        $this->assertTrue($this->filter->isActive());
94
    }
95
96
    public function getFiltersMultiple()
97
    {
98
        return [
99
            [[
100
                'choiceType' => ChoiceType::TYPE_NOT_CONTAINS,
101
                'value' => 'somevalue',
102
                'qbNodeCount' => 6,
103
                'assertPaths' => [
104
                    'where.constraint.constraint[0].constraint.operand_dynamic' => [
105
                        'getAlias' => 'a',
106
                        'getField' => 'somefield',
107
                    ],
108
                    'where.constraint.constraint[0].constraint.operand_static' => [
109
                        'getValue' => '%somevalue%',
110
                    ],
111
                ],
112
            ]],
113
            [[
114
                'choiceType' => ChoiceType::TYPE_NOT_CONTAINS,
115
                'value' => ['somevalue', 'somevalue'],
116
                'qbNodeCount' => 10,
117
                'assertPaths' => [
118
                    'where.constraint.constraint.constraint.operand_dynamic' => [
119
                        'getAlias' => 'a',
120
                        'getField' => 'somefield',
121
                    ],
122
                    'where.constraint.constraint.constraint.operand_static' => [
123
                        'getValue' => '%somevalue%',
124
                    ],
125
                    'where.constraint.constraint[1].constraint.operand_dynamic' => [
126
                        'getAlias' => 'a',
127
                        'getField' => 'somefield',
128
                    ],
129
                    'where.constraint.constraint[1].constraint.operand_static' => [
130
                        'getValue' => '%somevalue%',
131
                    ],
132
                ],
133
            ]],
134
            [[
135
                'choiceType' => ChoiceType::TYPE_CONTAINS,
136
                'value' => 'somevalue',
137
                'qbNodeCount' => 5,
138
                'assertPaths' => [
139
                    'where.constraint.constraint.operand_dynamic' => [
140
                        'getAlias' => 'a',
141
                        'getField' => 'somefield',
142
                    ],
143
                    'where.constraint.constraint.operand_static' => [
144
                        'getValue' => '%somevalue%',
145
                    ],
146
                    'where.constraint.constraint.operand_static' => [
147
                        'getValue' => '%somevalue%',
148
                    ],
149
                ],
150
            ]],
151
            [[
152
                'choiceType' => ChoiceType::TYPE_CONTAINS,
153
                'value' => ['somevalue', 'somevalue'],
154
                'qbNodeCount' => 8,
155
                'assertPaths' => [
156
                    'where.constraint.constraint.operand_dynamic' => [
157
                        'getAlias' => 'a',
158
                        'getField' => 'somefield',
159
                    ],
160
                    'where.constraint.constraint.operand_static' => [
161
                        'getValue' => '%somevalue%',
162
                    ],
163
                    'where.constraint.constraint[1].operand_dynamic' => [
164
                        'getAlias' => 'a',
165
                        'getField' => 'somefield',
166
                    ],
167
                    'where.constraint.constraint[1].operand_static' => [
168
                        'getValue' => '%somevalue%',
169
                    ],
170
                ],
171
            ]],
172
            [[
173
                'choiceType' => ChoiceType::TYPE_CONTAINS,
174
                'value' => 'somevalue',
175
                'qbNodeCount' => 5,
176
                'assertPaths' => [
177
                    'where.constraint.constraint.operand_dynamic' => [
178
                        'getAlias' => 'a',
179
                        'getField' => 'somefield',
180
                    ],
181
                    'where.constraint.constraint.operand_static' => [
182
                        'getValue' => '%somevalue%',
183
                    ],
184
                    'where.constraint.constraint.operand_static' => [
185
                        'getValue' => '%somevalue%',
186
                    ],
187
                ],
188
            ]],
189
            [[
190
                'choiceType' => ChoiceType::TYPE_CONTAINS,
191
                'value' => ['somevalue', 'somevalue'],
192
                'qbNodeCount' => 8,
193
                'assertPaths' => [
194
                    'where.constraint.constraint.operand_dynamic' => [
195
                        'getAlias' => 'a',
196
                        'getField' => 'somefield',
197
                    ],
198
                    'where.constraint.constraint.operand_static' => [
199
                        'getValue' => '%somevalue%',
200
                    ],
201
                    'where.constraint.constraint[1].operand_dynamic' => [
202
                        'getAlias' => 'a',
203
                        'getField' => 'somefield',
204
                    ],
205
                    'where.constraint.constraint[1].operand_static' => [
206
                        'getValue' => '%somevalue%',
207
                    ],
208
                ],
209
            ]],
210
            [[
211
                'choiceType' => ChoiceType::TYPE_EQUAL,
212
                'value' => 'somevalue',
213
                'qbNodeCount' => 5,
214
                'assertPaths' => [
215
                    'where.constraint.constraint.operand_dynamic' => [
216
                        'getAlias' => 'a',
217
                        'getField' => 'somefield',
218
                    ],
219
                    'where.constraint.constraint.operand_static' => [
220
                        'getValue' => 'somevalue',
221
                    ],
222
                    'where.constraint.constraint.operand_static' => [
223
                        'getValue' => 'somevalue',
224
                    ],
225
                ],
226
            ]],
227
            [[
228
                'choiceType' => ChoiceType::TYPE_EQUAL,
229
                'value' => ['somevalue', 'somevalue'],
230
                'qbNodeCount' => 8,
231
                'assertPaths' => [
232
                    'where.constraint.constraint.operand_dynamic' => [
233
                        'getAlias' => 'a',
234
                        'getField' => 'somefield',
235
                    ],
236
                    'where.constraint.constraint.operand_static' => [
237
                        'getValue' => 'somevalue',
238
                    ],
239
                    'where.constraint.constraint[1].operand_dynamic' => [
240
                        'getAlias' => 'a',
241
                        'getField' => 'somefield',
242
                    ],
243
                    'where.constraint.constraint[1].operand_static' => [
244
                        'getValue' => 'somevalue',
245
                    ],
246
                ],
247
            ]],
248
        ];
249
    }
250
251
    /**
252
     * @dataProvider getFiltersMultiple
253
     */
254
    public function testFilterMultipleSwitch($options): void
255
    {
256
        $options = array_merge([
257
            'choiceType' => null,
258
            'value' => null,
259
            'assertPaths' => [],
260
            'qbNodeCount' => 0,
261
        ], $options);
262
263
        $this->proxyQuery->expects($this->once())
0 ignored issues
show
Documentation Bug introduced by
The method expects does not exist on object<Sonata\DoctrinePH...le\Datagrid\ProxyQuery>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
264
            ->method('getQueryBuilder')
265
            ->willReturn($this->qb);
266
267
        $this->filter->filter(
268
            $this->proxyQuery,
269
            null,
270
            'somefield',
271
            ['type' => $options['choiceType'], 'value' => $options['value']]
272
        );
273
274
        foreach ($options['assertPaths'] as $path => $methodAssertions) {
0 ignored issues
show
Bug introduced by
The expression $options['assertPaths'] of type null|array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
275
            $node = $this->qbTester->getNode($path);
276
            foreach ($methodAssertions as $methodName => $expectedValue) {
277
                $res = $node->$methodName();
278
                $this->assertSame($expectedValue, $res);
279
            }
280
        }
281
282
        $this->assertTrue($this->filter->isActive());
283
        $this->assertSame($options['qbNodeCount'], \count($this->qbTester->getAllNodes()));
284
    }
285
}
286