Completed
Branch develop (8fea8e)
by Denis
04:45
created

QueryFilterTest::testAliases()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 63
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 50
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 63
ccs 0
cts 59
cp 0
crap 2
rs 9.0909

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 declare(strict_types=1);
2
3
namespace Tests\Unit\Artprima\QueryFilterBundle\QueryFilter;
4
5
use Artprima\QueryFilterBundle\Exception\InvalidArgumentException;
6
use Artprima\QueryFilterBundle\Exception\MissingArgumentException;
7
use Artprima\QueryFilterBundle\Exception\UnexpectedValueException;
8
use Artprima\QueryFilterBundle\Query\Filter;
9
use Artprima\QueryFilterBundle\QueryFilter\Config\Alias;
10
use Artprima\QueryFilterBundle\QueryFilter\Config\BaseConfig;
11
use Artprima\QueryFilterBundle\QueryFilter\QueryFilter;
12
use Artprima\QueryFilterBundle\QueryFilter\QueryFilterArgs;
13
use Artprima\QueryFilterBundle\QueryFilter\QueryResult;
14
use Artprima\QueryFilterBundle\Request\Request;
15
use Artprima\QueryFilterBundle\Response\Response;
16
use PHPUnit\Framework\TestCase;
17
use Tests\Unit\Artprima\QueryFilterBundle\Fixtures\Response\ResponseConstructorWithRequiredArguments;
18
use Tests\Unit\Artprima\QueryFilterBundle\Fixtures\Response\ResponseNotImplementingResponseInterface;
19
use Symfony\Component\HttpFoundation\Request as HttpRequest;
20
21
class QueryFilterTest extends TestCase
22
{
23
    /**
24
     * @test
25
     * @doesNotPerformAssertions
26
     */
27
    public function constructor_should_throw_no_exceptions_with_proper_argument()
28
    {
29
        new QueryFilter(Response::class);
30
    }
31
32
    /**
33
     * @test
34
     */
35
    public function constructor_should_throw_exception_for_response_not_implementing_ResponseInterface()
36
    {
37
        $this->expectException(InvalidArgumentException::class);
38
        $this->expectExceptionMessage(
39
            "Response class \"Tests\Unit\Artprima\QueryFilterBundle\Fixtures\Response\ResponseNotImplementingResponseInterface\" must implement \"Artprima\QueryFilterBundle\Response\ResponseInterface\""
40
        );
41
        new QueryFilter(ResponseNotImplementingResponseInterface::class);
42
    }
43
44
    /**
45
     * @test
46
     */
47
    public function constructor_should_throw_exception_for_response_constructor_having_required_arguments()
48
    {
49
        $this->expectException(InvalidArgumentException::class);
50
        $this->expectExceptionMessage(
51
            "Response class \"Tests\Unit\Artprima\QueryFilterBundle\Fixtures\Response\ResponseConstructorWithRequiredArguments\" must have a constructor without required parameters"
52
        );
53
        new QueryFilter(ResponseConstructorWithRequiredArguments::class);
54
    }
55
56
    public function testGetDataSimpleBaseCase()
57
    {
58
        $queryFilter = new QueryFilter(Response::class);
59
60
        $config = new BaseConfig();
61
        $request = new Request(new HttpRequest([
62
            'limit' => 100,
63
            'page'=> 3,
64
            'filter' => [
65
                'c.dummy' => 'the road to hell',
66
            ],
67
            'sortby' => 'c.id',
68
            'sortdir' => 'asc',
69
        ]));
70
        $config->setRequest($request);
71
        $config->setSearchAllowedCols(['c.dummy']);
72
        $config->setSortCols(['c.id']);
73
        $config->setAllowedLimits([10, 15, 100]);
74
        $config->setDefaultLimit(10);
75
76
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
77
            self::assertSame(100, $args->getLimit());
78
            self::assertSame(200, $args->getOffset());
79
            self::assertEquals([
80
                (new Filter())
81
                    ->setField('c.dummy')
82
                    ->setType('like')
83
                    ->setX('the road to hell'),
84
            ], $args->getSearchBy());
85
            self::assertEquals([
86
                'c.id' => 'asc',
87
            ], $args->getSortBy());
88
89
            return new QueryResult([
90
                ["dummy"],
91
                ["wammy"],
92
            ], 1000);
93
        });
94
        $response = $queryFilter->getData($config);
95
        self::assertEquals([
96
            ["dummy"],
97
            ["wammy"],
98
        ], $response->getData());
99
        self::assertSame(1000, $response->getMeta()['total_records']);
100
    }
101
102
    public function testGetDataSimpleBaseCaseNoSortColSet()
103
    {
104
        $queryFilter = new QueryFilter(Response::class);
105
106
        $config = new BaseConfig();
107
        $request = new Request(new HttpRequest([
108
            'limit' => 100,
109
            'page'=> 3,
110
            'filter' => [
111
                'c.dummy' => 'the road to hell',
112
            ],
113
        ]));
114
        $config->setRequest($request);
115
        $config->setSearchAllowedCols(['c.dummy']);
116
        $config->setSortCols(['c.id'], ['c.id' => 'asc']);
117
        $config->setAllowedLimits([10, 15, 100]);
118
        $config->setDefaultLimit(10);
119
120
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
121
            self::assertSame(100, $args->getLimit());
122
            self::assertSame(200, $args->getOffset());
123
            self::assertEquals([
124
                (new Filter())
125
                    ->setField('c.dummy')
126
                    ->setType('like')
127
                    ->setX('the road to hell'),
128
            ], $args->getSearchBy());
129
            self::assertEquals([
130
                'c.id' => 'asc',
131
            ], $args->getSortBy());
132
133
            return new QueryResult([
134
                ["dummy"],
135
                ["wammy"],
136
            ], 1000);
137
        });
138
        $response = $queryFilter->getData($config);
139
        self::assertEquals([
140
            ["dummy"],
141
            ["wammy"],
142
        ], $response->getData());
143
        self::assertSame(1000, $response->getMeta()['total_records']);
144
    }
145
146
    public function testGetDataInvalidSimpleFilterWithThrow()
147
    {
148
        self::expectException(UnexpectedValueException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

148
        self::/** @scrutinizer ignore-call */ 
149
              expectException(UnexpectedValueException::class);
Loading history...
149
        $queryFilter = new QueryFilter(Response::class);
150
151
        $config = new BaseConfig();
152
        $request = new Request(new HttpRequest([
153
            'filter' => [
154
                'c.knownColumn' => 'shla sasha po shosse i sosala sushku',
155
                'c.unknownColumn' => 'the road to hell',
156
            ],
157
        ]));
158
        $config->setRequest($request);
159
        $config->setSearchAllowedCols(['c.knownColumn']);
160
        $config->setStrictColumns(true);
161
162
        $queryFilter->getData($config);
163
    }
164
165
    public function testGetDataInvalidFullFilterWithThrow()
166
    {
167
        self::expectException(UnexpectedValueException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

167
        self::/** @scrutinizer ignore-call */ 
168
              expectException(UnexpectedValueException::class);
Loading history...
168
        self::expectExceptionMessage('Invalid filter column requested t.unknownColumn');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

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

168
        self::/** @scrutinizer ignore-call */ 
169
              expectExceptionMessage('Invalid filter column requested t.unknownColumn');
Loading history...
169
        $queryFilter = new QueryFilter(Response::class);
170
171
        $config = new BaseConfig();
172
        $request = new Request(new HttpRequest([
173
            'simple' => 0,
174
            'filter' => [
175
                [
176
                    'field' => 't.knownColumn',
177
                    'type' => 'eq',
178
                    'x' => 'shla sasha po shosse i sosala sushku'
179
                ],
180
                [
181
                    'field' => 't.unknownColumn',
182
                    'type' => 'eq',
183
                    'x' => 'the road to hell'
184
                ]
185
            ],
186
        ]));
187
        $config->setRequest($request);
188
        $config->setSearchAllowedCols(['t.knownColumn']);
189
        $config->setStrictColumns(true);
190
191
        $queryFilter->getData($config);
192
    }
193
194
    public function testGetDataInvalidFullFilterFormatWithThrow()
195
    {
196
        self::expectException(UnexpectedValueException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

196
        self::/** @scrutinizer ignore-call */ 
197
              expectException(UnexpectedValueException::class);
Loading history...
197
        self::expectExceptionMessage('Invalid filter column requested [1]');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

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

197
        self::/** @scrutinizer ignore-call */ 
198
              expectExceptionMessage('Invalid filter column requested [1]');
Loading history...
198
        $queryFilter = new QueryFilter(Response::class);
199
200
        $config = new BaseConfig();
201
        $request = new Request(new HttpRequest([
202
            'simple' => 0,
203
            'filter' => [
204
                [
205
                    'field' => 't.knownColumn',
206
                    'type' => 'eq',
207
                    'x' => 'shla sasha po shosse i sosala sushku'
208
                ],
209
                't.unknownColumn',
210
            ],
211
        ]));
212
        $config->setRequest($request);
213
        $config->setSearchAllowedCols(['t.knownColumn']);
214
        $config->setStrictColumns(true);
215
216
        $queryFilter->getData($config);
217
    }
218
219
    public function testGetDataInvalidSimpleFilterWithoutThrow()
220
    {
221
        $queryFilter = new QueryFilter(Response::class);
222
223
        $config = new BaseConfig();
224
        $request = new Request(new HttpRequest([
225
            'filter' => [
226
                't.knownColumn' => 'shla sasha po shosse i sosala sushku',
227
                't.unknownColumn' => 'the road to hell', // will be ignored
228
            ],
229
        ]));
230
        $config->setRequest($request);
231
        $config->setSearchAllowedCols(['t.knownColumn']);
232
        $config->setStrictColumns(false);
233
234
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
235
            self::assertEquals([
236
                (new Filter())
237
                    ->setField('t.knownColumn')
238
                    ->setType('like')
239
                    ->setX('shla sasha po shosse i sosala sushku'),
240
            ], $args->getSearchBy());
241
            return new QueryResult([
242
                ["dummy"],
243
                ["wammy"],
244
            ], 1000);
245
        });
246
        $response = $queryFilter->getData($config);
247
        self::assertEquals([
248
            ["dummy"],
249
            ["wammy"],
250
        ], $response->getData());
251
    }
252
253
    public function testGetDataInvalidFullFilterWithoutThrow()
254
    {
255
        $queryFilter = new QueryFilter(Response::class);
256
257
        $config = new BaseConfig();
258
        $request = new Request(new HttpRequest([
259
            'simple' => 0,
260
            'filter' => [
261
                [
262
                    'field' => 't.knownColumn',
263
                    'type' => 'eq',
264
                    'x' => 'shla sasha po shosse i sosala sushku'
265
                ],
266
                [ // will be ignored
267
                    'field' => 't.unknownColumn',
268
                    'type' => 'eq',
269
                    'x' => 'the road to hell'
270
                ]
271
            ],
272
        ]));
273
        $config->setRequest($request);
274
        $config->setSearchAllowedCols(['t.knownColumn']);
275
        $config->setStrictColumns(false);
276
277
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
278
            self::assertEquals([
279
                (new Filter())
280
                    ->setField('t.knownColumn')
281
                    ->setType('eq')
282
                    ->setX('shla sasha po shosse i sosala sushku'),
283
            ], $args->getSearchBy());
284
            return new QueryResult([
285
                ["dummy"],
286
                ["wammy"],
287
            ], 1000);
288
        });
289
        $response = $queryFilter->getData($config);
290
        self::assertEquals([
291
            ["dummy"],
292
            ["wammy"],
293
        ], $response->getData());
294
    }
295
296
    public function testGetDataInvalidFullFilterFormatWithoutThrow()
297
    {
298
        $queryFilter = new QueryFilter(Response::class);
299
300
        $config = new BaseConfig();
301
        $request = new Request(new HttpRequest([
302
            'simple' => 0,
303
            'filter' => [
304
                [
305
                    'field' => 't.knownColumn',
306
                    'type' => 'eq',
307
                    'x' => 'shla sasha po shosse i sosala sushku'
308
                ],
309
                't.unknownColumn', // will be ignored
310
            ],
311
        ]));
312
        $config->setRequest($request);
313
        $config->setSearchAllowedCols(['t.knownColumn']);
314
        $config->setStrictColumns(false);
315
316
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
317
            self::assertEquals([
318
                (new Filter())
319
                    ->setField('t.knownColumn')
320
                    ->setType('eq')
321
                    ->setX('shla sasha po shosse i sosala sushku'),
322
            ], $args->getSearchBy());
323
            return new QueryResult([
324
                ["dummy"],
325
                ["wammy"],
326
            ], 1000);
327
        });
328
        $response = $queryFilter->getData($config);
329
        self::assertEquals([
330
            ["dummy"],
331
            ["wammy"],
332
        ], $response->getData());
333
    }
334
335
    public function testGetDataInvalidRepositoryCallback()
336
    {
337
        self::expectException(MissingArgumentException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

337
        self::/** @scrutinizer ignore-call */ 
338
              expectException(MissingArgumentException::class);
Loading history...
338
        self::expectExceptionMessage('Repository callback is not set');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

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

338
        self::/** @scrutinizer ignore-call */ 
339
              expectExceptionMessage('Repository callback is not set');
Loading history...
339
        $queryFilter = new QueryFilter(Response::class);
340
341
        $config = new BaseConfig();
342
        $request = new Request(new HttpRequest([
343
            'simple' => 0,
344
            'filter' => [
345
                [
346
                    'field' => 't.knownColumn',
347
                    'type' => 'eq',
348
                    'x' => 'shla sasha po shosse i sosala sushku'
349
                ],
350
            ],
351
        ]));
352
        $config->setRequest($request);
353
        $config->setSearchAllowedCols(['t.knownColumn']);
354
        $queryFilter->getData($config);
355
    }
356
357
    public function testGetDataInvalidSortColumn()
358
    {
359
        self::expectException(UnexpectedValueException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

359
        self::/** @scrutinizer ignore-call */ 
360
              expectException(UnexpectedValueException::class);
Loading history...
360
        self::expectExceptionMessage('Invalid sort column requested c.invalidColumn');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

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

360
        self::/** @scrutinizer ignore-call */ 
361
              expectExceptionMessage('Invalid sort column requested c.invalidColumn');
Loading history...
361
        $queryFilter = new QueryFilter(Response::class);
362
363
        $config = new BaseConfig();
364
        $request = new Request(new HttpRequest([
365
            'sortby' => 'c.invalidColumn',
366
            'sortdir' => 'asc',
367
        ]));
368
        $config->setRequest($request);
369
        $config->setSortCols(['c.id']);
370
        $config->setStrictColumns(true);
371
372
        $queryFilter->getData($config);
373
    }
374
375
    public function testGetDataInvalidSortColumnType()
376
    {
377
        self::expectException(UnexpectedValueException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

377
        self::/** @scrutinizer ignore-call */ 
378
              expectException(UnexpectedValueException::class);
Loading history...
378
        self::expectExceptionMessage('Invalid sort type requested to_the_left');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

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

378
        self::/** @scrutinizer ignore-call */ 
379
              expectExceptionMessage('Invalid sort type requested to_the_left');
Loading history...
379
        $queryFilter = new QueryFilter(Response::class);
380
381
        $config = new BaseConfig();
382
        $request = new Request(new HttpRequest([
383
            'sortby' => 'c.id',
384
            'sortdir' => 'to_the_left',
385
        ]));
386
        $config->setRequest($request);
387
        $config->setSortCols(['c.id']);
388
        $config->setStrictColumns(true);
389
390
        $queryFilter->getData($config);
391
    }
392
393
    public function testGetDataAdvancedBaseCase()
394
    {
395
        $queryFilter = new QueryFilter(Response::class);
396
397
        $config = new BaseConfig();
398
        $request = new Request(new HttpRequest([
399
            'limit' => 100,
400
            'page'=> 3,
401
            'filter' => [
402
                [
403
                    'field' => 'c.hell',
404
                    'type' => 'eq',
405
                    'x' => 'the road to hell',
406
                ],
407
                [
408
                    'field' => 'c.heaven',
409
                    'type' => 'like',
410
                    'x' => 'the road to heaven',
411
                ],
412
                [
413
                    'field' => 'c.latency',
414
                    'type' => 'between',
415
                    'x' => '10',
416
                    'y' => '100',
417
                ],
418
                [
419
                    'field' => 'c.hell',
420
                    'type' => 'like',
421
                    'x' => 'the road to hell',
422
                    'connector' => 'or',
423
                    'extra' => 'exact',
424
                ],
425
            ],
426
            'sortby' => 'c.id',
427
            'sortdir' => 'asc',
428
            'simple' => '0',
429
        ]));
430
        $config->setRequest($request);
431
        $config->setSearchAllowedCols(['c.hell', 'c.heaven', 'c.latency']);
432
        $config->setSortCols(['c.id']);
433
        $config->setAllowedLimits([10, 15, 100]);
434
        $config->setDefaultLimit(10);
435
436
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
437
            self::assertSame(100, $args->getLimit());
438
            self::assertSame(200, $args->getOffset());
439
            self::assertEquals([
440
                (new Filter())
441
                    ->setField('c.hell')
442
                    ->setType('eq')
443
                    ->setX('the road to hell'),
444
                (new Filter())
445
                    ->setField('c.heaven')
446
                    ->setType('like')
447
                    ->setX('the road to heaven'),
448
                (new Filter())
449
                    ->setField('c.latency')
450
                    ->setType('between')
451
                    ->setX('10')
452
                    ->setY('100'),
453
                (new Filter())
454
                    ->setField('c.hell')
455
                    ->setType('like')
456
                    ->setX('the road to hell')
457
                    ->setExtra('exact')
458
                    ->setConnector('or')
459
            ], $args->getSearchBy());
460
            self::assertEquals([
461
                'c.id' => 'asc',
462
            ], $args->getSortBy());
463
464
            return new QueryResult([
465
                ["dummy"],
466
                ["wammy"],
467
            ], 1000);
468
        });
469
        $response = $queryFilter->getData($config);
470
        self::assertEquals([
471
            ["dummy"],
472
            ["wammy"],
473
        ], $response->getData());
474
        self::assertSame(1000, $response->getMeta()['total_records']);
475
    }
476
477
    public function testAliases()
478
    {
479
        $queryFilter = new QueryFilter(Response::class);
480
481
        $config = new BaseConfig();
482
        $request = new Request(new HttpRequest([
483
            'limit' => 100,
484
            'page'=> 3,
485
            'filter' => [
486
                [
487
                    'field' => 'fullname',
488
                    'type' => 'eq',
489
                    'x' => 'Vassily Poupkine',
490
                    'having' => '1',
491
                ],
492
                [
493
                    'field' => 'c.heaven',
494
                    'type' => 'like',
495
                    'x' => 'the road to heaven',
496
                ],
497
            ],
498
            'sortby' => 'c.id',
499
            'sortdir' => 'asc',
500
            'simple' => '0',
501
        ]));
502
        $config->setRequest($request);
503
        $config->setSearchAllowedCols(['fullname', 'c.heaven']);
504
        $config->setSortCols(['c.id']);
505
        $config->setAllowedLimits([10, 15, 100]);
506
        $config->setDefaultLimit(10);
507
        $config->setSearchByAliases([
508
            (new Alias('fullname', 'concat(\'c.firstname, \' \', c.lastname\')'))
509
        ]);
510
511
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
512
            self::assertSame(100, $args->getLimit());
513
            self::assertSame(200, $args->getOffset());
514
            self::assertEquals([
515
                (new Filter())
516
                    ->setField('concat(\'c.firstname, \' \', c.lastname\')')
517
                    ->setType('eq')
518
                    ->setX('Vassily Poupkine')
519
                    ->setHaving(true),
520
                (new Filter())
521
                    ->setField('c.heaven')
522
                    ->setType('like')
523
                    ->setX('the road to heaven'),
524
            ], $args->getSearchBy());
525
            self::assertEquals([
526
                'c.id' => 'asc',
527
            ], $args->getSortBy());
528
529
            return new QueryResult([
530
                ["dummy"],
531
                ["wammy"],
532
            ], 1000);
533
        });
534
        $response = $queryFilter->getData($config);
535
        self::assertEquals([
536
            ["dummy"],
537
            ["wammy"],
538
        ], $response->getData());
539
        self::assertSame(1000, $response->getMeta()['total_records']);
540
    }
541
}
542